サンプルプログラム F446RE_DFU_10K の説明
USBを介してSTM32F446REの
Flash Memoryに、.binファイルを
書き込むためのプログラムです。
DFU : Download Firmware Update
サンプルプログラムの動作を確認するために
えがおのでんし製の評価用基板 Base-Nucleo-64 と
STMicroelectronics社のfreeの開発ツール、
STM32CubeIDE を使用しています。
目次
概要
えがおのでんし製の評価用基板 Base-Nucleo-64 の説明
サンプルプログラム F446RE_DFU_10K のProject
PCとのUSB接続
CPU動作クロックの設定について
サンプルプログラム F446RE_DFU_10K の説明
F446RE_DFU_10K の構成
ユーザープログラムの実行開始位置
F446RE_DFU_10K の説明
1) 初期化の部分
2) 動作分岐の部分
3) LED点滅の部分
PCアプリケーション STM32CubeProgrammer
USBを介して、.bin ファイルをSTM32 CPUのFlash Memoryに書き込むためのPCアプリケーションです。
概要
サンプルプログラム F446RE_DFU_10Kは、USBを介して
STM32F446REの Flash Memoryに、.binファイルを書き込むためのプログラムです。
F446RE_DFU_10Kの .bin ファイル F446RE_DFU_10K_Release.bin 自体は、
STMicroelectronics社が提供しているPCアプリケーション STM32CubeProgrammer の
ST-LINK接続を使用して、0x08000000 番地に書き込みます。
F446RE_DFU_10K_Release.bin が書き込まれるエリアは以下の通りです。
sector 0 : 0x08000000 - 0x08003FFF : 16Kbytes
sector 1 : 0x08004000 - 0x08007FFF : 16Kbytes
USBを介しての .bin ファイルの書き込みには、
STM32CubeProgrammer のUSB接続を使用します。
書き込む .binファイルと書き込み開始アドレスを指定して、書き込みます。
.binファイルがプログラム(Firmware)の場合は、開始番地 0x08010000 を指定して書き込みます。
(sector 4 : 0x08010000 - 0x0801FFFF : 64Kbytes)
書き込んだプログラム(Firmware)は、0x08010000番地から実行されます。
また、そのプログラム(Firmware)は、0x08010000番地から実行するように設定しておく必要があります。
USBを介して書き込むプログラムの実行開始番地を 0x08010000 にしているのには理由があります。
STM32F446REの Flash Memory のセクターとサイズを以下に示します。
sector 0 : 0x08000000 - 0x08003FFF : 16Kbytes
sector 1 : 0x08004000 - 0x08007FFF : 16Kbytes
sector 2 : 0x08008000 - 0x0800BFFF : 16Kbytes
sector 3 : 0x0800C000 - 0x0800FFFF : 16Kbytes
sector 4 : 0x08010000 - 0x0801FFFF : 64Kbytes
sector 5 : 0x08020000 - 0x0803FFFF : 128Kbytes
sector 6 : 0x08040000 - 0x0805FFFF : 128Kbytes
sector 7 : 0x08060000 - 0x0807FFFF : 128Kbytes
Flash Memoryのイレースはセクター単位で行われます。
sector 4 からは、サイズが大きいため設定や動作パラメータを保存するのには
適さないと思います。
そこで、プログラムの実行開始番地を 0x08010000 にして、sector 2 と sector 3 を
パラメータ保存領域として使用することにしました。
えがおのでんし製の評価用基板 Base-Nucleo-64 の説明
このサンプルプログラムは、
えがおのでんし製の評価用基板 Base-Nucleo-64 を使用して動作を確認しています。
基板については、
Base-Nucleo-64基板 の説明 をご覧ください。
サンプルプログラム F446RE_DFU_10K のProject
STM32CubeIDE 1.12.0 を使用して作成しました。
ここからサンプルプログラムのProject W_F446RE_DFU_10K.zip をダウンロードしてください。
プロジェクト W_F446RE_DFU_10K は、
フォルダ C:\W_CubeIDE\W_F446RE\W_F446RE_DFU_10K のように配置して作成しました。
フォルダ C:\W_CubeIDE\W_F446RE を作成して、
そのフォルダに W_F446RE_DFU_10K.zip を貼り付けて解凍し、
プロジェクト作成時と同一に C:\W_CubeIDE\W_F446RE\W_F446RE_DFU_10K と
配置した場合は、普通にプロジェクトを開くことができます。
サンプルプログラムのプロジェクトを任意のフォルダに配置した場合に、
STM32CubeIDEにより、そのプロジェクトを開く方法については
既存のプロジェクトを開く方法 をご覧ください。
PCとのUSB接続
USBコネクタ部の回路を以下に示します。
これは、えがおのでんし製の試験基板 Base-Nucleo-64 のUSB部分の回路です。
USBコネクタには Mini-B を使用しています。
PC と Base-Nucleo-64 の USB-1 とを、USBケーブル(A - Mini B)で接続します。
CPU動作クロックの設定について
サンプルプログラム F446RE_DFU_10K のCPU動作クロック設定と
0x08010000番地に配置する、ユーザープログラムのCPU動作クロック設定は
同一である必要があります。
同一でない場合、ユーザープログラムが動作しません。
サンプルプログラム F446RE_DFU_10K のフォルダ Core/Src/main の
int main(void) に以下のCPU動作クロック設定の記述があります。
/* Configure the system clock */
SystemClock_Config();
CPUの動作クロックとPeripheralの動作クロックを設定します。
SystemClock_Config(); の設定内容は以下の通りです。
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 360;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 8;
RCC_OscInitStruct.PLL.PLLR = 6;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Activate the Over-Drive mode
*/
if (HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
サンプルプログラム F446RE_DFU_10K の説明
サンプルプログラム F446RE_DFU_10Kは、USBを介して
STM32F446REの Flash Memory に、.binファイルを書き込むためのプログラムです。
プロジェクトを開いた画面は以下のようになります。
以下、サンプルプログラム F446RE_DFU_10K について説明していきます。
サンプルプログラムの構成
STM32CubeIDEの画面左側、Project Explorerの
F446RE_DFU_10Kを展開した画面は以下のようになります。
サンプルプログラム F446RE_DFU_10K の構成を以下に示します。
F446RE_DFU_10K
|
|- Includes
|
|- Core
| |- Inc
| | |- main.h
| | |- stm32f4xx_hal_conf.h
| | |- stm32f4xx_it.h
| |
| |- Src
| | |- main.c
| | |- stm32f4xx_hal_msp.c
| | |- stm32f4xx_it.c
| | |- syscalls.c
| | |- system.c
| | |- system_stm32f4xx.c
| |
| |- Startup
|
|- Drivers
|
|- Middlewares
| |- ST
| |
| |- STM32_USB_Device_Library
| |- Class
| | |- DFU
| | |- Inc
| | | |- usbd_dfu.h
| | |
| | |- Src
| | |- usbd_dfu.c
| |
| |
| |- Core
| |- Inc
| | |- usbd_core.h
| | |- usbd_ctrreq.h
| | |- usbd_def.h
| | |- usbd_ioreq.h
| |
| |- Src
| |- usbd_core.c
| |- usbd_ctrreq.c
| |- usbd_ioreq.c
|
|- USB_DEVICE
| |- App
| | |- usb_device.c
| | |- usb_device.h
| | |- usbd_desc.c
| | |- usbd_desc.h
| | |- usbd_dfu_if.c
| | |- usbd_dfu_if.h
| |
| |- Target
| |- usbd_conf.c
| |- usbd_conf.h
|
|- STM32F446RETX_FLASH.ld
|- STM32F446RETX_RAM.ld
ユーザープログラムの実行開始位置
プログラムは、int main(void) から実行開始します。
int main(void) は、フォルダ Core/Src/main.c にあります。
STM32CubeIDEでビルドされたプログラムは、自動的にCPUの初期化を
行った後、int main(void) を呼び出します。
ユーザーコード(記述したプログラム)は、
int main(void) の先頭から実行されます。
F446RE_DFU_10K の説明
サンプルプログラム F446RE_DFU_10K の main() の記述は、
以下のとおりです。
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET)
{
/* Test if user code is programmed starting from USBD_DFU_APP_DEFAULT_ADD address */
if(((*(__IO uint32_t*)USBD_DFU_APP_DEFAULT_ADD) & 0x2FFC0000 ) == 0x20000000)
{
JumpAddress = *(__IO uint32_t*) (USBD_DFU_APP_DEFAULT_ADD + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) USBD_DFU_APP_DEFAULT_ADD);
JumpToApplication();
}
}
MX_USB_DEVICE_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
LED_ON(); // LED点灯
Wait_mSec(20); // 20mSec待つ
LED_OFF(); // LED消灯
Wait_mSec(180); // 180mSec待つ
}
/* USER CODE END 3 */
}
1) 初期化の部分
a) CPUのPeripheral初期化
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
により、CPUのPeripheralなどの基本的な初期化を行います。
PeripheralとはCPUの周辺インターフェースなどのことを言います。
プロジェクト構築時に自動的に組み込まれる、
HAL Drivers(フォルダ Drivers/STM32F4xx_HAL_Drivers) 内に記述されています。
b) CPU動作クロックの設定
/* Configure the system clock */
SystemClock_Config();
CPUの動作クロックとPeripheralの動作クロックを設定します。
SystemClock_Config(); の設定内容は、
int main(void)
{
.
.
.
}
の、すぐ下に記述されています。
c) GPIOの初期化
MX_GPIO_Init(); を呼び出して
USERスイッチ および LED が接続されているピンを初期化しています。
/* Initialize all configured peripherals */
MX_GPIO_Init();
2) 動作分岐の部分
動作分岐を以下に示します。
/* USER CODE BEGIN 2 */
/* Check if the KEY Button is pressed */
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET)
{
/* Test if user code is programmed starting from USBD_DFU_APP_DEFAULT_ADD address */
if(((*(__IO uint32_t*)USBD_DFU_APP_DEFAULT_ADD) & 0x2FFC0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (USBD_DFU_APP_DEFAULT_ADD + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) USBD_DFU_APP_DEFAULT_ADD);
JumpToApplication();
}
}
MX_USB_DEVICE_Init();
/* USER CODE END 2 */
プログラム実行開始時のUSERスイッチの状態をチェックして、
0x08010000 番地に分岐するか、DFU(Download Firmware Update)動作を行うかを
判断しています。
USERスイッチが押されていなければ、0x08010000 番地に分岐して、
0x08010000 番地に書き込まれている Firmware を実行します。
USERスイッチが押されてる場合は、USBを初期化して、
DFU(Download Firmware Update)動作を行います。
NUCLEO-F446RE基板上のUSERスイッチを押しながら、RESETスイッチを押すと、
DFU(Download Firmware Update)動作を開始します。
3) LED点滅の部分
永久ループ部分の記述を以下に示します。
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
LED_ON(); // LED点灯
Wait_mSec(20); // 20mSec待つ
LED_OFF(); // LED消灯
Wait_mSec(180); // 180mSec待つ
}
/* USER CODE END 3 */
LEDの 20mSec点灯 / 180mSec消灯 を繰り返します。
DFU(Download Firmware Update)動作は、割り込み処理で行われます。
PCアプリケーション STM32CubeProgrammer
USBを介して、.bin ファイルをSTM32 CPUのFlash Memoryに書き込むためのPCアプリケーションです。
PCアプリケーション STM32CubeProgrammer の説明 をご覧ください。
A+-2C (ええ加減にC) のページに戻る
メールアドレス: apm2c.sumi@gmail.com
なんでも、気軽に ご相談ください。
担当:おの
えがおのでんし 案内