搜索
bottom↓
回复: 37

AN2295 bootloader文档解析(二)

[复制链接]

出0入0汤圆

发表于 2014-7-21 10:05:43 | 显示全部楼层 |阅读模式
本帖最后由 FSL_TICS_ZP 于 2014-7-21 10:08 编辑

AN2295 bootloader文档解析

AN2295提供了基于8-bit MCU、Coldfire、Kinetis版本的boot loader代码,开发者可根据自己所选MCU的型号,选择对应的版本。由于在同一版本的boot loader代码中,为了适用于同一类型但不同系列的MCU,所以就定义了很多变量以作不同系列MCU的选择之用,但这样会导致boot loader代码的复杂程度递增,从而增加分析的难度。
    所以出于上述的原因,特地选择FRDM-KE02的boot loader例程,其可为作为AN2295 boot loader代码的“简装版”,来介绍boot loader例程的工作原理及流程。
        主程序代码说明
  1. int main(void)                                                                     
  2. {                                                                                 
  3.         uint32_t uiNullCounter = 0;                                                      
  4.         uint32_t uiRepeatCount = 0;                                                      
  5.         FC_Init();   
  6.     for(;;) {                                                                         
  7.                                                               
  8.                 if( !FC_Communication() )                                                      
  9.                 {                                                                              
  10.                         if( g_ucFC_State == FC_STATE_NULL )                                          
  11.                         {                                                                           
  12.                                 uiNullCounter ++;                                                         
  13.                                 if( uiNullCounter > 0xffff )                                               
  14.                                 {                                                                          
  15.                                         uiNullCounter = 0;                                                      
  16.                                         uiRepeatCount ++;                                                        
  17.                                         UART_putchar(TERM_PORT,0xfc);                                                     
  18.                                 }                                                                                                                                                                    
  19.                                 if( uiRepeatCount > CONNECT_OVER_TIME )                                    
  20.                                 {                                                                          
  21.                     #ifdef FLASH_LOCATION                                          
  22.                                         SCB_VTOR = RELOCATION_VERTOR_ADDR;                                       
  23.                                         JumpToUserApplication(RELOCATION_VERTOR_ADDR);                           
  24.                     #endif                                                         
  25.                                 }                                                                          
  26.                         }                                                                           
  27.                 }                                                                              
  28.                                                                                    
  29.         }                                                                                                                                                  
  30.         return 0;                                                                  
  31. }               
复制代码


        FC_Init函数
  1. void FC_Init( void )
  2. {
  3.         Flash_Init();                               //初始化Flash时钟
  4.         m_pRecFrame = (uint8_t *)&m_RecFrame;
  5.         g_ucFC_State = FC_STATE_NULL;
  6.         m_uiRecCount = 0;                       //初始化各变量值
  7. }
