Keil-MDK 中 [WEAK] 的作用

发布者:CelestialMagic最新更新时间:2017-02-18 来源: eefocus关键字:Keil-MDK  WEAK 手机看文章 扫描二维码
随时随地手机看文章

移植后的代码戳这里: https://code.csdn.net/KISSMonX/freertos_f3discovery_test

在上一篇文章 ARM 汇编中的 "B ." 语句意义.时, 顺带介绍了 [WEAK] 的作用.
昨天再思考移植问题的时候(也就是执行第一个任务时直接跳到 SVC_Handler 里的 B . 处), 
想到了这个问题, 然后在移植配置文件中添加了几个宏定义就解决了问题, 移植成功, 具体下文介绍. 
这里再做一次解释. 看看自己是不是真正的理解了. :)

第一步明显是要贴代码装逼, 去启动文件里摘取出要介绍的部分. 然后记笔记的形式摘录下来.如下:


  1. ; Reset handler 这里才是启动文件的重点啊. 不过没见到为 C 程序建立栈空间操作啊??? 直接调用 main 大丈夫? MAN???  

  2. Reset_Handler    PROC  

  3.                  EXPORT  Reset_Handler             [WEAK]  

  4.         IMPORT  SystemInit  

  5.         IMPORT  __main  

  6.   

  7.                  LDR     R0, =SystemInit  

  8.                  BLX     R0  

  9.                  LDR     R0, =__main  

  10.                  BX      R0  

  11.                  ENDP  

  12.   

  13. ; Dummy Exception Handlers (infinite loops which can be modified)  

  14.   

  15. NMI_Handler     PROC  

  16.                 EXPORT  NMI_Handler                [WEAK]  

  17.                 B       .  

  18.                 ENDP  

  19. HardFault_Handler\  

  20.                 PROC  

  21.                 EXPORT  HardFault_Handler          [WEAK]  

  22.                 B       .  

  23.                 ENDP  

  24. MemManage_Handler\  

  25.                 PROC  

  26.                 EXPORT  MemManage_Handler          [WEAK]  

  27.                 B       .  

  28.                 ENDP  

  29. BusFault_Handler\  

  30.                 PROC  

  31.                 EXPORT  BusFault_Handler           [WEAK]  

  32.                 B       .  

  33.                 ENDP  

  34. UsageFault_Handler\  

  35.                 PROC  

  36.                 EXPORT  UsageFault_Handler         [WEAK]  

  37.                 B       .  

  38.                 ENDP  

  39. SVC_Handler     PROC  

  40.                 EXPORT  SVC_Handler                [WEAK]  

  41.                 B       .  

  42.                 ENDP  

  43. DebugMon_Handler\  

  44.                 PROC  

  45.                 EXPORT  DebugMon_Handler           [WEAK]  

  46.                 B       .  

  47.                 ENDP  

  48. PendSV_Handler  PROC  

  49.                 EXPORT  PendSV_Handler             [WEAK]  

  50.                 B       .  

  51.                 ENDP  

  52. SysTick_Handler PROC  

  53.                 EXPORT  SysTick_Handler            [WEAK]  

  54.                 B       .  

  55.                 ENDP  

  56.   

  57. Default_Handler PROC  

  58.   

  59.                 EXPORT  WWDG_IRQHandler                   [WEAK]                                          

  60.                 EXPORT  PVD_IRQHandler                    [WEAK]                        

  61.                 EXPORT  TAMPER_STAMP_IRQHandler           [WEAK]           

  62.                 EXPORT  RTC_WKUP_IRQHandler               [WEAK]                       

  63.                 EXPORT  FLASH_IRQHandler                  [WEAK]                                           

  64.                 EXPORT  RCC_IRQHandler                    [WEAK]                                              

  65.                 EXPORT  EXTI0_IRQHandler                  [WEAK]                                              

  66.                 EXPORT  EXTI1_IRQHandler                  [WEAK]                                               

  67.                 EXPORT  EXTI2_TS_IRQHandler               [WEAK]                                              

  68.                 EXPORT  EXTI3_IRQHandler                  [WEAK]                                             

  69.                 EXPORT  EXTI4_IRQHandler                  [WEAK]                                              

  70.                 EXPORT  DMA1_Channel1_IRQHandler          [WEAK]                                  

  71.                 EXPORT  DMA1_Channel2_IRQHandler          [WEAK]                                     

  72.                 EXPORT  DMA1_Channel3_IRQHandler          [WEAK]                                     

  73.                 EXPORT  DMA1_Channel4_IRQHandler          [WEAK]                                     

  74.                 EXPORT  DMA1_Channel5_IRQHandler          [WEAK]                                     

  75.                 EXPORT  DMA1_Channel6_IRQHandler          [WEAK]                                     

  76.                 EXPORT  DMA1_Channel7_IRQHandler          [WEAK]                                     

  77.                 EXPORT  ADC1_2_IRQHandler                 [WEAK]                           

  78.                 EXPORT  USB_HP_CAN1_TX_IRQHandler         [WEAK]                                                  

  79.                 EXPORT  USB_LP_CAN1_RX0_IRQHandler        [WEAK]                                                 

  80.                 EXPORT  CAN1_RX1_IRQHandler               [WEAK]                                                  

  81.                 EXPORT  CAN1_SCE_IRQHandler               [WEAK]                                                  

  82.                 EXPORT  EXTI9_5_IRQHandler                [WEAK]                                      

  83.                 EXPORT  TIM1_BRK_TIM15_IRQHandler         [WEAK]                    

  84.                 EXPORT  TIM1_UP_TIM16_IRQHandler          [WEAK]                  

  85.                 EXPORT  TIM1_TRG_COM_TIM17_IRQHandler     [WEAK]   

  86.                 EXPORT  TIM1_CC_IRQHandler                [WEAK]                                     

  87.                 EXPORT  TIM2_IRQHandler                   [WEAK]                                              

  88.                 EXPORT  TIM3_IRQHandler                   [WEAK]                                              

  89.                 EXPORT  TIM4_IRQHandler                   [WEAK]                                              

  90.                 EXPORT  I2C1_EV_IRQHandler                [WEAK]                                               

  91.                 EXPORT  I2C1_ER_IRQHandler                [WEAK]                                               

  92.                 EXPORT  I2C2_EV_IRQHandler                [WEAK]                                              

  93.                 EXPORT  I2C2_ER_IRQHandler                [WEAK]                                                 

  94.                 EXPORT  SPI1_IRQHandler                   [WEAK]                                             

  95.                 EXPORT  SPI2_IRQHandler                   [WEAK]                                              

  96.                 EXPORT  USART1_IRQHandler                 [WEAK]                                            

  97.                 EXPORT  USART2_IRQHandler                 [WEAK]                                            

  98.                 EXPORT  USART3_IRQHandler                 [WEAK]                                           

  99.                 EXPORT  EXTI15_10_IRQHandler              [WEAK]                                    

  100.                 EXPORT  RTC_Alarm_IRQHandler              [WEAK]                    

  101.                 EXPORT  USBWakeUp_IRQHandler              [WEAK]                          

  102.                 EXPORT  TIM8_BRK_IRQHandler               [WEAK]                   

  103.                 EXPORT  TIM8_UP_IRQHandler                [WEAK]                   

  104.                 EXPORT  TIM8_TRG_COM_IRQHandler           [WEAK]   

  105.                 EXPORT  TIM8_CC_IRQHandler                [WEAK]  

  106.                 EXPORT  ADC3_IRQHandler                   [WEAK]                                     

  107.                 EXPORT  SPI3_IRQHandler                   [WEAK]                                               

  108.                 EXPORT  UART4_IRQHandler                  [WEAK]                                              

  109.                 EXPORT  UART5_IRQHandler                  [WEAK]                                              

  110.                 EXPORT  TIM6_DAC_IRQHandler               [WEAK]                     

  111.                 EXPORT  TIM7_IRQHandler                   [WEAK]                      

  112.                 EXPORT  DMA2_Channel1_IRQHandler          [WEAK]                                    

  113.                 EXPORT  DMA2_Channel2_IRQHandler          [WEAK]                                     

  114.                 EXPORT  DMA2_Channel3_IRQHandler          [WEAK]                                      

  115.                 EXPORT  DMA2_Channel4_IRQHandler          [WEAK]                                      

  116.                 EXPORT  DMA2_Channel5_IRQHandler          [WEAK]  

  117.                 EXPORT  ADC4_IRQHandler                   [WEAK]                                   

  118.                 EXPORT  COMP1_2_3_IRQHandler              [WEAK]                                                 

  119.                 EXPORT  COMP4_5_6_IRQHandler              [WEAK]                                                 

  120.                 EXPORT  COMP7_IRQHandler                  [WEAK]                                                 

  121.                 EXPORT  USB_HP_IRQHandler                 [WEAK]                        

  122.                 EXPORT  USB_LP_IRQHandler                 [WEAK]                        

  123.                 EXPORT  USBWakeUp_RMP_IRQHandler          [WEAK]                          

  124.                 EXPORT  FPU_IRQHandler                    [WEAK]                  

