Keil-MDK 中 [WEAK] 的作用
转自:http://blog.csdn.net/kissmonx/article/details/21622187
一句话:标记__weak 或 [weak]的函数 就是用在本文件占位的,如果别的文件重写的这个函数就用别文件的,否则使用本文件的。
移植后的代码戳这里: https://code.csdn.net/KISSMonX/freertos_f3discovery_test
在上一篇文章 ARM 汇编中的 "B ." 语句意义.时, 顺带介绍了 [WEAK] 的作用.
昨天再思考移植问题的时候(也就是执行第一个任务时直接跳到 SVC_Handler 里的 B . 处),
想到了这个问题, 然后在移植配置文件中添加了几个宏定义就解决了问题, 移植成功, 具体下文介绍.
这里再做一次解释. 看看自己是不是真正的理解了. :)
第一步明显是要贴代码装逼, 去启动文件里摘取出要介绍的部分. 然后记笔记的形式摘录下来.如下:
- ; Reset handler 这里才是启动文件的重点啊. 不过没见到为 C 程序建立栈空间操作啊??? 直接调用 main 大丈夫? MAN???
- Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT SystemInit
- IMPORT __main
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
- ; Dummy Exception Handlers (infinite loops which can be modified)
- NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
- HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
- MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
- BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
- UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
- SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
- DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
- PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
- SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
- Default_Handler PROC
- EXPORT WWDG_IRQHandler [WEAK]
- EXPORT PVD_IRQHandler [WEAK]
- EXPORT TAMPER_STAMP_IRQHandler [WEAK]
- EXPORT RTC_WKUP_IRQHandler [WEAK]
- EXPORT FLASH_IRQHandler [WEAK]
- EXPORT RCC_IRQHandler [WEAK]
- EXPORT EXTI0_IRQHandler [WEAK]
- EXPORT EXTI1_IRQHandler [WEAK]
- EXPORT EXTI2_TS_IRQHandler [WEAK]
- EXPORT EXTI3_IRQHandler [WEAK]
- EXPORT EXTI4_IRQHandler [WEAK]
- EXPORT DMA1_Channel1_IRQHandler [WEAK]
- EXPORT DMA1_Channel2_IRQHandler [WEAK]
- EXPORT DMA1_Channel3_IRQHandler [WEAK]
- EXPORT DMA1_Channel4_IRQHandler [WEAK]
- EXPORT DMA1_Channel5_IRQHandler [WEAK]
- EXPORT DMA1_Channel6_IRQHandler [WEAK]
- EXPORT DMA1_Channel7_IRQHandler [WEAK]
- EXPORT ADC1_2_IRQHandler [WEAK]
- EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
- EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
- EXPORT CAN1_RX1_IRQHandler [WEAK]
- EXPORT CAN1_SCE_IRQHandler [WEAK]
- EXPORT EXTI9_5_IRQHandler [WEAK]
- EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK]
- EXPORT TIM1_UP_TIM16_IRQHandler [WEAK]
- EXPORT TIM1_TRG_COM_TIM17_IRQHandler [WEAK]
- EXPORT TIM1_CC_IRQHandler [WEAK]
- EXPORT TIM2_IRQHandler [WEAK]
- EXPORT TIM3_IRQHandler [WEAK]
- EXPORT TIM4_IRQHandler [WEAK]
- EXPORT I2C1_EV_IRQHandler [WEAK]
- EXPORT I2C1_ER_IRQHandler [WEAK]
- EXPORT I2C2_EV_IRQHandler [WEAK]
- EXPORT I2C2_ER_IRQHandler [WEAK]
- EXPORT SPI1_IRQHandler [WEAK]
- EXPORT SPI2_IRQHandler [WEAK]
- EXPORT USART1_IRQHandler [WEAK]
- EXPORT USART2_IRQHandler [WEAK]
- EXPORT USART3_IRQHandler [WEAK]
- EXPORT EXTI15_10_IRQHandler [WEAK]
- EXPORT RTC_Alarm_IRQHandler [WEAK]
- EXPORT USBWakeUp_IRQHandler [WEAK]
- EXPORT TIM8_BRK_IRQHandler [WEAK]
- EXPORT TIM8_UP_IRQHandler [WEAK]
- EXPORT TIM8_TRG_COM_IRQHandler [WEAK]
- EXPORT TIM8_CC_IRQHandler [WEAK]
- EXPORT ADC3_IRQHandler [WEAK]
- EXPORT SPI3_IRQHandler [WEAK]
- EXPORT UART4_IRQHandler [WEAK]
- EXPORT UART5_IRQHandler [WEAK]
- EXPORT TIM6_DAC_IRQHandler [WEAK]
- EXPORT TIM7_IRQHandler [WEAK]
- EXPORT DMA2_Channel1_IRQHandler [WEAK]
- EXPORT DMA2_Channel2_IRQHandler [WEAK]
- EXPORT DMA2_Channel3_IRQHandler [WEAK]
- EXPORT DMA2_Channel4_IRQHandler [WEAK]
- EXPORT DMA2_Channel5_IRQHandler [WEAK]
- EXPORT ADC4_IRQHandler [WEAK]
- EXPORT COMP1_2_3_IRQHandler [WEAK]
- EXPORT COMP4_5_6_IRQHandler [WEAK]
- EXPORT COMP7_IRQHandler [WEAK]
- EXPORT USB_HP_IRQHandler [WEAK]
- EXPORT USB_LP_IRQHandler [WEAK]
- EXPORT USBWakeUp_RMP_IRQHandler [WEAK]
- EXPORT FPU_IRQHandler [WEAK]
然后到 keil 的帮助文档里找到这么一句话:
- /* WEAK : symbol is only imported into other sources if no other source exports an alternative symbol.
- If [WEAK] is used without symbol, all exported symbols are weak. */
紧接着下面就有这种介绍:
这里是针对汇编语言的, C 语言级别的别捉急. 英语好的可以直接移步:About weak references and definitions
比我介绍的详细准确多了.
英语不好的就算了吧. 大致意思就是:
- // 意思就是告诉链接器:
- // "我略弱但我很绅士, 如果你在别处看到和我一样的符号实例.你就用它吧. 表管我, 求忽视! "
所以......知道这个, 就可以解决为什么 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.
- __asm void prvStartFirstTask( void )
- {
- PRESERVE8
- /* Use the NVIC offset register to locate the stack. */
- ldr r0, =0xE000ED08
- ldr r0, [r0]
- ldr r0, [r0]
- /* Set the msp back to the start of the stack. */
- msr msp, r0
- /* Globally enable interrupts. */
- cpsie i
- dsb
- isb
- /* Call SVC to start the first task. */
- svc 0 // 0 号系统调用, 更多关于 SVC 可以参考 google 或者 ARM Cortex-M3 权威指南
- nop
- }
因为各个开发工具厂家对这些启动文件的异常和中断只做了简单的处理. 基本都是死循环(也就是"B .").
而且特意加上了 [WEAK] 修饰. 这样用户可以根据自己的需要重新编写自己的处理函数, 而且只要命名一样就 OK 了.
那名字要是不一样怎么办? 然后, 我去找了 SVC_Handler 这个名字, 并没有找到, 但是在 port.c 中找到了
下面这个函数:
- __asm void vPortSVCHandler( void )
- {
- PRESERVE8
- /* Get the location of the current TCB. */
- ldr r3, =pxCurrentTCB
- ldr r1, [r3]
- ldr r0, [r1]
- /* Pop the core registers. */
- ldmia r0!, {r4-r11, r14}
- msr psp, r0
- isb
- mov r0, #0
- msr basepri, r0
- bx r14
- }
这不就是披了马甲的 SVC_Handler 吗? 尼玛......显然里面的内容我不太明白, 就不解释了. 再学.
然后我当然没有那么聪明, 我找到了以前移植过的文件看了一下, 发现在 portmacro.h 中有下面三个宏定义:
- #define vPortSVCHandler SVC_Handler
- #define xPortSysTickHandler SysTick_Handler
- #define xPortPendSVHandler PendSV_Handler
扫噶. 原来宏名也比 WEAK 修饰过的强啊. 重新编译链接没错. 烧写, 各任务运行正常.
Keil-MDK 中 [WEAK] 的作用相关推荐
- keil MDK中如何生成*.bin格式的文件
在Realview MDK的集成开发环境中,默认情况下可以生成*.axf格式的调试文件和*.hex格式的可执行文件.虽然这两个格式的文件非常有利于ULINK2仿真器的下载和调试,但是ADS的用户更习惯 ...
- keil(MDK)中出现error: #513:
keil(MDK)中出现error: #513: a value of type "int" cannot be assigned to an entity of type &qu ...
- KEIL MDK中的RO、RW和ZI
KEIL MDK中的RO.RW和ZI DATA理解及KEIL中ROM和RAM使用大小计算 (2013-12-25 09:33:06) 转载▼ 标签: it 分类: 嵌入式相关 本文来源与网络 http ...
- 在Keil MDK中创建STM32F4系列的工程模板(标准外设库)
在Keil MDK中创建STM32F4系列的工程模板(标准外设库) 一.前往ST官网下载标准外设库 二.根据个人风格创建文件夹目录 三.创建MDK工程,创建分组 四.添加系统启动必要源文件 五.添加头 ...
- 【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 ...
- Keil MDK 中利用串口及c标准库函数printf为cortex-m3做调试输出(lpc1788)
摘要: c标准库的printf是输出给显示器的,将printf函数进行修改,使其输出重定向至串口,就能实现目的.printf函数调用fputc函数完成实质输出单一字符的工作,因此将fputc函数修改使 ...
- Keil MDK中编译连接选项--keep的用法
使用Keil mdk编程,假如有一个有用的函数你定义了但是没有显式的调用,mdk在默认编译链接时,将会把这个函数从整个程序总删除掉,以节省ROM. 比如,你在ROM的0x00010000处定义了一个函 ...
- 解决KEIL MDK中JLINK烧录代码时提示the connected jlink is defective问题
1.问题分析 网上有许多分析这个问题的博客,可以去参考 2.解决方法 a.在segger.com的官网下载了6.5版本的jlink驱动文件,安装后C:/program file(x86)/Segger ...
- 在Keil MDK中无法使用gmtime函数进行时间戳转换
硬件平台STM32,软件平台Keil MDK 5.18 由于项目中需要用到UNIX时间戳和日历的来回转换,于是想到C库函数<time.h>里面有现成的函数可以使用. 于直接使用mktime ...
最新文章
- cplus cjson 封装
- 程序员面试题精选100题(21)-左旋转字符串[算法]
- Elasticsearch之配置详解
- Linux缺少qt5core,关于qt5:无法运行Qt应用:找不到版本“ Qt_5”
- Lazy延迟实例对象
- 作者:张飞波,华侨大学信息管理系本科在读。
- 知识图谱运用于推荐系统
- futuretask java 并发请求_Java并发案例04---Future和 FutureTask
- 蓝桥杯 ALGO-149 算法训练 5-2求指数
- 浅谈APP与H5对比!优势都有哪些呢?
- 图像处理一:形态学膨胀和腐蚀
- Java 就业培训教程 再读笔记
- 计算机的网线连接路由器的什么接口,tp-link路由器网线插哪个口 tplink路由器网线连接图解...
- 我对Javascript闭包的理解
- 项目4-一元一次方程类
- 曲面积分的投影法_在家学|第一类曲面积分与第二类曲面积分的计算
- 恢复和去除时间(Recovery and Removal Time)
- HTML5与CSS3基础教程学习笔记【第三章 基本HTML结构】
- linux usb 打印机命令
- verilog基础——always、initial
热门文章
- golang相关知识总结
- TOP10! KubeCon + CloudNativeCon最受欢迎演讲视频
- 计算机对模具的影响,不容忽视 浅谈笔记本模具重要性
- 八年级python考试题及答案_(新世纪版)2018-2019学年第二学期八年级信息技术期末试卷+答题卡+答案...
- 2019年第一本书《幸福的婚姻》思维导图+感想
- python123大小写转换_python人民币小写转大写辅助工具
- ubuntu 18.04 新配主机 无wifi适配器 找不到wifi问题解决
- 杭电OJ——1290 献给杭电五十周年校庆的礼物
- 孢子社群:今日推荐人工智能微信群:中国高端工业智造生态圈
- 第八章——手机多媒体