复制代码


        FC_ Communication函数
  1. unsigned char FC_Communication( void )
  2. {
  3.         uint8_t uiReadData,i;
  4.         uint8_t *pAddress;
  5.         ADDRESS_TYPE * pTempAddress;
  6.                                            // 判断UART有无收到数据
  7.         if(UART_S1_RDRF_MASK != UART_getchar_present(TERM_PORT))
  8.         {
  9.                 return 0;
  10.         }
  11.                                                // 读取UART收到的数据
  12.         uiReadData = UART_getchar(TERM_PORT);
  13.         switch( g_ucFC_State )
  14.         {
  15.                 case FC_STATE_NULL:
  16.                 {
  17.                         if( uiReadData == FC_CMD_ACK )         // FC_CMD_ADK即为0xFC
  18.                         {
  19.           //由于KE02波特率设置精准,所以例程中无MCU与PC波特率同步校准函数
  20.                                 UART_putchar( TERM_PORT,0xfc );
  21. g_ucFC_State = FC_STATE_WORKING;  // 进入接受命令操作状态
  22.                         }
  23.                         else
  24.                         {
  25.                                 return 0;
  26.                         }
  27.                 }
  28.                 break;
  29.                 case FC_STATE_WORKING:
  30.                         {
  31.                                 switch( uiReadData )
  32.                                 {
  33.                  // Ident指令(0x49),发送boot loader的相关属性信息
  34.                                 case FC_CMD_IDENT:     
  35.                                         {
  36.                                                 UART_putchar( TERM_PORT,m_MCU_Info.Version);
  37.                                                 UART_putchar( TERM_PORT,m_MCU_Info.Sdid>>8);
  38.                                                 UART_putchar( TERM_PORT,m_MCU_Info.Sdid);
  39.                                         pTempAddress=(ADDRESS_TYPE *)&m_MCU_Info.BlocksCnt;
  40.                                                 for(i=0;i<7;i++)
  41.                                                 {
  42.                                                 UART_putchar( TERM_PORT,pTempAddress[i].Bytes.hh);
  43.                                                 UART_putchar( TERM_PORT,pTempAddress[i].Bytes.hl);
  44.                                                 UART_putchar( TERM_PORT,pTempAddress[i].Bytes.lh);
  45.                                                 UART_putchar( TERM_PORT,pTempAddress[i].Bytes.ll);
  46.                                                 }
  47.                                                 i = 0;
  48.                                                 do
  49.                                                 {
  50.                                                  UART_putchar( TERM_PORT,m_MCU_Info.IdString[i]);
  51.                                                 }while(m_MCU_Info.IdString[i++]);
  52.                                 }
  53.                                 break;
  54.                 // Erase指令(0x45),进入Erase Flash 操作
  55.                                 case FC_CMD_ERASE:
  56.                                         {
  57.                                                 g_ucFC_State = FC_STATE_EREASE;
  58.                                 }
  59.                                 break;
  60.                 // Write指令(0x57),进入Write Flash操作
  61.                                 case FC_CMD_WRITE:
  62.                                         {
  63.                                                 g_ucFC_State = FC_STATE_WRITE_ADDRESS;
  64.                                 }
  65.                                 break;
  66. //Read指令(0x52),进入Read Flash 操作
  67.                                 case FC_CMD_READ:
  68.                                         {
  69.                                                 g_ucFC_State = FC_STATE_READ;
  70.                                 }
  71.                                 break;
  72. //Quit指令(0x51),进入Quit 操作
  73.                                 case FC_CMD_QUIT:
  74.                                         {
  75.          //中断向量重定位
  76.                                                  SCB_VTOR = RELOCATION_VERTOR_ADDR;
  77.         //跳转到User application
  78.                                                  JumpToUserApplication(RELOCATION_VERTOR_ADDR);                        
  79.                                 }
  80.                                 break;
  81.                                 default:
  82.                                         break;
  83.                         }
  84.                         m_uiRecCount = 0;
  85.                 }
  86.                 break;
  87.             // Erase flash操作中
  88.                 case FC_STATE_EREASE:
  89.                         {
  90.                                 m_pRecFrame[m_uiRecCount++] = uiReadData;
  91.                                 if( m_uiRecCount >= sizeof(uint32_t) )
  92.                                 {
  93.                                         //地址字节校正
  94.                                         LONG_Convert(&m_RecFrame.uiAddress);
  95.                     //判断Erase flash操作是否成功
  96.                                         if(!Flash_EraseSector(m_RecFrame.uiAddress))
  97.                                         {
  98.                                                 UART_putchar( TERM_PORT,FC_CMD_ACK );
  99.                                         }
  100.                                         else
  101.                                         {
  102.                                                 UART_putchar( TERM_PORT,FC_CMD_NACK );
  103.                                         }
  104.                                         g_ucFC_State = FC_STATE_WORKING;
  105.                                 }
  106.                 }
  107.                 break;
  108.         // 接受Write Flash操作的起始地址
  109.                 case FC_STATE_WRITE_ADDRESS:
  110.                         {
  111.                                 m_pRecFrame[m_uiRecCount++] = uiReadData;
  112.                                 if( m_uiRecCount >= sizeof(uint32_t) )
  113.                                 {
  114.                                         g_ucFC_State = FC_STATE_WRITE_LEN;
  115.                                 }
  116.                                
  117.                 }
  118.                 break;
  119. // 接受Write Flash操作的字节个数
  120.                 case FC_STATE_WRITE_LEN:
  121.                         {
  122.                                 m_pRecFrame[m_uiRecCount++] = uiReadData;
  123.                                 g_ucFC_State = FC_STATE_WRITE_DATA;
  124.                 }
  125.                 break;
  126. // 接受Write Flash操作的数据
  127.                 case FC_STATE_WRITE_DATA:
  128.                         {
  129.                                 m_pRecFrame[m_uiRecCount++] = uiReadData;
  130.                                 if( m_uiRecCount > (m_RecFrame.Length + sizeof(uint32_t) ))
  131.                                 {
  132.                                         LONG_Convert(&m_RecFrame.uiAddress);
  133. Memcpy_Byte((uint8_t*)&m_ucDataBuff[0],(uint8_t*)&m_RecFrame.DataBuff[0],
  134. m_RecFrame.Length);
  135.                         uiNumberCount ++;
  136.                     if( !Flash_Program(m_RecFrame.uiAddress,
  137.                                    (uint8_t *)&m_ucDataBuff[0],m_RecFrame.Length) )
  138.                                         {
  139.                                                 UART_putchar( TERM_PORT,FC_CMD_ACK );
  140.                                         }
  141.                                         else
  142.                                         {
  143.                                                 UART_putchar( TERM_PORT,FC_CMD_NACK );
  144.                                         }
  145.                   
  146.                                         g_ucFC_State = FC_STATE_WORKING;
  147.                                 }
  148.                         }       
  149.                         break;
  150. //Read Flash操作
  151.                 case FC_STATE_READ:
  152.                         {
  153.                                 m_pRecFrame[m_uiRecCount++] = uiReadData;
  154.                                 if( m_uiRecCount > sizeof(uint32_t) )
  155.                                 {
  156.                                         LONG_Convert(&m_RecFrame.uiAddress);
  157.                                         pAddress = (uint8_t *)m_RecFrame.uiAddress;
  158.                                         for( i=0;i<m_RecFrame.Length;i++)
  159.                                         {
  160.                                                 UART_putchar( TERM_PORT,pAddress[i] );
  161.                                         }
  162.                                         g_ucFC_State = FC_STATE_WORKING;
  163.                                 }
  164.                 }
  165.                 break;
  166.                 default:
  167.                         break;
  168.                 }
  169.         return 1;
  170. }
