色偷偷偷久久伊人大杳蕉,色爽交视频免费观看,欧美扒开腿做爽爽爽a片,欧美孕交alscan巨交xxx,日日碰狠狠躁久久躁蜜桃

x
x
查看: 4984|回復(fù): 5
打印 上一主題 下一主題

用C++開(kāi)發(fā)STM32,解決了中斷向量問(wèn)題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2013-7-8 23:48:50 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
最近喜歡上了C++開(kāi)發(fā)STM32,C++語(yǔ)法上基本是C的擴(kuò)展,所以習(xí)慣用C的人所有的知識(shí)和代碼可以繼續(xù)發(fā)揮作用。
另外,C++的OO編程,代碼架構(gòu)更接近人的思考模式,即使我們不需要OO編程,代碼的可維護(hù)性也好了很多。

但若要完全C++開(kāi)發(fā),遇到的問(wèn)題是中斷向量的問(wèn)題,用C來(lái)包裝一個(gè)C++ 函數(shù)的方式可以解決,但似乎有些不爽。
中斷向量,就是函數(shù)入口地址,這個(gè)C++的靜態(tài)函數(shù)可以對(duì)應(yīng)起來(lái)。

我們可以從map文件中,把中斷向量的一個(gè)個(gè)的C++函數(shù)的入口地址符號(hào)找到,寫入startup文件中。
但C++的symbol不像C語(yǔ)言那么簡(jiǎn)潔了,而且可能隨著源代碼的編輯而改變,包括函數(shù)的順序,函數(shù)的返回值,函數(shù)的參數(shù)等。
_ZN10CInterrupt15TIM3_IRQHandlerEv 看看這個(gè)符號(hào),是不是很別扭,C語(yǔ)言的Symbol就一個(gè)TIM3_IRQHandler,跟函數(shù)名完全相同。

這時(shí)候,我們應(yīng)該盡量不要在匯編程序中寫向量表,而是到C++文件中寫向量表了。

沙發(fā)
 樓主| 發(fā)表于 2013-7-8 23:49:23 | 只看該作者
這是修改的的startup.s文件
-----------------------------華麗麗的分界線---------------------------------------------------

Stack_Size      EQU     0x00000800

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
__initial_sp_ex

Heap_Size       EQU     0x00000400

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit


                EXPORT  __initial_sp_ex
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size
__Vectors            EQU        0x08006000
__Vectors_End        EQU        0x08006040
__Vectors_Size        EQU        0x40


                PRESERVE8
                THUMB

                AREA    |.text|, CODE, READONLY

; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
     IMPORT  __main
     IMPORT  SystemInit
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP


;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
                 IF      EF:__MICROLIB           
               
                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
               
                 ELSE
               
                 IMPORT  __use_two_region_memory
                 EXPORT  __user_initial_stackheap
                 
__user_initial_stackheap

                 LDR     R0, =  Heap_Mem
                 LDR     R1, =(Stack_Mem + Stack_Size)
                 LDR     R2, = (Heap_Mem +  Heap_Size)
                 LDR     R3, = Stack_Mem
                 BX      LR

                 ALIGN

                 ENDIF

                 END
板凳
 樓主| 發(fā)表于 2013-7-8 23:49:59 | 只看該作者
這個(gè)是Interrupt.hpp文件,可根據(jù)需要增添,可以把所有的ISR函數(shù)都掛上去,也可以只寫自己需要的

class CInterrupt
{
public:
        static void USB_LP_CAN1_RX0_IRQHandler();
        static void TIM3_IRQHandler();
};
地板
 樓主| 發(fā)表于 2013-7-8 23:50:31 | 只看該作者
這個(gè)是Interrupt.cpp文件,包括2個(gè)成員函數(shù)的實(shí)現(xiàn)
------------------------------------------------------------------------------
void CInterrupt::USB_LP_CAN1_RX0_IRQHandler()
{
        if(!g_bInterruptPause)        AndyUSB.USB_Istr();
}
void CInterrupt::TIM3_IRQHandler()
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
        {
                TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
               
                g_nNowTime++;
               
//                if(0==(g_nNowTime%2))
                {
                        AndyHW.HwCallBackKeyScan();
                }
                AndyHW.HwCallBackOverCurrent();
                AndyOS.sysCallBackTimer10ms();   //10mS
        }
}
地下室
 樓主| 發(fā)表于 2013-7-8 23:51:21 | 只看該作者
下面的這個(gè)部分,可以寫在Interrupt.cpp文件中,也可單獨(dú)寫一個(gè)CPP文件。
-----------------------------------------------------------------------------------------------------------------------------


#ifdef __cplusplus
extern "C" {
#endif

void __initial_sp_ex(void);
void Reset_Handler(void);

#ifdef __cplusplus
}
#endif

void Default_Handler(void);

typedef void(* const ISR_t)(void);

ISR_t IsrVector[] __attribute__ ((section("RESET"))) =
{
                __initial_sp_ex,
                Reset_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                0,
                0,
                0,
                0,
                Default_Handler,
                Default_Handler,
                0,
                Default_Handler,
                Default_Handler,


                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                CInterrupt::USB_LP_CAN1_RX0_IRQHandler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                CInterrupt::TIM3_IRQHandler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler,
                Default_Handler
};

void Default_Handler(void)
{
    while (1);
}
6
 樓主| 發(fā)表于 2013-7-8 23:51:59 | 只看該作者
不過(guò)有些遺憾的是,STM32的FwLib沒(méi)有C++版本的,不過(guò)C++和C混合使用,沒(méi)問(wèn)題的
ST提供的h文件中全加入了兼容C和C++的宏處理
#ifdef __cplusplus
extern "C" {
#endif

當(dāng)轉(zhuǎn)到C++后,就可以使用虛函數(shù)來(lái)代替一部分函數(shù)指針,可讀性更好。
MDK中RVDS編譯器,對(duì)C++的優(yōu)化很好,沒(méi)用到的成員函數(shù)會(huì)被優(yōu)化掉,所以如果做平臺(tái)一定記得對(duì)相關(guān)的成員函數(shù)禁止優(yōu)化,使用--keep選項(xiàng)

OK,享受C++之旅吧

本版積分規(guī)則

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表