从MCU上电启动流程出发编写bootloader(中)

上文已经分析了MCU上电的启动流程。本文尝试编写一个简单的bootloader以及一个实现CAN通信的APP,为我们下一步尝试编写一个通过CAN通信实现刷写APP功能的bootloader作铺垫。
下面直接上干货。
在这里插入图片描述
看一下bootloader工程的结构,非常的简单,实现代码也非常简单。
在这里插入图片描述
main.h

#ifndef _MAIN_H
#define _MAIN_H

#define APPLICATION_ADDRESS (uint32_t)0x08004000//APP工程的起始地址

typedef void (*pFunction)(void);

#endif

main.c

#include "main.h"
#include "ac78xx_can.h"
#include "ac78xx_rtc.h"
#include "ac78xx_gpio.h"

uint32_t JumpAddress = 0;
uint8_t JumpToApplication_Flag = 0; 
pFunction JumpToApplication;

int main(void)
{
	JumpToApplication_Flag = 1;
	if(JumpToApplication_Flag == 1)
	{
		JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);//JumpAddress = 0x08004004 此处存放的是APP工程的Reset_Handler的中断向量
		JumpToApplication = (pFunction) JumpAddress;
		__set_MSP(*(__IO uint32_t*)APPLICATION_ADDRESS);//此处是设置SP指针指向0x08004000处的数据即APP工程的栈顶地址
		JumpToApplication();
	}
	while(1)
	{	
		
	}
}

此上就是简单实现了一个bootloader,能够跳转到我们的APP应用区。
下面看一下APP工程。
在这里插入图片描述
在这里插入图片描述

本APP简单实现了CAN的收发功能,展示下核心代码(协议报文自定义,采用motorola格式)

int32_t CAN1_IRQnCallBack(uint32_t event, uint32_t wparam, uint32_t lparam)
{
	uint8_t i = 0;
	if (event & CAN_EVENT_RECVMSG)
	{
		while(CAN_IsMsgInReceiveBuf((CAN_Type*)lparam))	 
		{		
			CAN_MessageRead((CAN_Type*)lparam, &RxMessage_Can1);
			if(RxMessage_Can1.IDE == 0)
			{
				if(RxMessage_Can1.ID == TEST_ADDRESS_333)
				{
					Can_Rec_Debug_Frame_Flag = 1;
			
					Rec_Byte_555_0 =  (uint8_t) RxMessage_Can1.Data[0];
					Rec_Byte_555_1 =  (uint8_t) RxMessage_Can1.Data[1];
					Rec_Byte_555_2 =  (uint8_t) RxMessage_Can1.Data[2];
					Rec_Byte_555_3 =  (uint8_t) RxMessage_Can1.Data[3];
					Rec_Byte_555_4 =  (uint8_t) RxMessage_Can1.Data[4];
					Rec_Byte_555_5 =  (uint8_t) RxMessage_Can1.Data[5];
					Rec_Byte_555_6 =  (uint8_t) RxMessage_Can1.Data[6];
					Rec_Byte_555_7 =  (uint8_t) RxMessage_Can1.Data[7];
					Debug_Frame_Management();
					send_can_message_task();
				}
			}	
			else if(RxMessage_Can1.IDE == 1)
			{
			}		
		}
	}
	return 1;
}

extern void Debug_Frame_Management(void)
{
	uint16_t temp = 0;
	if(Can_Rec_Debug_Frame_Flag == 1)
	{
		
		temp = Rec_Byte_555_0;
		temp = (temp << 8) + Rec_Byte_555_1;
		message.vol = temp / 10;
		
		temp = Rec_Byte_555_2;
		temp = (temp << 8) + Rec_Byte_555_3;
		message.curr = temp / 100 - 300;
	}
	
}

extern void  send_can_message_task(void)
{
	if(Can_Rec_Debug_Frame_Flag ==1)
	{
		uint8_t i = 0;
		TxMessage.ID = ACK_DBG_ADDRESS_666;     
		TxMessage.RTR = 0; 
		TxMessage.IDE = 0;	
		TxMessage.DLC = 8; 
		
		TxMessage.Data[i++] = ((message.vol * 10) >> 8) & 0xFF;
		TxMessage.Data[i++] = (message.vol * 10) & 0xFF;
		TxMessage.Data[i++] = (((message.curr + 300) * 100) >> 8 ) & 0xFF;
		TxMessage.Data[i++] = ((message.curr + 300) * 100) & 0xFF;
		TxMessage.Data[i++] = Rec_Byte_555_4;
		TxMessage.Data[i++] = Rec_Byte_555_5;
		TxMessage.Data[i++] = Rec_Byte_555_6;
		TxMessage.Data[i++] = Rec_Byte_555_7;
		
		if(CAN_MessageSend(CAN1, &TxMessage, TRANSMIT_SECONDARY) != 0)
			{
				
			}
		Can_Rec_Debug_Frame_Flag = 0;
	}
	
}

上位机使用的PCAN-Explorer,报文dbc如下:
在这里插入图片描述
在这里插入图片描述
以下是测试结果:
在这里插入图片描述
测试结果表明MCU上电后能够通过编写的简单的bootloader跳转至APP区且CAN通信正常,下一步我们将尝试编写更复杂的支持通过CAN通信刷写APP的bootloader。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无名小屁喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值