S32K144学习(16)-Bootloader

1.什么是bootloader

Bootloader(引导加载程序) 是存储在设备非易失性存储器(如 ROM、Flash)中的一段特殊程序,负责在设备上电后初始化硬件、加载操作系统(OS)或用户应用程序,并最终将控制权移交给它们。它是设备启动过程中第一个运行的软件,扮演着"启动管理者"的角色。

2.bootloader的用途

1.在启动应用程序之前,对硬件外设进行初始化,可以在某种程度上做到应用层和硬件层分离的作用

2.在启动时对硬件或者Mcu自身进行检测,在运行程序之前对异常状态进行警报

3.通过Bootloader实现在线升级,第一,接收客户端软件发来的程序;第二将接收到的程序写入mcu的flash中,片内flash编程;第二,跳转到APP运行

3.S32K144的Bootloader的分配

1.S32k144的Flash容量

2.MCU上电复位流程

3.地址分配

Bootloader 分配

App Flash分配表

向量表重映射,之前失效

4.实验流程

通过按键从bootloader跳转APP

5.S32 编译器软件配置

1. 解锁flash默认配置

进人构建配置

使能Flash配置,取消RAM勾选

配置ld文件的MEMORY区

bootloader针对性修改 32k

app 空间分配 256k

6.部分代码

1.bootloader应用程序的代码:

javascript 复制代码
 * IO配置
 * KEY1 PTC12
 * KEY2 PTC13
 * KEY3 PTB2
 * LED1 PTD16
 * LED2 PTD15
 * LED3 PTD1
 * LED4 PTD0
*/
#include "Cpu.h"
#include "delay.h"
#include "uart.h"
#include"key.h"
#include"oled.h"
#include <stdio.h>


  volatile int exit_code = 0;

#define LED1(x)  PINS_DRV_WritePin(PTD,16,!x);
#define LED2(x)  PINS_DRV_WritePin(PTD,15,!x);
#define LED3(x)  PINS_DRV_WritePin(PTD,1,!x);
#define LED4(x)  PINS_DRV_WritePin(PTD,0,!x);

#define APP_START_ADDRESS 0x00008000 //应用程序起始地址

// Bootup application function 
void Bootup_Application(uint32_t appEntry, uint32_t appStack)
{
	static void (*jump_to_application)(void);	//指向应用函数的指针
	static uint32_t stack_pointer;		//应用程序栈指针

	jump_to_application = (void (*)(void))appEntry;	//函数指针指向应用程序的复位向量表地址,强转函数指针

	stack_pointer = appStack;	//应用程序栈指针赋值

	S32_SCB->VTOR = (uint32_t) APP_START_ADDRESS;	//设置中断向量表地址为应用程序的起始地址

	__asm volatile ("cpsie i" : : : "memory");	// 关闭全局中断

	__asm volatile ("msr msp, %0\n" : : "r" (stack_pointer): "sp");	//设置主栈指针

	__asm volatile ("msr psp, %0\n" : : "r" (stack_pointer): "sp"); //设置进程栈指针

	jump_to_application();	//跳转到应用程序的复位向量表地址执行应用程序
}	



