ucosii在stm32上的移植详解5
任务代码(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
该移植代码在我自己开发的一个小玩意上已得到一段时间的验证,未发现问题。但由于水平所限,并不敢保证该移植是没有任何问题的,殷切希望大家批评指正。
ucosiistm32移植详 相关文章:
- ucosii在stm32上的移植详解1(11-09)
- ucosii在stm32上的移植详解3(11-09)
- ucosii在stm32上的移植详解2(11-09)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)