UCOS试验一
1.1 在STM32F4上运行UCOS的步骤
-
移植UCOSII
-
编写任务函数并设置其堆栈大小和优先级等参数
堆栈大小的设置需要根据函数需求来设置
优先级需要根据任务的重要性和实时性设置
-
初始化UCOSII,并在UCOSII中创建任务
-
启动UCOSII
1.2 硬件设计
本节试验在ucosII中创建3个任务:
开始任务,用于创建其它(LED0和LED1)任务后挂起
LED0任务,控制DS0 闪亮,每秒亮80ms
LED1任务,控制DS1
1.3 软件设计
1.添加UCOSII文件
UCOSII-CORE 分组下面是 UCOSII的核心源码,不需要做任何变动。
UCOSII-PORT 分组下面是我们移植UCOSII要修改的 3 个代码,这个在移植的时候完成
UCOSII-CONFIG 分组下面是 UCOSII的配置部分,主要由用户根据自己的需要对UCOSII进行裁剪或其他设置。
-
设置os_cfg.h OS_TICKS_PER_SEC 的值为 200; OS_MAX_TASKS 为 10;
-
在 sys.h 里面设置SYSTEM_SUPPORT_UCOS 为 1,以支持 UCOSII
在设置 SYSTEM_SUPPORT_UCOS 为 1 之后,UCOSII 的时钟节拍由 SYSTICK的中断服务函数提供,该部分代码如下:
//systick中断服务函数,使用ucos时用到
void SysTick_Handler(void)
{
OSIntEnter(); //进入中断
OSTimeTick(); //调用ucos的时钟服务程序
OSIntExit(); //触发任务切换软中断
}
OSIntEnter: 是进入中断服务函数,用来记录中断嵌套层数(OSIntNesting
增加 1);
OSTimeTick:是系统时钟节拍服务函数,在每个时钟节拍了解每个任务的延时状态,
使已经到达延时时限的非挂起任务进入就绪状态;
OSIntExit:是退出中断服务函数,该函数可能触发一次任务切换(当OSIntNesting==0&&调度器未上锁&&就绪表最高优先级任务!=被中断的任务优先级时),否则继续返回原来的任务执行代码(如果OSIntNesting 不为 0,则减1)。
-
Main函数代码
/ALIENTEK 探索者STM32F407开发板 实验56
//UCOSII实验1-任务调度 -库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者:正点原子 @ALIENTEK
/UCOSII任务设置///
//START 任务
//设置任务优先级
#define START_TASK_PRIO 10//开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE 64
//任务堆栈
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);
//LED0任务
//设置任务优先级
#define LED0_TASK_PRIO 7
//设置任务堆栈大小
#define LED0_STK_SIZE 64
//任务堆栈
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
//任务函数
void led0_task(void *pdata);
//LED1任务
//设置任务优先级
#define LED1_TASK_PRIO 6
//设置任务堆栈大小
#define LED1_STK_SIZE 64
//任务堆栈
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
//任务函数
void led1_task(void *pdata);
int main(void)
{
delay_init(168); //初始化延时函数
LED_Init(); //初始化LED端口
OSInit();
OSTaskCreate(start_task,(void*)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
OSStart();
}
//开始任务
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
pdata= pdata;
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
OSTaskCreate(led0_task, (void*)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);
OSTaskCreate(led1_task,(void*)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
//LED0任务
void led0_task(void *pdata)
{
while(1)
{
LED0=0;
delay_ms(80);
LED0=1;
delay_ms(920);
};
}
//LED1任务
void led1_task(void *pdata)
{
while(1)
{
LED1=0;
delay_ms(300);
LED1=1;
delay_ms(300);
};
}