对于很多使用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的初始化
请仔细察看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的初始化
中断里,不可以调用延时 |