打印
[Kinetis]

【经验分享】AN2295 bootloader文档解析(二)

[复制链接]
3418|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AN2295 bootloader文档解析
AN2295提供了基于8-bit MCU、Coldfire、Kinetis版本的boot loader代码,开发者可根据自己所选MCU的型号,选择对应的版本。由于在同一版本的boot loader代码中,为了适用于同一类型但不同系列的MCU,所以就定义了很多变量以作不同系列MCU的选择之用,但这样会导致bootloader代码的复杂程度递增,从而增加分析的难度。
    所以出于上述的原因,特地选择FRDM-KE02boot loader例程,其可为作为AN2295 bootloader代码的“简装版”,来介绍boot loader例程的工作原理及流程。
Ø  主程序代码说明
int main(void)                                                                     
{                                                                                 
        uint32_t uiNullCounter = 0;                                                      
        uint32_t uiRepeatCount = 0;                                                      
        FC_Init();   
    for(;;) {                                                                         
                                                              
                if( !FC_Communication() )                                                      
                {                                                                              
                        if( g_ucFC_State == FC_STATE_NULL )                                          
                        {                                                                           
                                uiNullCounter ++;                                                         
                                if( uiNullCounter > 0xffff )                                               
                                {                                                                          
                                        uiNullCounter = 0;                                                      
                                        uiRepeatCount ++;                                                        
                                        UART_putchar(TERM_PORT,0xfc);                                                     
                                }                                                                                                                                                                    
                                if( uiRepeatCount > CONNECT_OVER_TIME )                                    
                                {                                                                          
                    #ifdef FLASH_LOCATION                                          
                                        SCB_VTOR = RELOCATION_VERTOR_ADDR;                                       
                                        JumpToUserApplication(RELOCATION_VERTOR_ADDR);                           
                    #endif                                                         
                                }                                                                          
                        }                                                                           
                }                                                                              
                                                                                   
        }                                                                                                                                                  
        return 0;                                                                  
}               
Ø  FC_Init函数