然后到 keil 的帮助文档里找到这么一句话: 


  1. /* WEAK : symbol is only imported into other sources if no other source exports an alternative symbol.  

  2. If [WEAK] is used without symbol, all exported symbols are weak. */  

紧接着下面就有这种介绍:


这里是针对汇编语言的, C 语言级别的别捉急. 英语好的可以直接移步:About weak references and definitions
比我介绍的详细准确多了. 
英语不好的就算了吧. 大致意思就是:


  1. // 意思就是告诉链接器:   

  2. // "我略弱但我很绅士, 如果你在别处看到和我一样的符号实例.你就用它吧. 表管我, 求忽视! "   

所以......知道这个, 就可以解决为什么 FreeRTOS 在执行到下面这段代码老是跳转到 SVC_Handler 处了.

<乱入> SVC 作用:  SVCall  A supervisor call (SVC) is an exception that is triggered by the SVC instruction. In an OS environment, applications can use SVC instructions to 
access OS kernel functions and device drivers.


  1. __asm void prvStartFirstTask( void )  

  2. {  

  3.     PRESERVE8  

  4.   

  5.     /* Use the NVIC offset register to locate the stack. */  

  6.     ldr r0, =0xE000ED08  

  7.     ldr r0, [r0]  

  8.     ldr r0, [r0]  

  9.     /* Set the msp back to the start of the stack. */  

  10.     msr msp, r0  

  11.     /* Globally enable interrupts. */  

  12.     cpsie i  

  13.     dsb  

  14.     isb  

  15.     /* Call SVC to start the first task. */  

  16.     svc 0  // 0 号系统调用, 更多关于 SVC 可以参考 google 或者 ARM Cortex-M3 权威指南  

  17.     nop  

  18. }  

