DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 5187|回复: 4
打印 上一主题 下一主题

[UUProg] uuprog开发教程:Bootloader应用讲解2

[复制链接]
跳转到指定楼层
楼主
发表于 2014-11-16 06:23:22 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
      前面已经说了bootloader的基本设置,这次讲解下怎么控制bootloader工作,以便实现我们想要的功能。我们用他来做什么呢?这就是我们的目的:更新固件。要更新固件就要烧写固件代码,那就需要实现:擦出,烧写,校验这几个最基本的功能,当然其他功能就需要你自己发挥了。

这里就是要实现的功能,其实很简单的,我们用到了字符型的控制命令,这样的好处当然是为了容易理解。当然你要是用于商业化最好还是不要用这种明码方式了,自己想想吧,题外话了。
我们这里设置了个专门的处理函数,就是为了大家方便添加自己的处理功能,而不用关心usb协议的工作原理。说真的usb协议确实很难理解,所以很多人一说到usb就说头大,其实头大的不是usb协议,而是usb调试比较困难,不是很直观,不像串口调试那么简单而已。现在都有专业化的usb协议框架,自己只需要处理相关的函数就行。
这里我们用到的是端点1,他的相关处理函数如下:
  1. //-----------------------------------------------------------------------------
  2. // Handle_In1
  3. //-----------------------------------------------------------------------------
  4. //
  5. // Return Value : None
  6. // Parameters   : None
  7. //
  8. // This routine loads the current value from In_Packet on the Endpoint 2 fifo,
  9. // after  an interrupt is received from the last packet being transmitted
  10. //
  11. //-----------------------------------------------------------------------------

  12. void U_Handle_In1()
  13. {
  14.         BYTE ControlReg;
  15.         POLL_WRITE_BYTE(INDEX, 1);           // Set index to endpoint 1 registers
  16.         POLL_READ_BYTE(EINCSR1, ControlReg); // Read contol register for EP 1
  17.         
  18.         if (U_Ep_Status[1] == EP_HALT)         // If endpoint is currently halted, send a stall
  19.         {
  20.                 POLL_WRITE_BYTE(EINCSR1, rbInSDSTL);
  21.         }
  22.         
  23.         else                                 // Otherwise send last updated data to host
  24.         {
  25.                 if(ControlReg & rbInINPRDY)
  26.                 {
  27.                         return;
  28.                 }

  29.                 if (ControlReg & rbInSTSTL)       // Clear sent stall if last packet returned a stall
  30.                 {
  31.                         POLL_WRITE_BYTE(EINCSR1, rbInCLRDT);
  32.                 }
  33.                
  34.                 if (ControlReg & rbInUNDRUN)      // Clear underrun bit if it was set
  35.                 {
  36.                         POLL_WRITE_BYTE(EINCSR1, 0x00);
  37.                 }
  38.                
  39.                 if(U_EP1SendLen > 0)
  40.                 {
  41.                         U_Fifo_Write(FIFO_EP1, U_EP1SendLen, cmdbuf);        // Put new data on Fifo
  42.                         POLL_WRITE_BYTE(EINCSR1, rbInINPRDY);                         // Set In Packet ready bit, indicating
  43.                         U_EP1SendLen = 0;
  44.                 }
  45.         }                                                                                  // fresh data on Fifo 1
  46. }

  47. //-----------------------------------------------------------------------------
  48. // Handle_Out1
  49. //-----------------------------------------------------------------------------
  50. //
  51. // Return Value : None
  52. // Parameters   : None
  53. //
  54. // Take the received packet from the host off the fifo and put it into
  55. // the Out_Packet array
  56. //
  57. //-----------------------------------------------------------------------------

  58. void U_Handle_Out1()
  59. {
  60.         BYTE Count = 0;
  61.         BYTE ControlReg;
  62.         
  63.         POLL_WRITE_BYTE(INDEX, 1);          // Set index to endpoint 2 registers
  64.         POLL_READ_BYTE(EOUTCSR1, ControlReg);
  65.         
  66.         if (U_Ep_Status[2] == EP_HALT)        // If endpoint is halted, send a stall
  67.         {
  68.                 POLL_WRITE_BYTE(EOUTCSR1, rbOutSDSTL);
  69.         }
  70.         else                                // Otherwise read packet from host
  71.         {
  72.                 if (ControlReg & rbOutSTSTL)     // Clear sent stall bit if last packet  was a stall
  73.                 {
  74.                         POLL_WRITE_BYTE(EOUTCSR1, rbOutCLRDT);
  75.                 }
  76.                
  77.                 POLL_READ_BYTE(EOUTCNTL, Count);
  78.                 U_Fifo_Read(FIFO_EP1, Count, cmdbuf);
  79.                 Cmd_process();
  80.                 U_EP1SendLen = 0x40;
  81.                 U_Handle_In1();
  82.                 POLL_WRITE_BYTE(EOUTCSR1, 0);    // Clear Out Packet ready bit
  83.         }
  84. }
