見出し画像

ODIN-W2(WiFiモジュール)の内蔵Flashへの書き込みを試してみる。PlatformIOのmbed環境にて。

ODIN-W2の内蔵フラッシュにデータを書き込めそうなので、やってみました。WiFiの接続の条件などは、入力して内蔵フラッシュに保持しておきたいですよね。

下記がとっても参考になりました。ありがとうございました。

1.環境の構築

下記で説明しているので参考にしてください。

2.書き込む場所の設定。

下記が STMF32F43xx のメモリマップですが、Secter 23 (0x081E 000)からの128Kの部分に書き込むと、邪魔にならなそうです。

画像2

では、どこで設定するかというと、一度 Buildすると、STM32F439ZI.ld.link_script.ld が下記に生成されるのでそこで修正します。
<SOURCE_ROOT>\.pio\build\ublox_evk_odin_w2\STM32F439ZI.ld.link_script.ld

画像2

下記がオリジナルですが、これを

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

5.参考資料

ST32F439のマニュアルhttps://www.st.com/resource/en/reference_manual/dm00031020-stm32f405-415-stm32f407-417-stm32f427-437-and-stm32f429-439-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf


この記事が気に入ったらサポートをしてみませんか?