ODIN-W2(WiFiモジュール)の内蔵Flashへの書き込みを試してみる。PlatformIOのmbed環境にて。
ODIN-W2の内蔵フラッシュにデータを書き込めそうなので、やってみました。WiFiの接続の条件などは、入力して内蔵フラッシュに保持しておきたいですよね。
下記がとっても参考になりました。ありがとうございました。
1.環境の構築
下記で説明しているので参考にしてください。
2.書き込む場所の設定。
下記が STMF32F43xx のメモリマップですが、Secter 23 (0x081E 000)からの128Kの部分に書き込むと、邪魔にならなそうです。
では、どこで設定するかというと、一度 Buildすると、STM32F439ZI.ld.link_script.ld が下記に生成されるのでそこで修正します。
<SOURCE_ROOT>\.pio\build\ublox_evk_odin_w2\STM32F439ZI.ld.link_script.ld
下記がオリジナルですが、これを
M_CRASH_DATA_RAM_SIZE = 0x100;
STACK_SIZE = 1024;
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048k
CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (rwx) : ORIGIN = 0x200001B0, LENGTH = 192k - (0x1AC+0x4)
}
このように、DATA (rx) の行を加えます。FLASH (rx)も修正します。
M_CRASH_DATA_RAM_SIZE = 0x100;
STACK_SIZE = 1024;
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1920k
DATA (rx) : ORIGIN = 0x081E0000, LENGTH = 128k
CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (rwx) : ORIGIN = 0x200001B0, LENGTH = 192k - (0x1AC+0x4)
}
3.ソースコード
完成したコードが下記です。Ntripサーバーに設定するための情報などを保持できるようにしています。RESET解除時にSW0を押す押さないで、書き込みモードへの選択になります。
#include "mbed.h"
void _eraseFlash(void)
{
FLASH_EraseInitTypeDef erase;
erase.TypeErase = FLASH_TYPEERASE_SECTORS; /* セクタを選ぶ */
erase.Sector = FLASH_SECTOR_23; /* セクタ23を指定 */
erase.Banks = FLASH_BANK_2; /* 消去するバンク=2 */
erase.NbSectors = 1; /* 消すセクタの数 */
erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; /* 3.3Vで駆動 */
uint32_t pageError = 0;
HAL_FLASHEx_Erase(&erase, &pageError); /* HAL_FLASHExの関数で消去 */
}
void writeFlash(uint32_t address, uint8_t *data, uint32_t size)
{
HAL_FLASH_Unlock(); /* フラッシュをアンロック */
_eraseFlash(); /* セクタ23を消去 */
do {
/* 1Byteずつフラッシュに書き込む */
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, *data);
} while (++address, ++data, --size);
HAL_FLASH_Lock(); /* フラッシュをロック */
}
void loadFlash(uint32_t address, uint8_t *data, uint32_t size)
{
memcpy(data, (uint8_t*)address, size);
}
typedef struct {
char wifi_ssid[20];
char wifi_passwd[20];
char ntrip_server[20];
char ntrip_passwd[20];
char ntrip_mountpt[20];
} NTRIP_Condition;
int main(void)
{
mbed_stats_sys_t stats;
mbed_stats_sys_get(&stats);
printf("\n ---- ODIN-W2 Status -----\n");
printf("Mbed OS version %d.%d.%d\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
printf("CPU ID: 0x%x \n", (u_int16_t)stats.cpu_id);
printf("Compiler ID: %d \n", (u_int16_t)stats.compiler_id);
printf("Compiler Version: %d \n", stats.compiler_version);
const uint32_t address = 0x81E0000;
NTRIP_Condition ntrip_condition;
/* フラッシュから構造体にデータを読み込む */
loadFlash(address, (uint8_t*)&ntrip_condition, sizeof(NTRIP_Condition));
printf (" -------------------------\r\n");
printf ("| Current C099 conditions |\r\n");
printf (" -------------------------\r\n");
printf ("WiFi SSID = %s \r\n" , ntrip_condition.wifi_ssid );
printf ("WiFi Password = %s \r\n" , ntrip_condition.wifi_passwd );
printf ("Ntrip Server = %s \r\n" , ntrip_condition.ntrip_server );
printf ("Ntrip Password = %s \r\n" , ntrip_condition.ntrip_passwd );
printf ("Ntrip Mounpt = %s \r\n" , ntrip_condition.ntrip_mountpt );
DigitalIn switch_in0(SW0); // PUSH = 0 ;
switch_in0.mode(PullUp);
int x = switch_in0;
char buffer[4]="OK";
printf (" --------------------------------------------\r\n");
printf ("| If you release RESET while turning on SW0, |\r\n");
printf ("| C099 will enter the condition change mode. |\r\n");
printf (" --------------------------------------------\r\n");
while( (strstr(buffer,"OK") == NULL) || ( x == 0 ) ) // if SW0 is PUSH -> Change Condition
{
x = 1 ;
printf ("Please Input Condition\r\n");
printf ("\r\nWiFi SSID = ");
scanf ("%s" , ntrip_condition.wifi_ssid );
printf ("%s\r\nWiFi Password = " ,ntrip_condition.wifi_ssid);
scanf ("%s" , ntrip_condition.wifi_passwd );
printf ("%s\r\nNtrip Server (ex:rtk2go.com)= ",ntrip_condition.wifi_passwd);
scanf ("%s" , ntrip_condition.ntrip_server );
printf ("%s\r\nNtrip Server Passwd =" ,ntrip_condition.ntrip_server);
scanf ("%s" , ntrip_condition.ntrip_passwd );
printf ("%s\r\nNtrip Server Mount Point=" ,ntrip_condition.ntrip_passwd);
scanf ("%s" , ntrip_condition.ntrip_mountpt );
printf ("%s\r\n" ,ntrip_condition.ntrip_mountpt);
printf (" -------------------------\r\n");
printf ("| Changed C099 conditions |\r\n");
printf (" -------------------------\r\n");
printf ("WiFi SSID = %s \r\n" , ntrip_condition.wifi_ssid );
printf ("WiFi Password = %s \r\n" , ntrip_condition.wifi_passwd );
printf ("Ntrip Server = %s \r\n" , ntrip_condition.ntrip_server );
printf ("Ntrip Password = %s \r\n" , ntrip_condition.ntrip_passwd );
printf ("Ntrip Mounpt = %s \r\n" , ntrip_condition.ntrip_mountpt );
printf (" -----------------------------------------------------------------------\r\n");
printf ("| If this is all right, enter \"OK\". If not, enter \"NG\". (and ENTER) |\r\n");
printf (" -----------------------------------------------------------------------\r\n");
scanf("%s", buffer);
}
/* フラッシュに構造体のデータを書き込む */
writeFlash(address, (uint8_t*)&ntrip_condition, sizeof(NTRIP_Condition));
printf ("Quit\r\n");
return 0;
}
4.動作ログ
-------------------------
| Current C099 conditions |
-------------------------
WiFi SSID = 1
WiFi Password = 1
Ntrip Server = 1
Ntrip Password = 1
Ntrip Mounpt = 1
--------------------------------------------
| If you release RESET while turning on SW0, |
| C099 will enter the condition change mode. |
--------------------------------------------
Please Input Condition
WiFi SSID = zen4
WiFi Password = 12345678
Ntrip Server (ex:rtk2go.com)= rtk2go.com
Ntrip Server Passwd =12345678
Ntrip Server Mount Point=KOMAOKA
-------------------------
| Changed C099 conditions |
-------------------------
WiFi SSID = zen4
WiFi Password = 12345678
Ntrip Server = rtk2go.com
Ntrip Password = 12345678
Ntrip Mounpt = KOMAOKA
-----------------------------------------------------------------------
| If this is all right, enter "OK". If not, enter "NG". (and ENTER) |
-----------------------------------------------------------------------
Quit