stm32CubeMXが生成してくれるHALライブラリを使ってstm32F051のFlashにデータを書き込む
stMicro提供のライブラリを使うとstm32FシリーズCPU内蔵のFlashROMへデータを書き込むのはとても簡単なのだが
以前のstdperipheralライブラリからHALに乗り換えてちょっと躓いたのでメモ。
FLASHに書き込む時には書き込み対象ページのデータを書き込み前に消去しておかないとならない。
stm32F051ではライブラリの関数を使って1KByteのページ単位でデータを消去することになる。
書き込みはstm32f0xx_hal_flash.cにある関数HAL_FLASH_Programが以前のライブラリと殆ど同じ方法で使える。
サンプルプログラムを見ると消去の方は構造体を使ったパラメータ渡しのHAL_FLASHEx_Eraseという関数を使ってあるが使い方がややこしそうでしかも同じソースファイルには含まれていない。
で、同じソースにある簡単そうな関数FLASH_PageErase(uint32_t PageAddress)を使ってみたのだがこれが間違いの元で
暫く悩んだ挙句サンプルに従ってstm32f0xx_hal_flash_ex.cに含まれているHAL_FLASHEx_Erase関数を使ったらすんなりと書き込めてしまった。
(教訓)
HALライブラリの関数を使うときはHAL_という文字で始まる関数だけを使わないとトラブルの基になる。
// フラッシュROMへデータを書き込む void WriteToFlash(uint32_t addr, uint8_t* dat, uint16_t size) { int i; FLASH_EraseInitTypeDef EraseInitStruct; uint32_t PageError = 0; HAL_StatusTypeDef r; r = HAL_FLASH_Unlock(); if( r != HAL_OK ){ #ifdef _DEBUG_FLASH_HAL xprintf("WriteParamToFlash:FLASH_Unlock error r=%x\r\n",r); #endif return; } EraseInitStruct.TypeErase = TYPEERASE_PAGES; EraseInitStruct.PageAddress = addr; EraseInitStruct.NbPages = 1; r = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError); if ( r != HAL_OK ) { #ifdef _DEBUG_FLASH_HAL xprintf("WriteParamToFlash:FLASH_Erase error r=%x, pageerr=%x\r\n",r,PageError); #endif return; } for(i=0; i<size; i+=2){ r = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, addr+i, *(uint16_t*)(dat+i)); #ifdef _DEBUG_FLASH_HAL xprintf("WriteParamToFlash i=%d, r=%x\r\n",i,r); #endif if( r != HAL_OK ){ #ifdef _DEBUG_FLASH_HAL xprintf("WriteParamToFlash:FLASH_Program error i=%d, r=%x\r\n",i,r); #endif return; } } r = HAL_FLASH_Lock(); if( r != HAL_OK ){ #ifdef _DEBUG_FLASH_HAL xprintf("WriteParamToFlash:FLASH_Lock error r=%x\r\n",r); #endif } }