[讨论] [SAM R21]ASF 3.21中关于USB的bug

dcexpert   2015-1-26 00:42 楼主
这两天一直被SAM R21上的USB例程所困扰,将ASF 3.21中的USB CDC、USB Keyboard例程下载到板子上,都不能正常运行,系统提示无法识别的设备。 找了很久也没有找到原因。后来偶然想到试试低版本的ASF例程,因为以前遇到过新版本的ASF在I2C上存在问题而旧版本是正常的,于是尝试了一下ASF 3.20上同样的USB CDC和USB Keyboard例程,结果发现它们是正常的,说明这次的问题又出在新版本上了。 找到问题就好办了,下面就是用比较法和文件替换法查找具体的原因了。这是一个有点痛苦的过程,因为ASF中的文件实在太多了。具体过程就不多说了,就是一个一个文件对比。我使用了Total Commander内置的文件比较功能,虽然它的功能不是最强,但是比其他软件方便快速,适合多个文件比较。最后发现是 ASF\sam0\utils\cmsis\samr21\source\gcc\startup_samr21.c 这个文件的问题。 在ASF 3.21中,增加了一些IRQ的定义,目的可能是为了节约程序空间,提高代码效率。对USB部分增加的是USB_IRQn。在startup_samr21.c中,前后对比是: ASF 3.20
  1. void USB_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
  2. ...
  3. (void*) USB_Handler, /* 7 Universal Serial Bus */
ASF 3.21
  1. #ifdef USB_IRQn
  2. void USB_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
  3. #endif
USB_IRQn这个定义有点奇怪,从#ifdef USB_IRQn这个用法看,它应该是一个宏定义,但是在程序中它是在文件ASF\sam0\utils\cmsis\samr21\include\samr21g18a.h定义的,具体定义是一个枚举类型:
  1. /** Interrupt Number Definition */
  2. typedef enum IRQn
  3. {
  4. /****** Cortex-M0+ Processor Exceptions Numbers ******************************/
  5. NonMaskableInt_IRQn = -14,/**< 2 Non Maskable Interrupt */
  6. HardFault_IRQn = -13,/**< 3 Cortex-M0+ Hard Fault Interrupt */
  7. SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */
  8. PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */
  9. SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */
  10. /****** SAMR21G18A-specific Interrupt Numbers ***********************/
  11. PM_IRQn = 0, /**< 0 SAMR21G18A Power Manager (PM) */
  12. SYSCTRL_IRQn = 1, /**< 1 SAMR21G18A System Control (SYSCTRL) */
  13. WDT_IRQn = 2, /**< 2 SAMR21G18A Watchdog Timer (WDT) */
  14. RTC_IRQn = 3, /**< 3 SAMR21G18A Real-Time Counter (RTC) */
  15. EIC_IRQn = 4, /**< 4 SAMR21G18A External Interrupt Controller (EIC) */
  16. NVMCTRL_IRQn = 5, /**< 5 SAMR21G18A Non-Volatile Memory Controller (NVMCTRL) */
  17. DMAC_IRQn = 6, /**< 6 SAMR21G18A Direct Memory Access Controller (DMAC) */
  18. USB_IRQn = 7, /**< 7 SAMR21G18A Universal Serial Bus (USB) */
  19. EVSYS_IRQn = 8, /**< 8 SAMR21G18A Event System Interface (EVSYS) */
  20. SERCOM0_IRQn = 9, /**< 9 SAMR21G18A Serial Communication Interface 0 (SERCOM0) */
  21. SERCOM1_IRQn = 10, /**< 10 SAMR21G18A Serial Communication Interface 1 (SERCOM1) */
  22. SERCOM2_IRQn = 11, /**< 11 SAMR21G18A Serial Communication Interface 2 (SERCOM2) */
  23. SERCOM3_IRQn = 12, /**< 12 SAMR21G18A Serial Communication Interface 3 (SERCOM3) */
  24. SERCOM4_IRQn = 13, /**< 13 SAMR21G18A Serial Communication Interface 4 (SERCOM4) */
  25. SERCOM5_IRQn = 14, /**< 14 SAMR21G18A Serial Communication Interface 5 (SERCOM5) */
  26. TCC0_IRQn = 15, /**< 15 SAMR21G18A Timer Counter Control 0 (TCC0) */
  27. TCC1_IRQn = 16, /**< 16 SAMR21G18A Timer Counter Control 1 (TCC1) */
  28. TCC2_IRQn = 17, /**< 17 SAMR21G18A Timer Counter Control 2 (TCC2) */
  29. TC3_IRQn = 18, /**< 18 SAMR21G18A Basic Timer Counter 3 (TC3) */
  30. TC4_IRQn = 19, /**< 19 SAMR21G18A Basic Timer Counter 4 (TC4) */
  31. TC5_IRQn = 20, /**< 20 SAMR21G18A Basic Timer Counter 5 (TC5) */
  32. TC6_IRQn = 21, /**< 21 SAMR21G18A Basic Timer Counter 6 (TC6) */
  33. TC7_IRQn = 22, /**< 22 SAMR21G18A Basic Timer Counter 7 (TC7) */
  34. ADC_IRQn = 23, /**< 23 SAMR21G18A Analog Digital Converter (ADC) */
  35. AC_IRQn = 24, /**< 24 SAMR21G18A Analog Comparators (AC) */
  36. DAC_IRQn = 25, /**< 25 SAMR21G18A Digital Analog Converter (DAC) */
  37. PTC_IRQn = 26, /**< 26 SAMR21G18A Peripheral Touch Controller (PTC) */
  38. I2S_IRQn = 27, /**< 27 SAMR21G18A Inter-IC Sound Interface (I2S) */
  39. PERIPH_COUNT_IRQn = 28 /**< Number of peripheral IDs */
  40. } IRQn_Type;
那么#ifdef USB_IRQn就不会有效果,所以USB_Handler就被屏蔽掉了。当把startup_samr21.c中的USB_IRQn部分去掉后,程序也就正常了。USB部分的其他几个例程也是一样,只要修正了USB_IRQn部分就都正常了。 这个地方估计是ASF中的一个bug,看看在下个版本中是否会修正。同时如果我们遇到ASF中的问题,不妨试试旧版本,玩玩会有不错的效果。新版本的问题一般都是因为对程序优化造成的,旧版本虽然效率上低一点,但是功能是没有问题的。 本帖最后由 dcexpert 于 2015-1-26 00:45 编辑

回复评论 (4)

给力,这么快就找到原因了,这文件比较软件真有用,回去我也安装个试试
点赞  2015-1-26 08:37
引用: 770781327 发表于 2015-1-26 08:37
给力,这么快就找到原因了,这文件比较软件真有用,回去我也安装个试试

使用Total Commander,然后设置一个快捷键进行文件比较,我设置了F12,很方便的。
1.jpg

2.jpg



点赞  2015-1-26 09:22
楼主高人,顺便看看签名档
So TM what......?
点赞  2015-1-26 10:54
引用: ljj3166 发表于 2015-1-26 10:54
楼主高人,顺便看看签名档


你这个签名很有意思啊。

点赞  2015-1-26 11:07
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复