Простой в реализации вариант.
Принцип следующий:
При запуске программы настройки из флеш-памяти считываются в ОЗУ. Все операции производятся над этой копией, при модификации настроек, они блоком пишутся обратно в память программ. Для размещения используется специальный сектор памяти INFOA его размер 128 байт. В некоторых МК с большим объемом памяти два сектора - INFOA и INFOB.
Необходимо в h-файле объявить структуру в которой будут хранится настройки.
#define DEFAULT_SETTINGS { 5, 1.0 } }; typedef struct { unsigned int address; float clb_a; unsigned short crc; // должен быть всегда в конце } stru_config; extern stru_config cfg_main;
в main.c объявить глобальную переменную cfg_main
//! Default application settings const stru_config cfg_default = DEFAULT_SETTINGS; //! Current application settings stru_config cfg_main; __task void main( void ) { cfg_load_settings(); printf("Addr: %d", cfg_main.address ); if( new_addr != cfg_main.address ) { cfg_main.address = new_addr; cfg_save_settings(); } if( user_want_reset_to_default() ) cfg_load_default(); }
#ifndef KR_FLASH_INCLUDED #define KR_FLASH_INCLUDED void cfg_save_settings(void); void cfg_load_settings(void); void cfg_load_default (void); #endif
/** * @file flash.c * @brief MSP430 Flash memory * * Read and write built-in flash memory * * @author Rustem Kalimullin * @par E-mail: * hellos@mail.ru * @par Copyright: * (c) Kurt, 2005 */ #include "common.h" #include "cmn_util.h" #pragma memory=constseg(INFOA) const stru_config cfg_store = DEFAULT_SETTINGS; #pragma memory=default //--------------------------------------------------------- //! Save settings void cfg_save_settings( void ) { istate_t int_state = __get_interrupt_state(); __disable_interrupt(); cfg_main.crc = Calc_CRC16( (unsigned char *) &cfg_main, sizeof(cfg_main)-sizeof(cfg_main.crc)); FCTL2 = FWKEY + FSSEL_1 + FN3+FN1+FN0; // MCLK/12 = 4608000 / 12 = 384kHz FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY; // Clear Lock bit *(unsigned int *)&cfg_store.crc = 0xFFFF; // write dummy to erase FCTL1 = FWKEY + WRT; // Set WRT bit for write operation memcpy( (char *) &cfg_store, (char *) &cfg_main, sizeof(cfg_main)); FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Reset LOCK bit __set_interrupt_state(int_state); } //--------------------------------------------------------- //! Load default settings void cfg_load_default( void ) { memcpy( (char *)&cfg_main, (char *)&cfg_default, sizeof(cfg_main)); cfg_save_settings(); } //--------------------------------------------------------- //! Load settings. If failed load default values. void cfg_load_settings( void ) { memcpy( (char *)&cfg_main, (char *)&cfg_store, sizeof(cfg_main) ); if (Calc_CRC16( (unsigned char *) &cfg_main, sizeof(cfg_main)) != 0) { cfg_load_default(); } }