組み込みソフトウェアで内部flashを利用してパラメータを格納する方法
2697 ワード
01
前言
組み込みソフトウェアでは、ユーザ設定、キャリブレーションパラメータ、デバイス実行パラメータなど、不揮発性パラメータを格納することがよくあります.通常、EEPROMまたはSPI-FLASHに格納することを選択します.コスト削減を考慮した場合、メモリを節約することができ、パラメータを内部flashに保存することができます.結局、1枚あたり1元減らしても、量が大きくなってからは非常に大きいです.
02
パラメータ格納場所の選択
stm 32のflashアドレスは0 x 0800000から始まり、終了アドレスは0 x 0800000にチップの実際のflashサイズを加えると、チップによってflashサイズが異なる.KEILプロジェクトエンジニアリングのTargetでもROMの開始アドレスとサイズを見ることができます.Deviceページで使用しているチップゲージの型番を選択することを前提としています.
stm 32はflashを消去する際にセクタ(sector)単位であるため、パラメータを格納する際にもセクタ単位でセクタヘッダから消去、読み取り、書き込みを選択する論理は簡単である.LD,MD型製品のセクタサイズは1 K,HD,CL型製品のセクタサイズは2 Kである.一般的にパラメータをflashの末尾のいくつかのセクタに格納するのは妥当であり、プログラムファームウェア(コンパイルされた書き込みbinファイル)のサイズが末尾のいくつかのセクタに入らないことを確認すればよい.
stm 32 f 103 cbt 6を例にとると、flash開始アドレスは0 x 800000、サイズは0 x 20000である.1つのSectorの大きさは1 Kです.では、パラメータの位置を定義するには、次のようにします.
#define PARA_START_ADDR ((u32)0x0801fc00) #define PARA_PAGE_SIZE ((u16)0x400) 03
パラメータ形式
パラメータを構造体にカプセル化し、読み取りと保存を容易にします.注意Flashストレージは自動的に4バイトの位置合わせをして、すべてできるだけPARASAVED_を保証しますTの大きさは4の整数倍で、読み込み後のデータのずれを避ける.
#define PARA_FLAG 0 x 1000//パラメータタグtypedef struct{u 8 para[64];u 32 flag;}PARASAVED_T; PARASAVED_T para_t; 04
パラメータアクセス
パラメータを読み、flash内のデータをpara_に読み込むt構造体中
void ReadData(void) { u32 address; u32 *pd; u16 i;
address = PARA_START_ADDR; pd = (u32 *)(¶_t); for(i=0; i { *pd = *((u32 *) address); address += 4; pd++; } } パラメータを書き込みpara_tのデータをflashに書き込む
void SaveData(void) { u16 i; u8 writeTimes; u32 address; u8 isRight; u32 * pd;
FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
writeTimes = MAX_FLASH_WRITE_TIMES;
while(writeTimes–) { FLASH_ErasePage(PARA_START_ADDR); address = PARA_START_ADDR; pd = (u32 *)(¶_t); for(i=0; i { FLASH_ProgramWord(address, *pd); address += 4; pd++; }
} }
05
リードライトコールロジック
電源を入れてread関数を呼び出し、パラメータをグローバル変数para_に読み込みます.tでは、その後ライフサイクル全体でpara_を操作するt.para_tの内容が変更された後,save関数を呼び出し,変更値を保存する.
構造体のflagの役割は、すべてのパラメータの記憶マークとして、電源を入れて全ffであることを読むと、パラメータが空の初期状態になります.このとき、パラメータを初期化する操作をして、デフォルト値をflashに書き込むことができます.電源を入れるとflagが全ffではないと読みますが、define PARA_とFLAGが異なる場合、初期化パラメータまたはパラメータの一部になります.この役割は、デフォルトのパラメータ値を変更し、アップグレード後に有効にする必要がある場合にdefine値を変更してパラメータの初期化をトリガーすることです.
06
メリットとデメリット
パラメータを内部flashに格納すると、cost downができるメリットがありますが、チップのファームウェアをブラシすると、すべてのパラメータが消えてしまうというデメリットもあります.しかし一般的な適用の場合,このパラメータが消失するとパラメータ初期化がトリガーされ,大きな問題はない.ただし、パラメータに非常に困難なキャリブレーションパラメータ、運転データなどが格納されている場合は、慎重に使用してください.詳細はこちらをご覧ください.http://www.makeru.com.cn/course/1861.html?s=143793
前言
組み込みソフトウェアでは、ユーザ設定、キャリブレーションパラメータ、デバイス実行パラメータなど、不揮発性パラメータを格納することがよくあります.通常、EEPROMまたはSPI-FLASHに格納することを選択します.コスト削減を考慮した場合、メモリを節約することができ、パラメータを内部flashに保存することができます.結局、1枚あたり1元減らしても、量が大きくなってからは非常に大きいです.
02
パラメータ格納場所の選択
stm 32のflashアドレスは0 x 0800000から始まり、終了アドレスは0 x 0800000にチップの実際のflashサイズを加えると、チップによってflashサイズが異なる.KEILプロジェクトエンジニアリングのTargetでもROMの開始アドレスとサイズを見ることができます.Deviceページで使用しているチップゲージの型番を選択することを前提としています.
stm 32はflashを消去する際にセクタ(sector)単位であるため、パラメータを格納する際にもセクタ単位でセクタヘッダから消去、読み取り、書き込みを選択する論理は簡単である.LD,MD型製品のセクタサイズは1 K,HD,CL型製品のセクタサイズは2 Kである.一般的にパラメータをflashの末尾のいくつかのセクタに格納するのは妥当であり、プログラムファームウェア(コンパイルされた書き込みbinファイル)のサイズが末尾のいくつかのセクタに入らないことを確認すればよい.
stm 32 f 103 cbt 6を例にとると、flash開始アドレスは0 x 800000、サイズは0 x 20000である.1つのSectorの大きさは1 Kです.では、パラメータの位置を定義するには、次のようにします.
#define PARA_START_ADDR ((u32)0x0801fc00) #define PARA_PAGE_SIZE ((u16)0x400) 03
パラメータ形式
パラメータを構造体にカプセル化し、読み取りと保存を容易にします.注意Flashストレージは自動的に4バイトの位置合わせをして、すべてできるだけPARASAVED_を保証しますTの大きさは4の整数倍で、読み込み後のデータのずれを避ける.
#define PARA_FLAG 0 x 1000//パラメータタグtypedef struct{u 8 para[64];u 32 flag;}PARASAVED_T; PARASAVED_T para_t; 04
パラメータアクセス
パラメータを読み、flash内のデータをpara_に読み込むt構造体中
void ReadData(void) { u32 address; u32 *pd; u16 i;
address = PARA_START_ADDR; pd = (u32 *)(¶_t); for(i=0; i { *pd = *((u32 *) address); address += 4; pd++; } } パラメータを書き込みpara_tのデータをflashに書き込む
void SaveData(void) { u16 i; u8 writeTimes; u32 address; u8 isRight; u32 * pd;
FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
writeTimes = MAX_FLASH_WRITE_TIMES;
while(writeTimes–) { FLASH_ErasePage(PARA_START_ADDR); address = PARA_START_ADDR; pd = (u32 *)(¶_t); for(i=0; i { FLASH_ProgramWord(address, *pd); address += 4; pd++; }
isRight = 1;
address = PARA_START_ADDR;
pd = (u32 *)(¶_t);
for(i=0; i
} }
05
リードライトコールロジック
電源を入れてread関数を呼び出し、パラメータをグローバル変数para_に読み込みます.tでは、その後ライフサイクル全体でpara_を操作するt.para_tの内容が変更された後,save関数を呼び出し,変更値を保存する.
構造体のflagの役割は、すべてのパラメータの記憶マークとして、電源を入れて全ffであることを読むと、パラメータが空の初期状態になります.このとき、パラメータを初期化する操作をして、デフォルト値をflashに書き込むことができます.電源を入れるとflagが全ffではないと読みますが、define PARA_とFLAGが異なる場合、初期化パラメータまたはパラメータの一部になります.この役割は、デフォルトのパラメータ値を変更し、アップグレード後に有効にする必要がある場合にdefine値を変更してパラメータの初期化をトリガーすることです.
06
メリットとデメリット
パラメータを内部flashに格納すると、cost downができるメリットがありますが、チップのファームウェアをブラシすると、すべてのパラメータが消えてしまうというデメリットもあります.しかし一般的な適用の場合,このパラメータが消失するとパラメータ初期化がトリガーされ,大きな問題はない.ただし、パラメータに非常に困難なキャリブレーションパラメータ、運転データなどが格納されている場合は、慎重に使用してください.詳細はこちらをご覧ください.http://www.makeru.com.cn/course/1861.html?s=143793