栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从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。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/938548.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号