什么是Bootloader 浅谈STM32中bootloader的内存分配

发布时间:2023-09-25  

1. 什么是Bootloader

Bootloader是硬件启动的引导程序,是运行操作系统的前提。在操作系统内核或用户应用程序运行之前运行的一段小代码。对硬件进行相应的初始化和设定,最终为操作系统准备好环境。

2. Bootloader的特点

Bootloader不属于操作系统,一般采用汇编语言和C语言开发。需要针对特定的硬件平台编写。在移植过程时,首先为开发板移植Bootloader。Bootloader不但依赖于CPU的体系架构,而且依赖于嵌入式系统板级设备的配置。

3. STM32中bootloader的内存分配

stm32默认的是从0x08000000开始启动程序,所以bootloader也存在于这个地址,大小可以设置。如下图举例分配 48K的大小空间给Bootloader

pIYBAF_8DkWAUhLDAABdqrH-we0124.png

还有一种分配方式:镜像的备份 Firmware ---> Application Bak ---> SysRest ----> Bootloader -----> Check if new Firmware -----> Move App Bak to App area

这种方式需要更大的存储空间,如果MCU内置FLASH 不够备份Firmware则需要外置Flash,将Firmware备份在外置FLASH。

pIYBAF_8Dk-AHFkBAAB6DGF2S3A371.png

根据实际MCU的Flash的大小和固件的大小来分配空间。一般可以把固件信息(app固件的StartAddr, EndAddr, FirmwareSize, CRC等)存放在Free Spae.

bootloader的作用一般是用作更新APP,和初始化后设定跳转到对应的APP。如果APP不加更新功能的话也可以直接将APP写入到0x08000000这个地址里。更新程序就是数据包的接收、校验、写入,全部写入完成后检查APP的启动向量为合格就可以跳转到APP里。

pIYBAF_8DlqAfGpIAABXcfclGZU737.png

4. Bootloader的跳转简单实现

4.1 Bootloader

我基于STM32Cube配置的外设,IDE用的STM32SW4,STM32F103RCT6。

在实现IAP功能前,先实现跳转。这里先不涉及固件更新。

/*FLASH : 0x8000000 --- 0x8040000 Total Size: 256K
*RAM : 0x20000000 --- 0x2000C000 Total Size: 48K
*Bootloader: 0x8000000 --- 0x8008000 Total Size: 32K


1 /* Includes ------------------------------------------------------------------*/

  2 #include "main.h"

  3 #include "stm32f1xx_hal.h"

  4 #include "usart.h"

  5 #include "gpio.h"

  6 

  7 /* USER CODE BEGIN Includes */

  8 #include "stdio.h"

  9 /* USER CODE END Includes */

 10 

 11 /* USER CODE BEGIN PFP */

 12 /* Private function prototypes -----------------------------------------------*/

 13 pFunction jump2app;

 14 void (*jump2app)();

 15 /* USER CODE END PFP */

 16 

 17 

 18 

 19 /* USER CODE BEGIN 0 */

 20 #ifdef __GNUC__

 21     #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

 22 #else

 23     #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

 24 #endif

 25 

 26 /*retargets the C library printf function to the USART*/

 27 PUTCHAR_PROTOTYPE

 28 {

 29     HAL_UART_Transmit(&huart1,(uint8_t*)&ch, 1, 0xFFFF);

 30     return ch;

 31 }

 32 

 33 //FLASH            : 0x8000000  --- 0x8040000       Total Size: 256K

 34 //RAM           : 0x20000000 --- 0x2000C000       Total Size: 48K

 35 //Bootloader     : 0x8000000 --- 0x8008000     Total Size: 32K 

 36   37 #define ApplicationAddress    0x8008000

 38 

 39 

 40 void iap_load_app(uint32_t appAddr)

 41 {

 42     printf("first word : 0x%xn",(*(uint32_t*)appAddr));

 43     if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)

 44     {

 45         printf("IAP load APP!!!n");

 46 

 47         __disable_irq();

 48 

 49         jump2app = (void (*)())*(__IO uint32_t*) (appAddr + 4);

 50 

 51         __set_MSP(*(__IO uint32_t*) appAddr);

 52 

 53         jump2app();

 54     }

 55 }

 56 /* USER CODE END 0 */

 57 

 58 /**

 59   * @brief  The application entry point.

 60   *

 61   * @retval None

 62   */

 63 int main(void)

 64 {

 65   /* USER CODE BEGIN 1 */

 66 

 67   /* USER CODE END 1 */

 68 

 69   /* MCU Configuration----------------------------------------------------------*/

 70 

 71   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

 72   HAL_Init();

 73 

 74   /* USER CODE BEGIN Init */

 75 

 76   /* USER CODE END Init */

 77 

 78   /* Configure the system clock */

 79   SystemClock_Config();

 80 

 81   /* USER CODE BEGIN SysInit */

 82 

 83   /* USER CODE END SysInit */

 84 

 85   /* Initialize all configured peripherals */

 86   MX_GPIO_Init();

 87   MX_USART1_UART_Init();

 88   /* USER CODE BEGIN 2 */

 89 

 90   /* USER CODE END 2 */

 91 

 92   /* Infinite loop */

 93   /* USER CODE BEGIN WHILE */

 94   while (1)

 95   {

 96       printf("I am bootloader,jump to app after 5 seconds!n");

 97 

 98       HAL_Delay(1000);

 99 

100       printf("1rn");

101 

102       HAL_Delay(1000);

103 

104       printf("2rn");

105 

106       HAL_Delay(1000);

107 

108       printf("3rn");

109 

110       HAL_Delay(1000);

111 

112       printf("4rn");

113 

114       HAL_Delay(1000);

115 

116       printf("ready to jump!n");

117 

118       iap_load_app(ApplicationAddress);

119   /* USER CODE END WHILE */

120 

121   /* USER CODE BEGIN 3 */

122 

123   }

124   /* USER CODE END 3 */

125 

126 }