复制代码


Boot loader程序流程图
  boot loader例程程序流程图如下图所示。


文档下载:

FRDM-KE02例程包:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2014-7-21 10:06:21 | 显示全部楼层

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

出0入0汤圆

发表于 2014-7-21 10:16:01 | 显示全部楼层
mark           

出0入0汤圆

发表于 2014-7-21 10:34:50 | 显示全部楼层
不错终于看到带程序的讲解了
很直观,流程图

出0入0汤圆

发表于 2014-7-21 11:46:04 | 显示全部楼层
很不错,mark以下。

出0入0汤圆

 楼主| 发表于 2014-7-21 13:48:57 | 显示全部楼层
lyzhangxiang 发表于 2014-7-21 10:34
不错终于看到带程序的讲解了
很直观,流程图

欢迎浏览,如有什么疑问请在此帖下留言!

出0入0汤圆

 楼主| 发表于 2014-7-21 13:50:36 | 显示全部楼层
欢迎网友们浏览,如有什么疑问请在此帖下留言!

出0入0汤圆

发表于 2014-8-22 11:17:10 | 显示全部楼层
还要下载第三个,呵呵,收集全了

出0入0汤圆

发表于 2014-8-22 11:32:39 | 显示全部楼层
能不能合在一个文档里啊

出0入0汤圆

发表于 2014-8-22 12:23:40 | 显示全部楼层
这个非常好,有图有程序有解析,这样更容易理解了

出0入0汤圆

发表于 2014-8-22 15:18:21 | 显示全部楼层
很有指导性的文档  希望我申请的KE02快点到   赶快试试

出0入0汤圆

发表于 2014-9-2 13:54:42 | 显示全部楼层
收藏继续学习,这些都是要必须掌握的本领。谢谢楼主。

出0入0汤圆

发表于 2014-9-2 18:05:11 | 显示全部楼层
谁能告诉我 解析(一)的链接在哪里

出0入0汤圆

发表于 2014-9-2 18:08:45 | 显示全部楼层
另外,你们和飞思卡尔中文论坛的那些FAE是一伙人么

出0入0汤圆

发表于 2014-9-4 23:29:28 | 显示全部楼层
楼主的例程包里没发现boot loader工程哦。。。

出0入0汤圆

发表于 2014-9-5 06:22:47 | 显示全部楼层
流程图很清晰啊,辛苦了

出0入0汤圆

 楼主| 发表于 2014-9-5 09:01:17 | 显示全部楼层
lidreamer 发表于 2014-9-2 18:05
谁能告诉我 解析(一)的链接在哪里

AN2295 bootloader文档解析(一)
http://www.amobbs.com/thread-5587485-1-1.html
AN2295 bootloader文档解析(三)
http://www.amobbs.com/thread-5589466-1-1.html

出0入0汤圆

发表于 2014-9-5 09:14:51 | 显示全部楼层
必须支持啊....辛苦了

出0入0汤圆

 楼主| 发表于 2014-9-5 09:25:24 | 显示全部楼层