void FC_Init( void )
{
        Flash_Init();                               //初始化Flash时钟
        m_pRecFrame = (uint8_t *)&m_RecFrame;
        g_ucFC_State = FC_STATE_NULL;
        m_uiRecCount = 0;                       //初始化各变量值
}
Ø  FC_ Communication函数
unsigned char FC_Communication( void )
{
        uint8_t uiReadData,i;
        uint8_t *pAddress;
        ADDRESS_TYPE * pTempAddress;
                                           // 判断UART有无收到数据
        if(UART_S1_RDRF_MASK != UART_getchar_present(TERM_PORT))
        {
                return 0;
        }
                                               // 读取UART收到的数据
        uiReadData = UART_getchar(TERM_PORT);
        switch( g_ucFC_State )
        {
                case FC_STATE_NULL:
                {
                        if( uiReadData == FC_CMD_ACK )         // FC_CMD_ADK即为0xFC
                        {
          //由于KE02波特率设置精准,所以例程中无MCU与PC波特率同步校准函数
                                UART_putchar( TERM_PORT,0xfc );
g_ucFC_State = FC_STATE_WORKING;  // 进入接受命令操作状态
                        }
                        else
                        {
                                return 0;
                        }
                }
                break;
                case FC_STATE_WORKING:
                        {
                                switch( uiReadData )
                                {
                 // Ident指令(0x49),发送boot loader的相关属性信息
                                case FC_CMD_IDENT:     
                                        {
                                                UART_putchar( TERM_PORT,m_MCU_Info.Version);
                                                UART_putchar( TERM_PORT,m_MCU_Info.Sdid>>8);
                                                UART_putchar( TERM_PORT,m_MCU_Info.Sdid);
                                        pTempAddress=(ADDRESS_TYPE *)&m_MCU_Info.BlocksCnt;
                                                for(i=0;i<7;i++)
                                                {
                                                UART_putchar( TERM_PORT,pTempAddress[i].Bytes.hh);
                                                UART_putchar( TERM_PORT,pTempAddress[i].Bytes.hl);
                                                UART_putchar( TERM_PORT,pTempAddress[i].Bytes.lh);
                                                UART_putchar( TERM_PORT,pTempAddress[i].Bytes.ll);
                                                }
                                                i = 0;
                                                do
                                                {
                                                 UART_putchar( TERM_PORT,m_MCU_Info.IdString[i]);
                                                }while(m_MCU_Info.IdString[i++]);
                                }
                                break;
                // Erase指令(0x45),进入Erase Flash 操作
                                case FC_CMD_ERASE:
                                        {
                                                g_ucFC_State = FC_STATE_EREASE;
                                }
                                break;
                // Write指令(0x57),进入Write Flash操作
                                case FC_CMD_WRITE:
                                        {
                                                g_ucFC_State = FC_STATE_WRITE_ADDRESS;
                                }
                                break;
//Read指令(0x52),进入Read Flash 操作
                                case FC_CMD_READ:
                                        {
                                                g_ucFC_State = FC_STATE_READ;
                                }
                                break;
//Quit指令(0x51),进入Quit 操作
                                case FC_CMD_QUIT:
                                        {
         //中断向量重定位
                                                 SCB_VTOR = RELOCATION_VERTOR_ADDR;
        //跳转到User application
                                                 JumpToUserApplication(RELOCATION_VERTOR_ADDR);                        
                                }
                                break;
                                default:
                                        break;
                        }
                        m_uiRecCount = 0;
                }
                break;
            // Erase flash操作中
                case FC_STATE_EREASE:
                        {
                                m_pRecFrame[m_uiRecCount++] = uiReadData;
                                if( m_uiRecCount >= sizeof(uint32_t) )
                                {
                                        //地址字节校正
                                        LONG_Convert(&m_RecFrame.uiAddress);
                    //判断Erase flash操作是否成功
                                        if(!Flash_EraseSector(m_RecFrame.uiAddress))
                                        {
                                                UART_putchar( TERM_PORT,FC_CMD_ACK );
                                        }
                                        else
                                        {
                                                UART_putchar( TERM_PORT,FC_CMD_NACK );
                                        }
                                        g_ucFC_State = FC_STATE_WORKING;
                                }
                }
                break;
        // 接受Write Flash操作的起始地址
                case FC_STATE_WRITE_ADDRESS:
                        {
                                m_pRecFrame[m_uiRecCount++] = uiReadData;
                                if( m_uiRecCount >= sizeof(uint32_t) )
                                {
                                        g_ucFC_State = FC_STATE_WRITE_LEN;
                                }
                               
                }
                break;
// 接受Write Flash操作的字节个数
                case FC_STATE_WRITE_LEN:
                        {
                                m_pRecFrame[m_uiRecCount++] = uiReadData;
                                g_ucFC_State = FC_STATE_WRITE_DATA;
                }
                break;
// 接受Write Flash操作的数据
                case FC_STATE_WRITE_DATA:
                        {
                                m_pRecFrame[m_uiRecCount++] = uiReadData;
                                if( m_uiRecCount > (m_RecFrame.Length + sizeof(uint32_t) ))
                                {
                                        LONG_Convert(&m_RecFrame.uiAddress);
Memcpy_Byte((uint8_t*)&m_ucDataBuff[0],(uint8_t*)&m_RecFrame.DataBuff[0],
m_RecFrame.Length);
                        uiNumberCount ++;
                    if( !Flash_Program(m_RecFrame.uiAddress,
                                   (uint8_t *)&m_ucDataBuff[0],m_RecFrame.Length) )
                                        {
                                                UART_putchar( TERM_PORT,FC_CMD_ACK );
                                        }
                                        else
                                        {
                                                UART_putchar( TERM_PORT,FC_CMD_NACK );
                                        }
                  
                                        g_ucFC_State = FC_STATE_WORKING;
                                }
                        }       
                        break;
//Read Flash操作
                case FC_STATE_READ:
                        {
                                m_pRecFrame[m_uiRecCount++] = uiReadData;
                                if( m_uiRecCount > sizeof(uint32_t) )
                                {
                                        LONG_Convert(&m_RecFrame.uiAddress);
                                        pAddress = (uint8_t *)m_RecFrame.uiAddress;
                                        for( i=0;i<m_RecFrame.Length;i++)
                                        {
                                                UART_putchar( TERM_PORT,pAddress[i] );
                                        }
                                        g_ucFC_State = FC_STATE_WORKING;
                                }
                }
                break;
                default:
                        break;
                }
        return 1;
}
Boot loader程序流程图
  boot loader例程程序流程图如下图所示。


文档下载
AN2295—Developer’s Serial Bootloader 解析(二).pdf (457.14 KB)
FRDM-KE02例程包:




相关帖子

沙发
FSL_TICS_A|  楼主 | 2014-7-21 10:16 | 只看该作者


不足之处,欢迎指正,未完待续!!

使用特权

评论回复
板凳
ar_m_cu| | 2014-7-21 10:18 | 只看该作者
顶,支持

使用特权

评论回复
地板
FSL_TICS_ZJJ| | 2014-7-21 10:18 | 只看该作者
最新经验分享,欢迎大家学习。

使用特权

评论回复
5
xinyinxing| | 2014-7-21 21:03 | 只看该作者
感谢分享,支持@

使用特权

评论回复
6
FSL_TICS_Jeremy| | 2014-8-5 14:02 | 只看该作者
ar_m_cu 发表于 2014-7-21 10:18
顶,支持

谢谢支持,关于Bootloader使用有什么疑问的话,可以来论坛中讨论!

使用特权

评论回复
7
风电小二| | 2017-9-14 15:23 | 只看该作者
先赞一个

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

41

主题

1014

帖子

20

粉丝