转自:http://blog.csdn.net/kissmonx/article/details/21622187

一句话:标记__weak 或 [weak]的函数 就是用在本文件占位的,如果别的文件重写的这个函数就用别文件的,否则使用本文件的。

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

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

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

[plain] view plaincopy
  1. ; Reset handler 这里才是启动文件的重点啊. 不过没见到为 C 程序建立栈空间操作啊??? 直接调用 main 大丈夫? MAN???
  2. Reset_Handler    PROC
  3. EXPORT  Reset_Handler             [WEAK]
  4. IMPORT  SystemInit
  5. IMPORT  __main
  6. LDR     R0, =SystemInit
  7. BLX     R0
  8. LDR     R0, =__main
  9. BX      R0
  10. ENDP
  11. ; Dummy Exception Handlers (infinite loops which can be modified)
  12. NMI_Handler     PROC
  13. EXPORT  NMI_Handler                [WEAK]
  14. B       .
  15. ENDP
  16. HardFault_Handler\
  17. PROC
  18. EXPORT  HardFault_Handler          [WEAK]
  19. B       .
  20. ENDP
  21. MemManage_Handler\
  22. PROC
  23. EXPORT  MemManage_Handler          [WEAK]
  24. B       .
  25. ENDP
  26. BusFault_Handler\
  27. PROC
  28. EXPORT  BusFault_Handler           [WEAK]
  29. B       .
  30. ENDP
  31. UsageFault_Handler\
  32. PROC
  33. EXPORT  UsageFault_Handler         [WEAK]
  34. B       .
  35. ENDP
  36. SVC_Handler     PROC
  37. EXPORT  SVC_Handler                [WEAK]
  38. B       .
  39. ENDP
  40. DebugMon_Handler\
  41. PROC
  42. EXPORT  DebugMon_Handler           [WEAK]
  43. B       .
  44. ENDP
  45. PendSV_Handler  PROC
  46. EXPORT  PendSV_Handler             [WEAK]
  47. B       .
  48. ENDP
  49. SysTick_Handler PROC
  50. EXPORT  SysTick_Handler            [WEAK]
  51. B       .
  52. ENDP
  53. Default_Handler PROC
  54. EXPORT  WWDG_IRQHandler                   [WEAK]
  55. EXPORT  PVD_IRQHandler                    [WEAK]
  56. EXPORT  TAMPER_STAMP_IRQHandler           [WEAK]
  57. EXPORT  RTC_WKUP_IRQHandler               [WEAK]
  58. EXPORT  FLASH_IRQHandler                  [WEAK]
  59. EXPORT  RCC_IRQHandler                    [WEAK]
  60. EXPORT  EXTI0_IRQHandler                  [WEAK]
  61. EXPORT  EXTI1_IRQHandler                  [WEAK]
  62. EXPORT  EXTI2_TS_IRQHandler               [WEAK]
  63. EXPORT  EXTI3_IRQHandler                  [WEAK]
  64. EXPORT  EXTI4_IRQHandler                  [WEAK]
  65. EXPORT  DMA1_Channel1_IRQHandler          [WEAK]
  66. EXPORT  DMA1_Channel2_IRQHandler          [WEAK]
  67. EXPORT  DMA1_Channel3_IRQHandler          [WEAK]
  68. EXPORT  DMA1_Channel4_IRQHandler          [WEAK]
  69. EXPORT  DMA1_Channel5_IRQHandler          [WEAK]
  70. EXPORT  DMA1_Channel6_IRQHandler          [WEAK]
  71. EXPORT  DMA1_Channel7_IRQHandler          [WEAK]
  72. EXPORT  ADC1_2_IRQHandler                 [WEAK]
  73. EXPORT  USB_HP_CAN1_TX_IRQHandler         [WEAK]
  74. EXPORT  USB_LP_CAN1_RX0_IRQHandler        [WEAK]
  75. EXPORT  CAN1_RX1_IRQHandler               [WEAK]
  76. EXPORT  CAN1_SCE_IRQHandler               [WEAK]
  77. EXPORT  EXTI9_5_IRQHandler                [WEAK]
  78. EXPORT  TIM1_BRK_TIM15_IRQHandler         [WEAK]
  79. EXPORT  TIM1_UP_TIM16_IRQHandler          [WEAK]
  80. EXPORT  TIM1_TRG_COM_TIM17_IRQHandler     [WEAK]
  81. EXPORT  TIM1_CC_IRQHandler                [WEAK]
  82. EXPORT  TIM2_IRQHandler                   [WEAK]
  83. EXPORT  TIM3_IRQHandler                   [WEAK]
  84. EXPORT  TIM4_IRQHandler                   [WEAK]
  85. EXPORT  I2C1_EV_IRQHandler                [WEAK]
  86. EXPORT  I2C1_ER_IRQHandler                [WEAK]
  87. EXPORT  I2C2_EV_IRQHandler                [WEAK]
  88. EXPORT  I2C2_ER_IRQHandler                [WEAK]
  89. EXPORT  SPI1_IRQHandler                   [WEAK]
  90. EXPORT  SPI2_IRQHandler                   [WEAK]
  91. EXPORT  USART1_IRQHandler                 [WEAK]
  92. EXPORT  USART2_IRQHandler                 [WEAK]
  93. EXPORT  USART3_IRQHandler                 [WEAK]
  94. EXPORT  EXTI15_10_IRQHandler              [WEAK]
  95. EXPORT  RTC_Alarm_IRQHandler              [WEAK]
  96. EXPORT  USBWakeUp_IRQHandler              [WEAK]
  97. EXPORT  TIM8_BRK_IRQHandler               [WEAK]
  98. EXPORT  TIM8_UP_IRQHandler                [WEAK]
  99. EXPORT  TIM8_TRG_COM_IRQHandler           [WEAK]
  100. EXPORT  TIM8_CC_IRQHandler                [WEAK]
  101. EXPORT  ADC3_IRQHandler                   [WEAK]
  102. EXPORT  SPI3_IRQHandler                   [WEAK]
  103. EXPORT  UART4_IRQHandler                  [WEAK]
  104. EXPORT  UART5_IRQHandler                  [WEAK]
  105. EXPORT  TIM6_DAC_IRQHandler               [WEAK]
  106. EXPORT  TIM7_IRQHandler                   [WEAK]
  107. EXPORT  DMA2_Channel1_IRQHandler          [WEAK]
  108. EXPORT  DMA2_Channel2_IRQHandler          [WEAK]
  109. EXPORT  DMA2_Channel3_IRQHandler          [WEAK]
  110. EXPORT  DMA2_Channel4_IRQHandler          [WEAK]
  111. EXPORT  DMA2_Channel5_IRQHandler          [WEAK]
  112. EXPORT  ADC4_IRQHandler                   [WEAK]
  113. EXPORT  COMP1_2_3_IRQHandler              [WEAK]
  114. EXPORT  COMP4_5_6_IRQHandler              [WEAK]
  115. EXPORT  COMP7_IRQHandler                  [WEAK]
  116. EXPORT  USB_HP_IRQHandler                 [WEAK]
  117. EXPORT  USB_LP_IRQHandler                 [WEAK]
  118. EXPORT  USBWakeUp_RMP_IRQHandler          [WEAK]
  119. EXPORT  FPU_IRQHandler                    [WEAK]

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