lidreamer 发表于 2014-9-2 18:08
另外,你们和飞思卡尔中文论坛的那些FAE是一伙人么

一伙人,感觉像不法组织一样。
是的,我们都会在论坛上提供支持。

出0入0汤圆

发表于 2014-9-5 14:02:07 | 显示全部楼层
FSL_TICS_ZP 发表于 2014-9-5 09:25
一伙人,感觉像不法组织一样。
是的,我们都会在论坛上提供支持。

呵呵,不拘小节.....据说,你们以后会着重整那个KBOOT,AN2295就停止维护了是么?

出0入0汤圆

发表于 2014-9-5 14:04:25 | 显示全部楼层
tyqhaha 发表于 2014-9-4 23:29
楼主的例程包里没发现boot loader工程哦。。。

自己去官网下载吧

出0入0汤圆

 楼主| 发表于 2014-9-5 14:06:00 | 显示全部楼层
lidreamer 发表于 2014-9-5 14:02
呵呵,不拘小节.....据说,你们以后会着重整那个KBOOT,AN2295就停止维护了是么? ...

KBOOT肯定替代AN229等一些Bootloader方案,KBOOT是个全新Bootloader方案,
让客户使用起来更加方便。

出0入0汤圆

发表于 2014-9-5 14:07:22 | 显示全部楼层
FSL_TICS_ZP 发表于 2014-9-5 14:06
KBOOT肯定替代AN229等一些Bootloader方案,KBOOT是个全新Bootloader方案,
让客户使用起来更加方便。 ...

正在研究你们的KBOOT,好像目前只支持K64

出0入0汤圆

 楼主| 发表于 2014-9-9 09:26:45 | 显示全部楼层
本帖最后由 FSL_TICS_ZP 于 2014-9-9 09:33 编辑
lidreamer 发表于 2014-9-5 14:07
正在研究你们的KBOOT,好像目前只支持K64


是的,好像这一版只推出针对K64的bootloader例程,保守起见,我再确认一下。

出0入0汤圆

发表于 2014-9-9 09:34:17 | 显示全部楼层
谢谢  分享。。

出0入0汤圆

发表于 2014-9-9 13:36:53 | 显示全部楼层
楼主本论坛里发表的格式很good呀!

出0入0汤圆

发表于 2014-11-26 20:29:01 | 显示全部楼层
不错,赞一个。貌似没有错误处理机制

出0入0汤圆

 楼主| 发表于 2014-11-27 09:27:43 | 显示全部楼层
renjun_EMbest 发表于 2014-11-26 20:29
不错,赞一个。貌似没有错误处理机制

你说的挺正确,错误辨别和处理机制几乎是没有的,这只是一个类似最小系统板的东西,真正应用还需要客户自己添加对应的应用。

出0入0汤圆

发表于 2014-11-30 13:00:06 来自手机 | 显示全部楼层
一直想研究一下这个东西

出0入0汤圆

发表于 2014-11-30 15:57:29 | 显示全部楼层
牛逼 谢谢

出0入0汤圆

发表于 2014-11-30 16:06:47 | 显示全部楼层
只是大概介绍了流程 最终用到产品的时候比这个考虑的肯定会更加全面

出0入0汤圆

 楼主| 发表于 2014-12-1 09:29:16 | 显示全部楼层
子鱼 发表于 2014-11-30 16:06
只是大概介绍了流程 最终用到产品的时候比这个考虑的肯定会更加全面

你好,
你说的很对,本贴介绍的就是实现bootloader的基本内容,真正在产品里肯定不能这么干了,
还可能加上加密,解密等。

出0入0汤圆

发表于 2014-12-1 09:40:09 | 显示全部楼层
不错终于看到带程序的讲解了

出0入0汤圆

发表于 2014-12-2 12:49:54 | 显示全部楼层
看了一下,是不是和STM32的差不多,也是必须建立两个工程分别烧录IAP和APP吗

出0入0汤圆

发表于 2014-12-2 12:54:14 | 显示全部楼层
哎哟喂,才看到这个BOOTLOADER的分析,这绝对要收藏的啊,好东西;

出0入0汤圆

发表于 2014-12-18 16:37:51 | 显示全部楼层
有这个应该可以做烧写器了

出0入0汤圆

发表于 2019-6-10 17:20:45 | 显示全部楼层
下载学习 多谢分享

出0入0汤圆

发表于 2019-6-10 22:09:06 来自手机 | 显示全部楼层
下载学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-23 22:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表