int main(void)
{
  /* Write your local variable definition here */
	uint8_t pinstate;
	int MCU_Freq;
	uint32_t appEntry,appStack;	//应用程序入口地址和栈指针地址
  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  #ifdef PEX_RTOS_INIT
    PEX_RTOS_INIT();                   /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of Processor Expert internal initialization.                    ***/

	CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
	CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
	MCU_Freq = delay_init();//初始化delay函数
	PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); //初始化IO
	I2C_MasterInit(&i2c1_instance, &i2c1_MasterConfig0);//初始化I2C外设,用于OLED通讯
	LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0); //初始化串口

	oled_init(); //OLED配置参数初始化
	OLED_TITLE((uint8_t*)"S32K144",(uint8_t*)"01_BASE");//OLED显示标题
	u1_printf("初始化完毕,MCU运行频率为 %d Mhz \r\n",MCU_Freq);
    while(1)
    {
		pinstate = KEY_Proc (0);
		if(pinstate ==BTN1_PRES )
		{
			u1_printf("KEY1 Pressed 2s enter app\r\n");
			u1_printf("Enter App\r\n");
			u1_printf("in 2 seconds\r\n");
			delay_ms(1000);
			u1_printf("in 1 seconds\r\n");
			delay_ms(1000);
			u1_printf("in 0 seconds\r\n");

			appStack  = *(uint32_t *)(APP_START_ADDRESS + 0x00);	//读取应用程序栈指针地址
			appEntry  = *(uint32_t *)(APP_START_ADDRESS + 0x04);	//读取应用程序入口地址
			Bootup_Application(appEntry,appStack);	//跳转到应用程序
		}
    }
  /*** Don't write any code pass th5is line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
  return exit_code;
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

编译后:未超出32k空间

2.app代码

javascript 复制代码
 * IO配置
 * KEY1 PTC12
 * KEY2 PTC13
 * KEY3 PTB2
 * LED1 PTD16
 * LED2 PTD15
 * LED3 PTD1
 * LED4 PTD0
*/
#include "Cpu.h"
#include "delay.h"
#include "uart.h"
#include"key.h"
#include"oled.h"
  volatile int exit_code = 0;

#define LED1(x)  PINS_DRV_WritePin(PTD,16,!x);
#define LED2(x)  PINS_DRV_WritePin(PTD,15,!x);
#define LED3(x)  PINS_DRV_WritePin(PTD,1,!x);
#define LED4(x)  PINS_DRV_WritePin(PTD,0,!x);


int main(void)
{
  /* Write your local variable definition here */
	uint8_t pinstate;
	int MCU_Freq;
  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  #ifdef PEX_RTOS_INIT
    PEX_RTOS_INIT();                   /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of Processor Expert internal initialization.                    ***/

	CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
	CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
	MCU_Freq = delay_init();//初始化delay函数
	PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); //初始化IO
	I2C_MasterInit(&i2c1_instance, &i2c1_MasterConfig0);//初始化I2C外设,用于OLED通讯
	LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0); //初始化串口
  
  LED1(0);LED2(0);LED3(0);LED4(0);//LED熄灭

	oled_init(); //OLED配置参数初始化
	OLED_TITLE((uint8_t*)"S32K144",(uint8_t*)"01_BASE");//OLED显示标题
	u1_printf("初始化完毕,MCU运行频率为 %d Mhz \r\n",MCU_Freq);
    while(1)
    {
      u1_printf("App Running...\r\n");
      PINS_DRV_TogglePins(PTD, 1 << 0);
      delay_ms(1000);
      u1_printf("App Running...\r\n");
      PINS_DRV_TogglePins(PTD, 1 << 1);
      delay_ms(1000);
    }
  /*** Don't write any code pass th5is line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
  return exit_code;
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

7.实验现象

将两份代码都下载进芯片中,芯片先进入bootloader.main 从定向到0x8000

再指向app_main

相关推荐
虾球xz29 分钟前
游戏引擎学习第236天:GPU 概念概述
c++·学习·游戏引擎
虾球xz1 小时前
游戏引擎学习第237天:使用 OpenGL 显示图像
学习·microsoft·游戏引擎
superior tigre3 小时前
C++学习:六个月从基础到就业——C++学习之旅:STL容器详解
c++·学习
悟凡爱学习3 小时前
Linux嵌入式系统SQlite3数据库学习笔记
数据库·学习·sqlite
Suckerbin4 小时前
Pikachu靶场-RCE漏洞
学习·安全·网络安全
Rey_family6 小时前
HTML 表单学习笔记
笔记·学习·html
xx24066 小时前
CSS3笔记
笔记·学习·css3
HHU_HuLihan6 小时前
静压模型SWASH学习(9)——平底水槽高频驻波算例(Standing short wave in closed basin)
学习
张张张3128 小时前
4.21—4.22学习总结 JavaWeb:HTML-CSS
前端·css·学习·html
姝孟8 小时前
Linux学习笔记2
linux·笔记·学习