一,实验设计
/*
* bootloader实验
* 实验目的:
* 将bootloader 和 app 工程烧录进入开发板,在bootloader程序里,使用按键KEY1,跳转进入APP程序
*
* BOOTLOADRT程序内存分配:
* 中断向量表
* 0x00000000 - 0x00000400
* flash配置信息
* 0x00000400 - 0x00000410
* bootloader程序 占用31.728k空间
* 0x00000410 - 0x00008000
*
* APP程序内存分配:
* 中断向量表
* 0x00008000 - 0x00008400
* flash配置信息
* 0x00008400 - 0x00008410
* bootloader程序 占用256k空间
* 0x00008410 - 0x00048410
* 内存配置文件在工程文件夹内的Project Setting/Linker Files/S32K144_64_flash下
*
* 操作方法,将两个应用同时烧录进开发板内即可。
* IO配置
* KEY1 PTC12
* KEY2 PTC13
* KEY3 PTB2
* LED1 PTD16
* LED2 PTD15
* LED3 PTD1
* LED4 PTD0
*/
二,BootLoader代码设计
1.S32k144_64_flash.id文件
2.main.c
#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);
#define APP_START_ADDRESS 0x00008000 //app开始地址
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 ("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;
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
LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0); //初始化串口
u1_printf("当前进入BOOTLOADER程序,MCU运行频率为 %d Mhz \r\n",MCU_Freq);
while(1)
{
pinstate = KEY_Proc (1);
if(pinstate ==BTN1_PRES )
{
u1_printf("KEY1 按下 2秒后进入app \r\n");
delay_ms(2000);
appStack = *(uint32_t *)(APP_START_ADDRESS);
appEntry = *(uint32_t *)(APP_START_ADDRESS + 4);
Bootup_Application(appEntry, appStack);
}
else
{
LCD_clear_L(0,4); //OLED清行
LCD_clear_L(0,5);
}
delay_ms(100);
PINS_DRV_TogglePins(PTD, 1 << 0);
PINS_DRV_TogglePins(PTD, 1 << 1);
}
return exit_code;
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
3.下载配置
三,APP的配置
1.S32k144_64_flash.id文件
2.main.c
#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)
{
int MCU_Freq;
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_Deinit(INST_LPUART1);
LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0); //初始化串口
u1_printf("当前进入APP程序 内存起始地址为0x0008000,MCU运行频率为 %d Mhz \r\n",MCU_Freq);
while(1)
{
delay_ms(100);
PINS_DRV_TogglePins(PTD, 1 << 15);
PINS_DRV_TogglePins(PTD, 1 << 16);
}
for(;;) {
if(exit_code != 0) {
break;
}
}
return exit_code;
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
3.下载配置
下载文件配置,要保证两个程序不能交叉,互相擦除