【飞思卡尔 MC9S12】BootLoader 下位机

 

本篇讲述BootLoader下位机的开发。

Bootloader上位机、下位机以及用户App 范例源码:https://gitee.com/beatfan/freescale_mc9s12xep100_-bootloader.git

实际上搞定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<milliSeconds;i++)
        for(j=0;j<1000;j++) ;
               
}

//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:
                            g_Bootloader_DataProgramEndReponse[1]= CmdRunOK;
                            UserFlash_SetAppIndicate_g(APP_UPDATE_OK_GLOBAL_ADDR); //set app flag
                            McuDriver_GPIO_PB0_Set(); // led 0 off
                            break;
                        }
        				
                        Software_Wait(100);
        				CAN_Send(1,g_Bootloader_DataProgramEndReponse,8);

        				app_entry();          /*jump to app and should not back */
        				break;

        			case CheckBootloader:
        				CAN_Send(1,g_Bootloader_CheckBootloaderReponse,8);
        				break;

        			
        			default:
        				break;
        		}/*end if switch*/
            }
    		else if(m_CAN_RxMsg.U32ID==ReceiveDataCANID)  //cmd id
            {
    			if(m_State==1)
    		    {
    		      
    		      //g_ReceiveCount++;
    		      //if(g_ReceiveCount>=20063)
    		      //  _asm(nop);
    				UserFlash_DataParse_g(m_CAN_RxMsg.Datas,m_CAN_RxMsg.DataLength);
    				McuDriver_GPIO_PB2_Toggle(); //led 2 blink

    				CAN_Send(0,g_Bootloader_SendDataReponse,8);
    				
    				
    		    }
        			
            }

        }
         

	}/*end of g_CAN0_BufferReceive_Flag==1 if*/
}

 

posted on 2019-07-04 08:27  Beatfan  阅读(371)  评论(0)    收藏  举报

导航