上一篇:【飞思卡尔 MC9S12】内部D-Flash模拟EEPROM
本篇讲述BootLoader下位机的开发。
刚到新公司第三天就接了一个项目,搞到现在才局部完成,更新比较慢了。
先上传源码比较实际,再介绍基本功能。
源码地址:https://download.csdn.net/download/u010875635/11692136
实际上搞定CAN通信和Flash读写,Bootloader下位机就没什么问题了。
注意一下Bootloader与App的分区划分。
Bootloader与App分别占用2个非分页区。
Bootloader: 0xC000-0xFFFF(实际到0xF7FF,保留一个sector给vector table)
Application: 0x4000-0x7FFF,加上其它分页区(转换成全局地址为0x7F4000-0x7FFFF)
Bootloader实际上核心逻辑没有什么东西,无非就是传输协议,数据重新组合,然后写进去,只不过数据组合的方式决定了刷写的速度。
MCU上电后,首先会进入Bootloader中,1s内没有收到刷写命令(如果App可以接收跳转,则时间不需要这么久,可直接从App跳到Bootloader进行刷写),就会跳到App。数据的CAN ID和命令的CAN ID分开。
本Bootloader采用按行传送数据,减少地址传送次数,以及数据和命令分开传送的方式,提高单位时间数据传送量,以加快刷写速度,在刷写结束后,做个简单校验(例如CRC校验,此处没有做,大家可以自行补充),然后在某个地方写Flag标识,开机启动时Bootloader会读取这个标识,然后判断App是否完好,若是完好,则会在超时后跳到App。
需要注意的是,跳转前要将使用的设备DeInit,例如CAN,否则App使用时可能会有问题。
核心逻辑代码如下(详细请参考源码):
void main(void)
{
McuDrivers_System_Init();
McuDrivers_GPIO_Init();
McuDrivers_CAN2_Init();
EnableInterrupts;
CAN_Send(1,g_Bootloader_EntryBootloaderReponse,8);
for(;;)
{
CAN_Tasks(); //can
Tick_Tasks();
//_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
UINT32 countTick = 0;
UINT8 Tick_Tasks()
{
countTick++;
//每隔1000大约1ms
if(countTick==1000)
{
countTick=0;
return Time_Tasks();
}
return 1;
}
UINT32 countTimer=0;
UINT8 Time_Tasks()
{
countTimer++;
if(countTimer<(1000*g_GOTOAPP_TIMEOUT))
{
if(countTimer%500==0)
McuDriver_GPIO_PB0_Toggle(); //blue led blink
}
else if(countTimer==(1000*g_GOTOAPP_TIMEOUT))
{
app_entry();
return 0;
}
if(countTimer>(1000*g_GOTOAPP_TIMEOUT*10))
countTimer=(1000*g_GOTOAPP_TIMEOUT)+1;
return 1;
}
Scm_CanStandData m_CAN_RxMsg; /* for CAN RX */
#pragma MESSAGE DISABLE C1420 //result of function call is ignore
//send can data
void CAN_Send(UINT8 isCmdType,UINT8 *datas,UINT8 length)
{
m_CAN_RxMsg.U32ID = isCmdType==1?SendCmdCANID:SendDataCANID;
m_CAN_RxMsg.DataType = 0; //data type
m_CAN_RxMsg.DataFormat = 1; //ext
m_CAN_RxMsg.DataLength = length;
memcpy(m_CAN_RxMsg.Datas,datas,length);
McuDrivers_CAN2_SendData(&m_CAN_RxMsg);
}
void Software_Wait(UINT16 milliSeconds)
{
UINT16 i,j;
for(i=0;i } //UINT32 g_ReceiveCount=0; UINT8 m_State = 0; #pragma MESSAGE DISABLE C2705//result of function call is ignore //Receive Can Data void CAN_Tasks() { Protocol_Bootloader_CmdType result; int reponse = 0; if(McuDrivers_CAN2_GetStateRX()) { if(McuDrivers_CAN2_ReadData(&m_CAN_RxMsg)==ERR_OK) { if(m_CAN_RxMsg.U32ID==ReceiveCmdCANID) //cmd id { result = Bootloader_DataParse_g(m_CAN_RxMsg.Datas,m_CAN_RxMsg.DataLength); switch (result) { case Reset: app_entry(); /*jump to app and should not back */ break; case FlashErase: if(m_State==0) { countTimer=(1000*g_GOTOAPP_TIMEOUT)+1; reponse = UserFlash_EraseIvtAndUserAppBlock_g(m_CAN_RxMsg.Datas,m_CAN_RxMsg.DataLength); switch(reponse) { case -1: g_Bootloader_EraseFlashReponse[1]=AddressChecksumError; break; case -2: g_Bootloader_EraseFlashReponse[1]= AddressOverRange; break; case -3: g_Bootloader_EraseFlashReponse[1]= EraseFailed; break; default: g_Bootloader_EraseFlashReponse[1]= CmdRunOK; UserFlash_ClearAppIndicate_g(APP_UPDATE_OK_GLOBAL_ADDR); //clear app flag McuDriver_GPIO_PB0_Set(); // led 0 off m_State = 1; break; } CAN_Send(1,g_Bootloader_EraseFlashReponse,8); } break; case SendAddress: if(m_State==1) { // g_ReceiveCount++; //if(g_ReceiveCount>=20063) // _asm(nop); reponse = UserFlash_AddrParse_g(m_CAN_RxMsg.Datas,m_CAN_RxMsg.DataLength); switch(reponse) { case -1: g_Bootloader_SendAddressReponse[1]=AddressChecksumError; break; case -2: g_Bootloader_SendAddressReponse[1]= DataChecksumError; break; default: g_Bootloader_SendAddressReponse[1]= CmdRunOK; break; } CAN_Send(1,g_Bootloader_SendAddressReponse,8); } break; case DataEnd: reponse = UserFlash_CheckLastLineChecksumAndWritten_g(); //write last line to flash switch(reponse) { case -1: g_Bootloader_DataProgramEndReponse[1]=DataChecksumError; break; case -2: g_Bootloader_DataProgramEndReponse[1]= FlashProgramFailed; break; default:
上一篇:MC9S12XE的模拟EEPROM综述
下一篇:飞思卡尔MC9S12(X)系列的内存资源分配和.prm文件的结构
推荐阅读最新更新时间:2024-11-13 20:22
设计资源 培训 开发板 精华推荐
- LTC3863 的典型应用 - 60V 低 IQ 反相 DC/DC 控制器
- LTC2992HMS-1 双向宽范围功率监视器的典型应用
- LTC1530CS8 演示板、高效升压稳压器、3.3Vin、5Vout @ 5A
- LTC3835EGN 演示板、低 Iq、36Vin 同步降压控制器
- DC2269A-C,用于 LTM4675 双路 13A 降压模块的演示板,带有 PMBU,4.5V = VIN = 26.5V,Vout0 = 1V @ 13A,Vout1 = 1.8V @ 13A
- WCH-LinkE-Mini
- 水墨屏驱动板
- WT588D烧录转接板
- TCR2EN10、200mA、1V 输出电压 CMOS 低压降稳压器的典型应用
- 电源电路包含用于反转单相电机的分立半导体器件