修改ld文件 STM32F103RCTx_Flash.ld

pIYBAF_8DmiAONZzAALEZOEolfE616.png

编译烧录。首先将STM32F103RCT6的FLASH全部擦除如下图,然后用STM32SW4烧录Bootloader

o4YBAF_8DnuAZNL-AAHZsg8s2G0912.png

调试Bootloader如下图

o4YBAF_8DomAWgA9AALWnGn2I04381.png

4.2 Application

APP主要是修改ld文件,Bootloader分配了 32Kb, 剩余224K的先全分配给App, 实现简单跳转。

o4YBAF_8DpeASiHlAALEByM_BuY517.png

int main(void)

{

    //NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000);

  /* USER CODE BEGIN 1 */

    SCB->VTOR = ((uint32_t)0x8000000) | (0x8000 & (uint32_t)0x1FFFFF80);

  /* USER CODE END 1 */


  /* MCU Configuration----------------------------------------------------------*/


  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  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();

  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

  __enable_irq();

  /* USER CODE END 2 */


  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

     printf("I am new APP !nr");


     HAL_Delay(1000);

  /* USER CODE END WHILE */


  /* USER CODE BEGIN 3 */


  }

  /* USER CODE END 3 */


}


再将APP烧录,Reset

o4YBAF_8DqWAO282AAGCsqwxa2I458.png


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    -Planar) 分辨率为 84(wh)的 YUV 图像,则内存分布如下 YUV 码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,YUV4:4:4,YUV4:2:2, YUV4:2:0......
    内容: 内存的管理单元 获取内存的方法 获取高端内存 内核内存的分配方式 总结   1. 内存的管理单元 内存最基本的管理单元是页,同时按照内存地址的大小,大致分为3个区。 1.1 页 页的......
    块是连续的。 从上图中我们还可以看出内存分配的方向是从底到顶的分配方向,即首先从最末端开始找空内存。通常当内存管理刚初始化的时候,内存表全部清零,表示没有任何内存块被占用。 (1)内存分配原理 当指针p调用......
    型的用户空间 malloc 在实际上有很大的差别,内核使用特殊的基于页的分配技术,以最佳的方式利用系统 RAM。Linux 处理内存分配的方法:创建一系列内存对象集合,每个集合内的内存......
    块已经被占用,其数值则代表被连续占用的内存块数。比如某项值为 10,那么说明包括本项对应的内存块在内,总共分配了 10 个内存块给外部的某个指针。内寸分配方向如图所示,是从顶到底的分配方向。即首先从最末端开始找空内存......
    函数的参数值、局部变量的值等,其操作方式类似于数据结构中的栈。    (2)堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。分配方式......
    什么是Bootloader 浅谈STM32中bootloader的内存分配;1. 什么是Bootloader Bootloader是硬件启动的引导程序,是运行操作系统的前提。在操......
    。这里的对象指小于一页大小的内存块。 除了内存分配内存释放也是按照此层次结构操作。如释放对象,先释放到per-cpu缓存,再释放到slab缓存,最后再释放到伙伴系统。 框图中有三个主要模块,即伙......
    也在潮汐引擎中实现了安卓手机的首个 CPU高速缓存与系统级缓存的动态分配方案。新一代潮汐引擎为天玑9400的 CPU L3 缓存带来更智能、更精准的缓存分配方案,将移动终端的能效推入全新阶段。在天玑 9400 芯片能效提升的基础上,搭载......
    管理技术,只能采用实存储器管理策略。系统使用分页内存分配方式,在启动时对实际存储器进行分页。系统对内存的访问是直接的,操作系统对内存空间没有保护,多个进程可共享一个运行空间,所以,即使......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>