micro:bitをArduino環境で使う (3)内部フラッシュへのデータ書き込み
256kバイトもあるフラッシュメモリにプログラムから自由にデータを書き込みたいと思い、ライブラリを作成しまた。
2017/12/27 更新
書込みの*addr++ = *ptr++;の両アドレスが4バイト境界でないとフォルトを起こしてしまうようです。
その防止のためのエラー処理を追加しました。
ライブラリ
// // フラッシュメモリ書き込みライブラリ // 2017/12/25 by たま吉さん // 参考文献 // nRF51 Series Reference Manual Version 3.0 「6 Non-Volatile Memory Controller (NVMC)」 // #include <Arduino.h> #include "nrf.h" // // フラッシュメモリ指定ページ消去 // フラッシュメモリアドレスは、0x00000000 ~ 0x0003FFFFの範囲とする // 1ページのサイズは1024バイトとし、アドレスは // // 引数 // addr 消去対象ページ先頭アドレス // 戻り値 // 0:正常終了 // 1:異常終了(指定アドレスが正しくない) // uint8_t flashPageErase(uint32_t addr) { if ( addr >= 0x00040000 ) return 1; // フラッシュメモリ領域外 if ( addr % 1024 ) return 1; // ページ先頭アドレスでない // 書込みアンロック NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; while (NRF_NVMC->READY == NVMC_READY_READY_Busy); // 指定ページの消去 NRF_NVMC->ERASEPAGE = addr; while (NRF_NVMC->READY == NVMC_READY_READY_Busy); // 書込みロック NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; while (NRF_NVMC->READY == NVMC_READY_READY_Busy); return 0; } // フラッシュメモリ32ビットワードデータ書き込み // 引数 // addr: 書込みアドレス(4バイト境界アドレスであること) // ptr : 書込みデータ格納アドレス(4バイト境界アドレスであること) // len : 書込みデータ長さ // 戻り値 // 0:正常終了 // 1:異常終了(指定アドレスが正しくない) // uint8_t flashWriteData(uint32_t* addr, uint32_t *ptr, uint16_t len) { if ( ((uint32_t)addr) >= 0x00040000 ) return 1; // フラッシュメモリ領域外 if ( ((uint32_t)addr) % 1024 ) return 1; // ページ先頭アドレスでない if (((uint32_t)ptr)%4) return 1; // 4バイト境界アドレスでない // 書込み有効設定 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; while (NRF_NVMC->READY == NVMC_READY_READY_Busy); // データ書き込みループ for (uint32_t i = 0; i<len; i++) { *addr++ = *ptr++; //Serial.println(i,DEC); while (NRF_NVMC->READY == NVMC_READY_READY_Busy); } // 書込み無効設定 NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; while (NRF_NVMC->READY == NVMC_READY_READY_Busy); return 0; }
利用サンプルスケッチ
// // micro:bit フラッシュメモリ書込みテスト 2017/12/25 by たま吉さん // uint8_t flashPageErase(uint32_t addr); void flashWriteData(uint32_t* addr, uint32_t *ptr, uint16_t len); #define FLASH_PAGESIZE 1024 // ページサイズ #define FLASH_PAGENUM 256 // 総ページ数 #define FLASH_TOPADR 0x00000000 // フレッシュメモリ先頭アドレス #define FLASH_SAVESIZE 4096 // 保存データサイズ(ttbasicを想定) #define FLASH_SAVEPAGENUM 4 // #define FLASH_SAVENUM 1 #define FLASH_SAVEPOP ((FLASH_TOPADR+FLASH_PAGESIZE*256)-FLASH_SAVESIZE*FLASH_SAVENUM) uint8_t buf[FLASH_SAVESIZE]; void setup() { uint8_t c; Serial.begin(115200); Serial.print("Save top adr="); Serial.println(FLASH_SAVEPOP,HEX); // テスト用ダミーデータ for (uint16_t i=0; i < FLASH_SAVESIZE; i++) { buf[i] = i%256; } Serial.print("Write(y/n)? "); while(!Serial.available()); c = Serial.read(); Serial.write(c); Serial.println(); if (c == 'y') { // ページの消去 Serial.println("ERASE PAGE"); for (uint8_t i=0; i<FLASH_SAVEPAGENUM; i++) { flashPageErase(FLASH_SAVEPOP+FLASH_PAGESIZE*i); } // データの書込み Serial.println("Write Data"); //for (uint8_t i=0; i<FLASH_SAVEPAGENUM; i++) { flashWriteData((uint32_t*)FLASH_SAVEPOP, (uint32_t*)buf, FLASH_SAVESIZE/4); //} } // データの確認 Serial.println("Read Data"); for (uint32_t i=0; i <FLASH_SAVESIZE; i++) { if (i%16 == 0) { Serial.print(FLASH_SAVEPOP+i,HEX); Serial.print(":"); } c = *((uint8_t*)FLASH_SAVEPOP+i); if (c<0x10){ Serial.print("0");Serial.print(c,HEX); } else { Serial.print(c,HEX); } if (i%16 == 15) Serial.println(); else Serial.print(" "); } } void loop() { // put your main code here, to run repeatedly: }
実行結果

フラッシュメモリの書込みは、ページ単位(1024バイト)で行います。
データの書込みはワード単位(4バイト)で行います。
フラッシュメモリの256kバイト領域のアドレス範囲は、
0x00000000 ~ 0x0003FFFF
です。
テストプログラムでは、ブートローダやプログラムを破壊しないよう、後半部に4kバイトを書き込んでいます。
このライブラリは、豊四季TinyBASICの移植時に利用する予定です。
« STM32関連 「STM32HAL&SW4入門 Kindle版」を読んでみると.. | トップページ | micro:bitをArduino環境で使う(4)豊四季Tiny BASICを動かしてみる »
「arduino」カテゴリの記事
- Freenove Mecanum ホイール カー キットを購入しました(2025.05.28)
- Arduino IDE+Arduino STM32環境で指定と異なるgccが使われてしまう(2025.01.23)
- Zorin OSでArduino Uno互換機(CH340)が認識しない(2025.01.19)
- Arduino IDE 2.3.4でArduino STM32を利用する(2025.01.12)
- Arduino用 SKK日本語変換ライブラリの開発 その1(2024.12.28)
「micro:bit」カテゴリの記事
- 豊四季Tiny Basic for micro:bit のマニュアルを更新しました(2020.11.21)
- micro:bitで8x8ドットNeopixelを使ったメッセージ表示(2018.05.15)
- 豊四季Tiny BASIC for micro:bit をV0.08に更新しました(2018.05.14)
- micro:bitをArduino環境で使う (7) シリアル通信(2018.02.07)
- 豊四季Tiny BASIC for micro:bit をV0.07に更新しました(2018.02.04)
« STM32関連 「STM32HAL&SW4入門 Kindle版」を読んでみると.. | トップページ | micro:bitをArduino環境で使う(4)豊四季Tiny BASICを動かしてみる »

コメント