复制代码
里面已经添加了专门处理函数Cmd_process(),下面是这个函数的实现代码:
  1. unsigned char Cmd_process(void)
  2. {
  3.         switch(cmdbuf[1])
  4.         {
  5.                 case 'E':        //擦除
  6.                         FlashErase(*((unsigned int *)(cmdbuf + 2)));
  7.                         cmdbuf[1] = RES_OK;
  8.                         cmdbuf[2] = 2;
  9.                         return 1;
  10.                 case 'C':        //校验数据
  11.                         cmdbuf[1] = FlashCheck(*((unsigned int *)(cmdbuf + 2)),&cmdbuf[5],cmdbuf[4]);
  12.                         cmdbuf[2] = 2;
  13.                         return 1;
  14.                 case 'W':        //写数据
  15.                         FlashWrite(*((unsigned int *)(cmdbuf + 2)),&cmdbuf[5],cmdbuf[4]);
  16.                         cmdbuf[1] = RES_OK;
  17.                         cmdbuf[2] = 2;
  18.                         return 1;
  19.                 case 'V':        //读版本
  20.                         cmdbuf[1] = RES_OK;
  21.                         cmdbuf[2] = 7;
  22.                         cmdbuf[3] = 'V';
  23.                         cmdbuf[4] = '1';
  24.                         cmdbuf[5] = '.';
  25.                         cmdbuf[6] = '0';
  26.                         cmdbuf[7] = '0';
  27.                         cmdbuf[8] = '\0';
  28.                         return 1;
  29.                 case 'R':        //运行客户程序
  30.                         RunUserProg();
  31.                         return 2;
  32.                 case 'T':        //Bootloader测试
  33.                         cmdbuf[1] = RES_OK;
  34.                         cmdbuf[2] = 1;
  35.                         cmdbuf[3] = '-';
  36.                         return 1;
  37.                 default:
  38.                         return 0;
  39.         }
  40. }
复制代码
具体的每个功能函数的实现就自己下载源代码看了,师父领进门,修行在个人嘛,不可能面面俱到的,实现代码不难,难在你自己怎么看。不理解的代码就赶紧进补下。
下次将讲解上位机怎么控制这个固件实现你得功能,欢迎大家密切关注。



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏1 分享分享 支持支持 反对反对
板凳
发表于 2014-11-18 22:17:10 | 只看该作者
门外汉,门外羡慕嫉妒恨中~~~~~~
地板
发表于 2015-1-11 21:29:04 | 只看该作者
不知完成了编程器,还学习了mcu技术.赞
5#
发表于 2021-1-24 13:44:54 | 只看该作者
可以的 其实最好能发命令进入bootloader 直接搞短接 不太好
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-11-23 04:29 , 耗时 0.102595 秒, 25 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

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