對於很多使用ZLG ARM Image for uCOSII for lpc213x 模板的初學者,常常會置疑使用該模板後自動產生的target.c檔案,和在程式中調用的TargetInit()函數,我和 Zgpswh都是如此,這個問題當初困擾了很久:當使用者程式中不調用TargetInit()時,發現核心能運行,但是等待機制失靈,調用TargetInit(),很多硬體中斷打不開,後來,在很多熱心人的指點下解決了,現重新總結如下:
請仔細察看ZLG模板裡的target.c檔案,這裡的TargetInit()如下:
void TargetInit(void)
{
OS_ENTER_CRITICAL();
srand((uint32) TargetInit);
VICInit();
Timer0Init();
OS_EXIT_CRITICAL();
}
其中的Timer0Init();用於硬體定時器0的初始化,事實上,ZLG的移植代碼的μC/OS-Ⅱ的時鐘節拍是通過定時器0提供的,不在主程式裡調用這個函數,μC/OS-Ⅱ的時鐘源就無法開啟;但是,沒有開啟時鐘源的μC/OS-Ⅱ是同樣能啟動並執行,只是核心提供的延時和等待時限機制都不起作用,系統雖能將就運行,但因沒調用TargetInit()而使核心功能不健全。
請注意,TargetInit()中的另一個函數VICInit()是用來中斷的初始化,它其中含有對UART0中斷的分配,在使用者程式裡需要根據使用的硬體中斷修改這部分代碼,否則,這些硬體中斷無法開啟;再者,在不調用TargetInit()的時候,硬體的中斷初始化是在硬體初始化函數中完成,這也就是Zgpswh提到的現象:不調用TargetInit()核心運行異常,調用了卻開不了UART0的中斷。
解決的方法如下:
這在《ARM嵌入式系統基礎教程》的430頁7.4.3節中論述的很清楚:
……關鍵在於把程式與晶片相關中斷源掛接,使晶片在產生相應的中斷後會調用相應的處理常式。這需要做兩方面事情:
1. 增加彙編介面的支援。……
2. 初始化向量中斷控制器。……
按照一下方法完成中斷源的的掛接:
1、增加彙編介面的支援。方法是修改IRQ.s檔案,在末尾添加本句代碼:
UART0_Handler HANDLER UART0_Exception
追加定義了通用串口0 中斷控制代碼。
2、初始化向量中斷控制器。將target.c檔案中的VICInit()修改如下:
void VICInit(void)
{ extern void IRQ_Handler(void);
extern void Timer0_Handler(void);
extern void UART0_Handler(void);
VICIntEnClr = 0xffffffff;
VICDefVectAddr = (uint32)IRQ_Handler;
VICVectAddr0 = (uint32)Timer0_Handler;
VICVectCntl0 = (0x20 | 0x04);
VICIntEnable = 1 << 4;
VICVectAddr14 = (uint32)UART0_Handler;
VICVectCntl14 = (0x20 | 0x06);
VICIntEnable = 1 << 6;
}
此為初始化向量中斷控制器。包括定時器0和串口0,特別要注意的是,一定不可以省略對定時器0的初始化