因为各个开发工具厂家对这些启动文件的异常和中断只做了简单的处理. 基本都是死循环(也就是"B .").
而且特意加上了 [WEAK] 修饰. 这样用户可以根据自己的需要重新编写自己的处理函数, 而且只要命名一样就 OK 了.
那名字要是不一样怎么办? 然后, 我去找了 SVC_Handler 这个名字, 并没有找到, 但是在 port.c 中找到了
下面这个函数:


  1. __asm void vPortSVCHandler( void )  

  2. {  

  3.     PRESERVE8  

  4.   

  5.     /* Get the location of the current TCB. */  

  6.     ldr r3, =pxCurrentTCB  

  7.     ldr r1, [r3]  

  8.     ldr r0, [r1]  

  9.     /* Pop the core registers. */  

  10.     ldmia r0!, {r4-r11, r14}  

  11.     msr psp, r0  

  12.     isb  

  13.     mov r0, #0  

  14.     msr basepri, r0  

  15.     bx r14  

  16. }  

这不就是披了马甲的 SVC_Handler 吗? 尼玛......显然里面的内容我不太明白, 就不解释了. 再学.
然后我当然没有那么聪明, 我找到了以前移植过的文件看了一下, 发现在 portmacro.h 中有下面三个宏定义:


  1. #define vPortSVCHandler      SVC_Handler  

  2. #define xPortSysTickHandler  SysTick_Handler  

  3. #define xPortPendSVHandler   PendSV_Handler  

扫噶. 原来宏名也比 WEAK 修饰过的强啊. 重新编译链接没错. 烧写, 各任务运行正常.


关键字:Keil-MDK  WEAK 引用地址:Keil-MDK 中 [WEAK] 的作用

上一篇:SPI模式下MCU对SD卡的控制及操作命令
下一篇: ARM CPU 寄存器组织

推荐阅读最新更新时间:2024-03-16 15:33

STM32 Keil-MDK工程模板 V3.5 固件库
原来一直在用3.3 的固件库,3.4 的出来好久了 也没顾得上更新如今的3.5 的库再也忍不住了,建好了个新的V3.5的工程模板 用的是最新的MDK4.20 . 3.5 到3.3 对于一般用户而言 基本没有什么 界面的上变革 目前看来好像仅仅改变了一些定义所处的文件位置,看起来跟合理些,SD 等的驱动更加稳定。我一直很是喜欢STM32的官方固件库 完好的遵循ANSI 风格,代码编写严谨,还有一点C语言面向对象的感觉。更重要的是开源,我想这才是能流行起来的原因。 工程移植了 KEIL 的图形化配置向导 stm32_Init.c 工程路径 Cortex_M3_Project_V3.5\STM32\STM32F10X_HD\RVMDK
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多每日新闻
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved