Hal_config_block

I sort of assumed that HAL_CONFIG_BLOCK (and the ER_CONFIG file that gets flashed to new devices) was some sort of hard-coded structure, but from looking at the one-line comments for the functions, it looks like a fairly robust system for storing arbitrary configuration data.

Has anyone used it to store application data before? I’m a little confused about how to access it and write to it (especially when it comes to creating new blocks for my custom application)

look at our LCD code.

I used it to store user config.
It is simple to use when you know how to :slight_smile:
Here is my interop code:

INT8 SystemConfig::WriteUserConfig( LPCSTR name, INT32 size, CLR_RT_TypedArray_UINT8 data, HRESULT &hr )
{
	return HAL_CONFIG_BLOCK::UpdateBlockWithName(name, data.GetBuffer(), size, TRUE);
}

INT8 SystemConfig::ReadUserConfig( LPCSTR name, INT32 size, CLR_RT_TypedArray_UINT8 data, HRESULT &hr )
{
	return HAL_CONFIG_BLOCK::ApplyConfig(name, data.GetBuffer(), size);
}

And the managed part:

        /// <summary>
        /// Create or update a user configuration block in flash memory 
        /// </summary>
        /// <param name="name">Unique config ID (63 characters max)</param>
        /// <param name="size">Buffer size</param>
        /// <param name="data">Data buffer</param>
        /// <returns></returns>
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern bool WriteUserConfig(String name, int size, byte[] data);
        /// <summary>
        /// Read a user configuration block in flash memory, returns the config block data or <c>null</c> 
        /// </summary>
        /// <param name="name">Unique config ID (63 characters max)</param>
        /// <param name="size">Buffer size</param>
        /// <param name="data">Data buffer to update</param>
        /// <returns></returns>
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal static extern bool ReadUserConfig(String name, int size, byte[] data);

Note that name and size must be constant, so I use a class to handle that:

    /// <summary>
    /// User configuration data.
    /// <para>This class is a container for persistent data stored in flash memory (NETMF config block).</para>
    /// <para>This class can be used as a base class. In that case Name must be changed, Size can be changed.</para>
    /// <para>Note to implementers: do not change Size when a config block is already existing in flash. Erase and restore the firmware to delete existing config blocks.</para>
    /// </summary>
    public class UserConfig
        {
        /// <summary>
        /// Gets the configuration unique identifier
        /// </summary>
        public virtual String Name {
            get { return "USER_CONFIG"; }
            }
        /// <summary>
        /// Gets the configuration data size
        /// </summary>
        public virtual int Size {
            get { return 128; }
            }
        private byte[] _data;
        /// <summary>
        /// Gets the configuration data
        /// </summary>
        public byte[] Data {
            get { return _data; }
            }
        /// <summary>
        /// Initialize a new instance of <see cref="UserConfig"/>
        /// </summary>
        public UserConfig() {
            _data = new byte[Size];
            }
        /// <summary>
        /// Gets the config Name
        /// </summary>
        /// <returns></returns>
        public override string ToString() {
            return Name;
            }
        /// <summary>
        /// Load the configuration data from flash memory
        /// </summary>
        /// <returns></returns>
        public bool Load() {
            return SystemConfig.ReadUserConfig(Name, Size, _data);
            }
        /// <summary>
        /// Save the configuration data to flash memory
        /// </summary>
        /// <returns></returns>
        public bool Save() {
            return SystemConfig.WriteUserConfig(Name, Size, _data);
            }

        }

1 Like

Awesome! I’ll add this as an interop library feature to the NETMF Community Ports github. Thanks!