Keil-MDK 中 [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 修飾過的強啊. 重新編譯鏈接沒錯. 燒寫, 各任務運行正常.

發佈了163 篇原創文章 · 獲贊 47 · 訪問量 89萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章