uC/OS-II内核移植_时钟节拍函数使用的初步认识
断断续续看了uC/OS-II内核书和一两个实验,发现移植的第一部,就遇到时钟节拍处理不好的困难。这两天,又对其中的一个比较完善的例程作仔细的分析,初步有了一些认识。
个人认为,移植的第一个问题,是解决时钟节拍的处理,过程如下:
一、首先在主函数中调用目标板初始化函数ARMTargetInit();主要是初始化要用到的定时器和外部中断;
二、在启动系统之前,调用函数ARMTargetStart(),打开Timer0中断;
三、启动系统OSStart();
下面,详细说明上述过程的步骤:
建立文件target.c和target.h
target.c:
void ARMTargetInit(void)
{
InitInterrupts();
InitTimers();
}
void InitInterrupts(void) //初始化中断模式
{
rINTCON=0x5; // Non-vectored,IRQ enable,FIQ disable
rINTMOD=0x0; // All=IRQ mode
rINTMSK=0X7FFFFFF; // all interrupts disable.
}
void InitTimers(void) //初始化Time0,作为系统始终节拍
{
rTCFG0=(MCLK>>1)/1000000-1; //预分频值
rTCFG1=0x00000000; // mux0 = 1/2
//定时器0输入时钟频率=MCLK/(预分频值+1)/除法值mux0,定时器0输入时钟频率为1MHz
rTCNTB0= 1000000/OS_TICKS_PER_SEC; //定时器0输出时钟频率为OS_TICKS_PER_SEC
rTCMPB0= 0x0;
rTCON=0x2; //update mode for TCNTB0 and TCMPB0.
rTCON=0x9; //timer0 = auto reload, start
}
void ARMTargetStart(void) //启动定时中断和外中断EXINT0
{
RequestSystemTimer();
InstallSystemTimer();
}
void RequestSystemTimer(void)
{
pISR_TIMER0= (unsigned)Timer0_Exception; //设置Timer0中断函数地址
pISR_EINT0 = (unsigned)Exint0_Exception;
//这里可以设置任何中断!注意要添加对应的中断服务函数
}
void InstallSystemTimer(void)
{
rINTCON=0x5; //Non-vectored,IRQ enable,FIQ disable
rINTMSK=~( BIT_GLOBAL | BIT_TIMER0 ); //Default value=0x7ffffff
}
void Timer0_Exception(void)
{
rI_ISPC=BIT_TIMER0; //清除定时器0中断挂起位
OSTimeTick(); //注意:在进入中断后运行次语句前,必须禁止中断
}
void Exint0_Exception(void)
{
rI_ISPC=BIT_EINT0;
//此后可以打开中断
}
注意:OSTimeTick()是uC/OS-II系统函数!
target.h根据上面的.c文件,就很容易写出来。
这里可能需要重点说明中断执行过程,也是个人的一点粗浅认识。以 Timer0中断为例:
如果发生定时器Timer0中断,PC将跳转到pISR_TIMER0所在地址,根据44binit.s文件,分析可以知道(参考我的《ARM的中断处理过程》一文)函数Timer0_Exception()将得以执行!
关于节拍的产生过程以及相应的任务切换,将在下一个文件中谈到。
注意:我的文章多半是学习时产生的认识,需要今后的应用中验证。