[cpp] view plaincopy
  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
比我介绍的详细准确多了. 
英语不好的就算了吧. 大致意思就是:

[cpp] view plaincopy
  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.

[cpp] view plaincopy
  1. __asm void prvStartFirstTask( void )
  2. {
  3. PRESERVE8
  4. /* Use the NVIC offset register to locate the stack. */
  5. ldr r0, =0xE000ED08
  6. ldr r0, [r0]
  7. ldr r0, [r0]
  8. /* Set the msp back to the start of the stack. */
  9. msr msp, r0
  10. /* Globally enable interrupts. */
  11. cpsie i
  12. dsb
  13. isb
  14. /* Call SVC to start the first task. */
  15. svc 0  // 0 号系统调用, 更多关于 SVC 可以参考 google 或者 ARM Cortex-M3 权威指南
  16. nop
  17. }

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

[cpp] view plaincopy
  1. __asm void vPortSVCHandler( void )
  2. {
  3. PRESERVE8
  4. /* Get the location of the current TCB. */
  5. ldr r3, =pxCurrentTCB
  6. ldr r1, [r3]
  7. ldr r0, [r1]
  8. /* Pop the core registers. */
  9. ldmia r0!, {r4-r11, r14}
  10. msr psp, r0
  11. isb
  12. mov r0, #0
  13. msr basepri, r0
  14. bx r14
  15. }

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

[cpp] view plaincopy
  1. #define vPortSVCHandler      SVC_Handler
  2. #define xPortSysTickHandler  SysTick_Handler
  3. #define xPortPendSVHandler   PendSV_Handler

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

