CubeMXを使用したSTM32ブートローダーDFUモード。 ステップバイステップの指示、ステップバイステップ

そのため、このマンドリガルの作業は、STMicroelectronicsが提供する通常のツールを使用した段階的な指示がほぼ完全に存在しないことに動機付けられました。



ネットワーク上にある非常に多くのブートローダーは、時には非常に忙しく、特定のクリスタルでは残念ながら「シャープ」になっています。



提案された資料には、CubeMXパッケージ、DfuSeDemo「ブートローダー」、およびDfuファイルマネージャーファームウェア準備ユーティリティの使用手順が含まれています。



環境を調理する...



DubeSeDemo + DfuファイルマネージャのダウンロードであるCubeMX自体が同じパッケージSTM32 ST-LINK Utilityに含まれている必要があります。STMicroelectronicsのWebサイトですべて無料で入手できます。



アンクルリャオのSTM32F103C8T6チップを使用した実験用スティック



画像



そしてそこからST-Linkプログラマー。



画像



ええ、お気に入りのIDE、この特定のプレゼンテーションではKEILを使用していますが、他のIDEのコンパイル設定はそれほど変わりません。



さあ行こう...



CubeMXを起動し、クリスタルを選択して......



画像



ウィッシュリストを祝いましょう...



画像



この特定のタスクでは、USBデバイス→デバイスFSをアクティブにし、それに応じてUSBデバイス→ファームウェアアップデートクラスをダウンロードし、忘れられないRCC→高速クロック→クリスタル/セラミックレゾネーターをオンボードにします。



次に、ブートローダーモードスイッチを選択する必要があります。この例では、既存のboot1ジャンパーを使用します。



画像



小さなスキームを見て、それに合わせてboot1がPB2のレッグに接続されているため、GPIO_Inputモードで使用します。



完了し、[Clock Configuration]タブをアクティブにして、構成選択マシンを起動します。



画像

「構成」タブにジャンプして......



画像



GPIOボタンを選択して......



画像



そして、フィールドで...



画像

カスタムラベルを作成し、boot1にします。



次に、プロジェクトを設定します...



画像



プロジェクト→設定を選択します...



画像



選択して記入....



画像



したがって、プロジェクトを生成するIDE Cub(この場合はMDK-ARM V5)を選択します。



この実施形態のコード生成タブは変更されないままになります...



画像



さて、それですべて、プロジェクトの生成を開始しますプロジェクト→コードの生成



画像



最後に、CubはIDEをすぐに起動するように促します...何をすべきか。



画像



画像



コンパイルとアセンブリを開始し、クリスタルにロードします... F7、F8 ...



画像



最終結果...



ボードのピンを動作モードに切り替え、USBケーブルを接続して......



画像



画像



Windows→システム→デバイスマネージャー→USBコントローラーでコントロールパネルを開きます。 デバイスのリストを見ると、Windowsが少し音を立てて、STMデバイスをDFUモードドライバーにインストールします(まだインストールされていない場合)。



それで、ドライバーは立ち上がって決定し、「ブート」DfuSeDemoを実行します...



画像



DFUデバイスをキャッチしたものを見て、[ターゲットの選択]フィールドをダブルクリックします...



画像



アドレス0x0800C000までのフラッシュが書き込みのために閉じられていることを注意深く見て驚嘆し、このアドレスを書き込みます。



ちなみに、STM32F407VEで試してみました。0x08000000から記録用にメモリが開いています。つまり、最初からです。なぜ、このバージョンでは明確ではなく、掘り込まず、どこかに埋まっていますが、明らかに書かれていません。所有者なしで大きなピースが消えるからです...おそらく誰かがあなたに掘る場所を教えてくれるでしょう...



だから、「散髪が始まったばかり」...



必要なソースファイルは2つだけです...



画像



IDEでそれらを開き、修正し、追加します...



USER CODE BEGINとUSER CODE ENDの間の挿入を再生成するとき、CubeMXは一緒にしないことを考慮します...そこで追加を入力します...



main.cから始めましょう



/* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ typedef void (*pFunction)(void); pFunction JumpToApplication; uint32_t JumpAddress; /* USER CODE END PV */ . . . /* USER CODE BEGIN 0 */ uint32_t AddressMyApplicationBegin = 0x0800C000; uint32_t AddressMyApplicationEnd = 0x0800FBFC; /* USER CODE END 0 */ . . . /* USER CODE BEGIN 2 */ /* Check if the KEY Button is pressed */ if(HAL_GPIO_ReadPin(boot1_GPIO_Port, boot1_Pin ) == GPIO_PIN_SET) { /* Test if user code is programmed starting from address 0x0800C000 */ if (((*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD) & 0x2FFE0000) == 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 */ . . .
      
      





それはすべてmain.cで...



usbd_conf.hに移動して



 #define USBD_DFU_APP_DEFAULT_ADD 0x0800000
      
      





思い起こさせる...



 #define USBD_DFU_APP_DEFAULT_ADD 0x080C000 //     …
      
      





usbd_dfu_it.cに渡します。ここではさらに....



 . . . /* USER CODE BEGIN PRIVATE_TYPES */ extern uint32_t AddressMyApplicationBegin; extern uint32_t AddressMyApplicationEnd; /* USER CODE END PRIVATE_TYPES */ . . . /* USER CODE BEGIN PRIVATE_DEFINES */ #define FLASH_ERASE_TIME (uint16_t)50 #define FLASH_PROGRAM_TIME (uint16_t)50 /* USER CODE END PRIVATE_DEFINES */ . . .   ,    «»  … uint16_t MEM_If_Init_FS(void) { /* USER CODE BEGIN 0 */ HAL_StatusTypeDef flash_ok = HAL_ERROR; //   while(flash_ok != HAL_OK){ flash_ok = HAL_FLASH_Unlock(); } return (USBD_OK); /* USER CODE END 0 */ } . . . uint16_t MEM_If_DeInit_FS(void) { /* USER CODE BEGIN 1 */ HAL_StatusTypeDef flash_ok = HAL_ERROR; //  flash_ok = HAL_ERROR; while(flash_ok != HAL_OK){ flash_ok = HAL_FLASH_Lock(); } return (USBD_OK); /* USER CODE END 1 */ } . . . uint16_t MEM_If_Erase_FS(uint32_t Add) { /* USER CODE BEGIN 2 */ uint32_t NbOfPages = 0; uint32_t PageError = 0; /* Variable contains Flash operation status */ HAL_StatusTypeDef status; FLASH_EraseInitTypeDef eraseinitstruct; /* Get the number of sector to erase from 1st sector*/ NbOfPages = ((AddressMyApplicationEnd - AddressMyApplicationBegin) / FLASH_PAGE_SIZE) + 1; eraseinitstruct.TypeErase = FLASH_TYPEERASE_PAGES; eraseinitstruct.PageAddress = AddressMyApplicationBegin; eraseinitstruct.NbPages = NbOfPages; status = HAL_FLASHEx_Erase(&eraseinitstruct, &PageError); if (status != HAL_OK) { return (!USBD_OK); } return (USBD_OK); /* USER CODE END 2 */ } . . . uint16_t MEM_If_Write_FS(uint8_t *src, uint8_t *dest, uint32_t Len) { /* USER CODE BEGIN 3 */ uint32_t i = 0; for(i = 0; i < Len; i+=4) { /* Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by byte */ if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)(dest+i), *(uint32_t*)(src+i)) == HAL_OK) { // Usart1_Send_String("MEM_If_Write_FS OK!"); /* Check the written value */ if(*(uint32_t *)(src + i) != *(uint32_t*)(dest+i)) { /* Flash content doesn't match SRAM content */ return 2; } } else { /* Error occurred while writing data in Flash memory */ return (!USBD_OK); } } return (USBD_OK); /* USER CODE END 3 */ } . . . uint8_t *MEM_If_Read_FS (uint8_t *src, uint8_t *dest, uint32_t Len) { /* Return a valid address to avoid HardFault */ /* USER CODE BEGIN 4 */ uint32_t i = 0; uint8_t *psrc = src; for (i = 0; i < Len; i++) { dest[i] = *psrc++; } return (uint8_t*)(dest); /* ,     */ /* USER CODE END 4 */ } . . . uint16_t MEM_If_GetStatus_FS (uint32_t Add, uint8_t Cmd, uint8_t *buffer) { /* USER CODE BEGIN 5 */ switch (Cmd) { case DFU_MEDIA_PROGRAM: buffer[1] = (uint8_t)FLASH_PROGRAM_TIME; buffer[2] = (uint8_t)(FLASH_PROGRAM_TIME << 8); buffer[3] = 0; break; case DFU_MEDIA_ERASE: default: buffer[1] = (uint8_t)FLASH_ERASE_TIME; buffer[2] = (uint8_t)(FLASH_ERASE_TIME << 8); buffer[3] = 0; break; } return (USBD_OK); /* USER CODE END 5 */ }
      
      





実際にはそれだけです...



プログラマーを接続し、ジャンパーをプログラミングモードにすると、F7、F8、およびボットローダーが記録されます...



使用できますか...



次に、bootloderを介してロードするためのアプリケーションを準備します...

お気に入りのアプリがLEDを点滅させ......



アプリケーションを準備およびデバッグし、コンパイラーおよびプログラム本体の個々の場所を変更して、プログラムの起動および割り込みベクトルのアドレスを変更します...



すなわち、KEIL→Configure→Flash Tools



画像



プログラムの先頭のアドレスを変更して......



画像



HEXファイルを生成すると言います



画像



そして、ベクターテーブルのアドレスを変更して......



F7プログラムの収集...



Dfuファイルマネージャーユーティリティを使用して、受信したHEXをdfoファイルに変換します...



画像



ボタンS19またはHEX ...でHEXファイルを選択し、Generateをクリックします...



画像



dfuファイルを取得します。



実際、すべて準備ができています。



コントローラーへのロード...



ジャンパーをDFUモードに設定した後、実験ボードと既にロードされたボットローダーをUSBに接続します。



画像



デバイスリストでDFUモードのSTMデバイスの外観を制御できます。

「ブートローダー」を実行します。



画像

彼女に私たちのdfuファイルを教えてください...



画像



アップグレードを押し、ロードの結果を観察します...自信のために、チェックを押します。



画像



すべてが成功しています...あなたが実行することができます...



エラーが発生した場合、それはどこか側線を意味します...



画像



たとえば...



したがって、すべてが成功したと仮定します...ジャンパーをアプリケーションモードに切り替えます



画像



点滅ダイオードをお楽しみください...

...

うわ たくさんのbukoffff。 写真をコピーするのにうんざり:-)



ご清聴ありがとうございました...



All Articles