日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32f103C8T6 bootloader设计

發布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32f103C8T6 bootloader设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

STM32 bootloader設計

?

???????使用的是STM32f103C8T6:64Kflash,在應用程序中通過CAN把接受到的bin寫到外置 flash的指定地址處。在bootloader中判斷一個單獨的標志位看程序是否需要升級,如果需要升級,則復制外置flash處的內容到STM32的內置flash的指定地址處。

如:

bootloader地址:0x08000000UL?? 大小:10K——0x2800——STM32的內置flash

應用程序地址:0x08002800UL?? 大小:45K——0xB400——STM32的內置flash

升級信息表:0x720000UL?? 大小:8K——0x2000——外置flash

升級的bin文件地址:0x08012400? 大小:45K——0xB400——外置flash

?

升級信息表主要有:更新標志,程序大小等;

bootloader設計思想:(bootloader是一個引導程序,復雜的CAN接收升級文件部分在應用程序中實現, 它只起一個拷貝和跳轉的功能)

1、判斷“升級信息表”中的標志位是否更新,是更新,則復制“升級的bin文件地址”的內容到“應用程序地址”處;

2、跳轉到應用程序處。

?

bootloader:BootLoader 就是在操作系統內核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設備、建立內存空間映射圖,從而將系統的軟硬件環境帶到一個合適狀態,以便為最終調用操作系統內核準備好正確的環境。這里我們所說的Bootloader也是系統開機前的一段小程序,其主要任務是用來初始化串口和IAP 端口(網口CAN 接口等)的,通過判斷狀態是否需要從IAP 端口進行更新應用程序,若需要更新則從端口接收應用程序,并存放到指定的Flash 里面,更新完成后則跳入到指定的Flash 里面執行應用程序。

應用程序:即我們需要開發板實現功能的程序,其中應用程序主要分為兩種:hex 文件和bin 文件。在我們經常使用的KEIL 中默認編譯生成的可執行文件(應用程序)為hex 格式的,若需要編譯生成bin 格式需要做如下修改,加入 “D:\Keil\ARM\ARMCC\bin\fromelf.exe--bin--output ./Obj/Can_Updata.bin ./Obj/test.axf” ,重新編譯生成的 Can_Updata.bin文件存放在 Obj 文件夾下。

?

有幾點需要注意的:

1、中斷向量的重映射(應用程序中要設置,否則無法使用中斷)