Keil-MDK 中 [WEAK] 的作用相关推荐

  1. keil MDK中如何生成*.bin格式的文件

    在Realview MDK的集成开发环境中,默认情况下可以生成*.axf格式的调试文件和*.hex格式的可执行文件.虽然这两个格式的文件非常有利于ULINK2仿真器的下载和调试,但是ADS的用户更习惯 ...

  2. keil(MDK)中出现error: #513:

    keil(MDK)中出现error: #513: a value of type "int" cannot be assigned to an entity of type &qu ...

  3. KEIL MDK中的RO、RW和ZI

    KEIL MDK中的RO.RW和ZI DATA理解及KEIL中ROM和RAM使用大小计算 (2013-12-25 09:33:06) 转载▼ 标签: it 分类: 嵌入式相关 本文来源与网络 http ...

  4. 在Keil MDK中创建STM32F4系列的工程模板(标准外设库)

    在Keil MDK中创建STM32F4系列的工程模板(标准外设库) 一.前往ST官网下载标准外设库 二.根据个人风格创建文件夹目录 三.创建MDK工程,创建分组 四.添加系统启动必要源文件 五.添加头 ...

  5. 【Keil MDK中工程报错Browse information of one of more files is not available解决方法】

    [Keil MDK中工程报错Browse information of one of more files is not available解决方法] 今天在进行工程编写时,出现了这个错误Browse ...

  6. Keil MDK 中利用串口及c标准库函数printf为cortex-m3做调试输出(lpc1788)

    摘要: c标准库的printf是输出给显示器的,将printf函数进行修改,使其输出重定向至串口,就能实现目的.printf函数调用fputc函数完成实质输出单一字符的工作,因此将fputc函数修改使 ...

  7. Keil MDK中编译连接选项--keep的用法

    使用Keil mdk编程,假如有一个有用的函数你定义了但是没有显式的调用,mdk在默认编译链接时,将会把这个函数从整个程序总删除掉,以节省ROM. 比如,你在ROM的0x00010000处定义了一个函 ...

  8. 解决KEIL MDK中JLINK烧录代码时提示the connected jlink is defective问题

    1.问题分析 网上有许多分析这个问题的博客,可以去参考 2.解决方法 a.在segger.com的官网下载了6.5版本的jlink驱动文件,安装后C:/program file(x86)/Segger ...

  9. 在Keil MDK中无法使用gmtime函数进行时间戳转换

    硬件平台STM32,软件平台Keil MDK 5.18 由于项目中需要用到UNIX时间戳和日历的来回转换,于是想到C库函数<time.h>里面有现成的函数可以使用. 于直接使用mktime ...

最新文章

  1. cplus cjson 封装
  2. 程序员面试题精选100题(21)-左旋转字符串[算法]
  3. Elasticsearch之配置详解
  4. Linux缺少qt5core,关于qt5:无法运行Qt应用:找不到版本“ Qt_5”
  5. Lazy延迟实例对象
  6. 作者:张飞波,华侨大学信息管理系本科在读。
  7. 知识图谱运用于推荐系统
  8. futuretask java 并发请求_Java并发案例04---Future和 FutureTask
  9. 蓝桥杯 ALGO-149 算法训练 5-2求指数
  10. 浅谈APP与H5对比!优势都有哪些呢?
  11. 图像处理一:形态学膨胀和腐蚀
  12. Java 就业培训教程 再读笔记
  13. 计算机的网线连接路由器的什么接口,tp-link路由器网线插哪个口 tplink路由器网线连接图解...
  14. 我对Javascript闭包的理解
  15. 项目4-一元一次方程类
  16. 曲面积分的投影法_在家学|第一类曲面积分与第二类曲面积分的计算
  17. 恢复和去除时间(Recovery and Removal Time)
  18. HTML5与CSS3基础教程学习笔记【第三章 基本HTML结构】
  19. linux usb 打印机命令
  20. verilog基础——always、initial

热门文章

  1. golang相关知识总结
  2. TOP10! KubeCon + CloudNativeCon最受欢迎演讲视频
  3. 计算机对模具的影响,不容忽视 浅谈笔记本模具重要性
  4. 八年级python考试题及答案_(新世纪版)2018-2019学年第二学期八年级信息技术期末试卷+答题卡+答案...
  5. 2019年第一本书《幸福的婚姻》思维导图+感想
  6. python123大小写转换_python人民币小写转大写辅助工具
  7. ubuntu 18.04 新配主机 无wifi适配器 找不到wifi问题解决
  8. 杭电OJ——1290 献给杭电五十周年校庆的礼物
  9. 孢子社群:今日推荐人工智能微信群:中国高端工业智造生态圈
  10. 第八章——手机多媒体