详解1-4把移植进程都现已介绍了。接下来的作业是验证移植是否ok以及怎么根据移植好的ucosii开发运用程序。前一个问题能够说是后一个问题的特殊情况,一般咱们会创立两个简略的使命,看看使命切换是否成功来验证移植是否ok,由于使命切换能够说是ucosii最中心的功用。
使命代码(main.c):
static void task1(void *p_arg)
{
for (;;)
{
led_on(LED_0);
OSTimeDly(500);
led_off(LED_0);
OSTimeDly(500);
}
}
static void task2(void *p_arg)
{
for (;;)
{
led_on(LED_1);
OSTimeDly(500);
led_off(LED_1);
OSTimeDly(500);
}
}
在startup_task()创立使命:
err = OSTaskCreate(task1, (void *)0,
&task1_stk[TASK1_STK_SIZE-1], TASK1_PRIO);
err = OSTaskCreate(task2, (void *)0,
&task2_stk[TASK2_STK_SIZE-1], TASK2_PRIO);
把使命的仓库巨细和优先级写入app_cfg.h,界说使命仓库,编译调试。
在使命中打断点,用模仿器调试能够发现现已能够做使命切换了。假如有板子,烧到板子中运转,能够看到两个灯展以1Hz的频率闪耀。
能够以为移植开始成功,内核其他功用有待在运用中持续验证。
怎么根据移植好的ucosii开发运用程序呢?
开发运用程序大部分都是为了处理或操控一个实在的物理体系,而实在的物理体系往往都是模仿体系,为了便利计算机处理,首要需要对体系做离散化处理。针对ucosii,离散化进程是经过体系“心跳”(SysTick)来完成的。一般运用程序都有多个使命(不多使命谁用ucosii啊),使命能够分为周期使命和非周期使命。周期使命是周期性循环地处理工作的使命,而非周期使命一般是某个条件触发才履行的使命。这里有一个问题,SysTick的时刻是多少适宜。SysTick的时刻一般取周期性使命中周期最短的时刻值。譬如说,体系里有3个周期性使命:体系主使命(如处理pid等,使命周期4ms),键盘扫描使命(使命周期16ms),通讯使命(使命周期128ms),SysTick时刻就取4ms。当然在SysTick时刻较小时,要注意体系负荷问题,这时最好测一下cpu运用率及各个使命的时刻等。
周期性使命的开发套路是怎么样的呢?看看定时器使命的做法就知道了,代码在os_tmr.c。首要在OSTmr_Init()中初始化OSTmrSemSignal,然后OSTmr_Task()使命会一向等候OSTmrSemSignal,比及OSTmrSemSignal后去处理各个定时器。那么谁在开释OSTmrSemSignal呢?OSTmrSignal(),这个函数要求放在必定频率的时钟中止里,默许是在SysTick中止中(假如使能OS_TIME_TICK_HOOK_EN)。好了,现在咱们能够总结总结周期性使命的一般套路了。
首要在使命初始化函数中初始化一个信号量(一般会用信号量),伪代码如下:
void task_init(void)
{
task_sem = OSSemCreate(0);
}
在使命中等候信号量
void task (void *p_arg)
{
for (;;)
{
OSSemPend(task_sem, 0, &err);
/* TODO: task handle here */
}
}
周期性的开释信号量
OSSemPost(task_sem);
关于上面所说体系主使命,OSSemPost(task_sem)能够放在SysTick_Handler()中。所以一般来说OS_CPU_SysTickHandler()改动的可能性是非常大的。
非周期使命的开发套路又是怎样的呢?其实和周期性使命是差不多的,仅仅信号量不是周期性地开释,而是按需开释。
其他内核功用就不多介绍了,我们按需运用,不是很难。
本文代码:http://download.csdn.net/source/3472653
该移植代码在我自己开发的一个小玩意上已得到一段时刻的验证,未发现问题。但由于水平所限,并不敢确保该移植是没有任何问题的,殷切希望我们批评指正。