?

  • NVIC_VectTab_FLASH —— 0x8002800

  • NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2800);

  • ?

    2、跳轉到指定地址處;

    ?

  • static voidjump_to_app(void)

  • {

  • app_cb app_start = (app_cb)(*(uint32_t*)(APP_START_ADDR + 4));

  • ?
  • all_nvic_disabled();

  • //all_gpio_disabled();

  • ?
  • delay_ms(100);

  • __set_PSP(*(u32 *)(APP_START_ADDR));

  • __set_CONTROL(0);

  • ?
  • __set_MSP(*(uint32_t *)(APP_START_ADDR));

  • NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2800);

  • ?
  • app_start();

  • }


  • 部分代碼:

    ?

    ?

  • #include <stdio.h>

  • #include "usart.h"

  • #include "delay.h"

  • #include "iap.h"

  • #include "misc.h"

  • ?
  • typedef void (*app_cb)(void);

  • ?
  • static void all_nvic_disabled(void)

  • {

  • int i = 0;

  • for(i = 19; i < 59; i++)

  • {

  • NVIC->ICER[i >> 0x05] = (unsigned int )0x01 << (i & (unsigned char)0x1F);

  • }

  • ?
  • }

  • ?
  • static void all_gpio_disabled(void)

  • {

  • GPIO_InitTypeDef gpio_init;

  • gpio_init.GPIO_Pin = 0xffff;

  • gpio_init.GPIO_Speed = GPIO_Speed_50MHz;

  • gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  • GPIO_Init(GPIOA, &gpio_init);

  • GPIO_Init(GPIOB, &gpio_init);

  • GPIO_Init(GPIOC, &gpio_init);

  • GPIO_Init(GPIOD, &gpio_init);

  • }

  • ?
  • static void jump_to_app(void)

  • {

  • app_cb app_start = (app_cb)(*(uint32_t *)(APP_START_ADDR + 4));

  • ?
  • all_nvic_disabled();

  • //all_gpio_disabled();

  • ?
  • delay_ms(100);

  • __set_PSP(*(u32 *)(APP_START_ADDR));

  • __set_CONTROL(0);

  • ?
  • __set_MSP(*(uint32_t *)(APP_START_ADDR));

  • NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2800);

  • ?
  • app_start();

  • }

  • ?
  • int main(void)

  • {

  • iap_t iap;

  • uint8_t flag; // 0:未升級 1:已升級

  • ?
  • DelayInit();

  • UARTInit(9600);

  • GD25Q32BConfig();

  • printf("uart ok...\r\n");

  • delay_ms(100);

  • ?
  • flag = FlashIAPReadFlag(&iap);

  • ?
  • printf("flag: %d\n", flag);

  • printf("iap.version: %d\n", iap.version);

  • printf("iap.size: %d\n", iap.size);

  • ?
  • if(0 == flag)

  • {

  • FlashCopy(APP_START_ADDR, IAP_APP_START, &iap);

  • printf("copy ok!\n");

  • }

  • ?
  • jump_to_app();

  • ?
  • return 0;

  • }

  • #include <string.h>

  • #include "app_flash_manager.h"

  • #include "iap.h"

  • #include "debug.h"

  • ?
  • // 讀取升級狀態,0: 未升級; 1: 已經升級

  • uint8_t FlashIAPReadFlag(iap_t *update)

  • {

  • uint8_t flag;

  • ?
  • spiFlashRead(IAP_INFO_START, sizeof(iap_t), (uint8_t *)update);

  • ?
  • flag = update->flag;

  • ?
  • return flag;

  • }

  • ?
  • // 從backup_addr拷貝info->size的大小到app_addr地址處

  • boolean FlashCopy(uint32_t app_addr, uint32_t backup_addr, iap_t *info)

  • {

  • uint8_t upgrade_buffer[FLASH_SECTOR_SIZE];

  • uint16_t pageremain = FLASH_SECTOR_SIZE - backup_addr % FLASH_SECTOR_SIZE; // 單頁剩余字節

  • ?
  • if(((app_addr + info->size - 1) > APP_END_ADDR) || (app_addr < APP_START_ADDR))

  • {

  • return COPY_FALSE;

  • }

  • ?
  • if(info->size <= pageremain) // 程序總大小小于等于單頁大小

  • {

  • pageremain = info->size;

  • }

  • FlashErase(app_addr, APP_BLOCK);

  • ?
  • while(1)

  • {

  • // 分頁寫入

  • memset(upgrade_buffer, 0, sizeof(upgrade_buffer));

  • spiFlashRead(backup_addr, pageremain, upgrade_buffer); // 從備份區讀出pageremain字節數

  • FlashWrite(app_addr, upgrade_buffer, pageremain); // 寫到程序運行的地址處

  • ?
  • if(info->size == pageremain)

  • {

  • break; // 寫入結束

  • }

  • else

  • {

  • backup_addr += pageremain;

  • app_addr += pageremain;

  • info->size -= pageremain; // 減去已經寫入了的字節數,地址都往后面偏移

  • ?
  • if(info->size > FLASH_SECTOR_SIZE)

  • {

  • pageremain = FLASH_SECTOR_SIZE; // 超過1頁數據,一頁一頁寫入

  • }

  • else

  • {

  • pageremain = info->size; // 不夠1頁數據

  • }

  • }

  • }

  • ?
  • return COPY_OK;

  • }

  • #include "mcu_flash.h"

  • #include <string.h>

  • #include "stm32f10x_flash.h"

  • // STM32f103內置flash的讀寫擦除

  • // addr:地址 count:塊數量

  • flash_status_t FlashErase(uint32_t addr, uint8_t count)

  • {

  • uint8_t i;

  • ?
  • for(i = 0; i < count; ++i)

  • {

  • if(FLASH_ErasePage(addr + i * FLASH_SECTOR_SIZE) != FLASH_COMPLETE)

  • {

  • return FLASH_FAILURE;

  • }

  • }

  • ?
  • return FLASH_SUCCESS;

  • }

  • ?
  • uint32_t FlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)

  • {

  • uint16_t i, data = 0;

  • ?
  • FLASH_Unlock();

  • ?
  • for(i = 0; i < length; i += 2)

  • {

  • data = (*(buffer + i + 1) << 8) + (*(buffer + i));

  • if(FLASH_ProgramHalfWord((uint32_t)(addr + i), data) != FLASH_COMPLETE)

  • {

  • return i;

  • }

  • }

  • ?
  • FLASH_Lock();

  • ?
  • return length;

  • }

  • ?
  • uint32_t FlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)

  • {

  • memcpy(buffer, (void *)addr, length);

  • ?
  • return length;

  • }

  • 總結

    以上是生活随笔為你收集整理的STM32f103C8T6 bootloader设计的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国内偷拍av| 四虎影院污 | 欧美日韩一级二级三级 | 国产欧美一区二区三区在线看蜜臀 | 69国产视频 | 久久麻豆视频 | 尤物国产在线 | 亚洲熟妇中文字幕五十中出 | 日本理伦片午夜理伦片 | 欧美少妇诱惑 | 亚洲国产一区二区在线 | 麻豆视频黄色 | 一级美女黄色片 | 成人综合区| 一级特黄毛片 | 国产在线视频自拍 | 久久精品无码中文字幕 | 瑟瑟视频在线免费观看 | 精产国品一二三产品蜜桃 | 精品久久久精品 | 1024国产在线 | 国产99久久 | 成人做爰100 | 新红楼梦2005锦江版高清在线观看 | 尹人久久| 香蕉黄色片 | 加勒比精品| 久久精品久久精品久久 | 800av凹凸 | 中国女人内谢69xxxx免费视频 | 国产91绿帽单男绿奴 | 四虎国产精品成人免费入口 | 欧美精品成人一区二区在线观看 | 久久无码国产视频 | 国产精品免费一区二区三区 | 红桃成人在线 | chinese中国性按摩hd | 国产一二三在线视频 | 全肉的吸乳文 | 久久加久久 | 91精品91| 九九色播 | 亚洲理论在线观看 | 人禽l交视频在线播放 视频 | 天天综合色 | 91久操 | 国产农村妇女毛片精品久久麻豆 | 四虎4hu永久免费网站影院 | 免费成人看视频 | 久久草精品 | 国产精品中文在线 | 超碰com | 少妇久久久久久久久久 | 亚洲av无码电影在线播放 | 新红楼梦2005锦江版高清在线观看 | 亚洲色图五月天 | 丰满大乳少妇在线观看网站 | 在线观看黄色av网站 | 日日夜夜免费 | 国产白浆在线观看 | 青苹果av | 国产精品久久亚洲 | 91亚洲精品在线观看 | 亚洲国产中文在线 | 奶水旺盛的女人伦理 | 欧美日韩国产二区 | 中文字幕一区二区三区人妻四季 | 韩国三级视频在线 | 激情一区二区三区 | 91精品一区二区三区在线观看 | 黄色片网站在线免费观看 | 国产大片aaa | 一区二区影院 | 欧美性猛交xxx乱久交 | 日韩一区二区在线免费观看 | 日韩视频在线观看一区二区 | 福利一区二区在线 | 国产男女猛烈无遮挡免费观看网站 | 日本三级中文字幕 | 丰满少妇被猛烈进入高清播放 | 在线免费看a | 天天高潮夜夜爽 | youjizzxxx69| 男人和女人日批 | 欧美一本 | 国产中文字幕一区二区三区 | 欧美 日韩 国产 一区 | 狠狠操在线播放 | 欧美一级淫片bbb一84 | 国产69页 | 泷泽萝拉在线播放 | 婷婷色六月 | 日韩国产欧美一区二区 | 91视频啪啪 | 免费黄视频网站 | 亚洲国产欧美在线人成 | 少妇av网 | 超碰在线观看99 | 精品麻豆视频 |