打印
[应用相关]

基于STM32单片机的ucOS II操作系统,学习笔记

[复制链接]
1570|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Rooney30|  楼主 | 2016-4-23 15:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.0、RTX51 是专为8051单片机设计的实时操作系统,精简版Tiny最大任务数为16个。每个任务都必须是死循环,在while(1){}里面写任务函数。
1.1、RTX 51 tiny 是通过时间片来切换任务,只要时间到了,就会强制切换到下一个任务,不区分优先级,先就绪先运行。
1.2、没有main函数,程序首先从任务0开始运行,一般的启动过程是:进入任务0、初始化外设、创建用户任务、挂起任务0

2.0、ucOS操作系统可以移植到多种MCU上,甚至PC环境下,最大任务数挺多的。每个任务都必须是死循环,在while(1){}里面写任务函数。
2.1、UCOS 没有所谓的时间片(但是也可以设定时间来控制延时快慢),只要任务不调用OS的延时,就会一直占用CPU资源(除非有优先级高的任务已经就绪,就会去运行优先级高的任务),延时函数为:OSTimeDlyHMSM(时,分,秒,毫秒);只要延时时间到了,任务就会处于“就绪状态”,当CPU空闲,且没有优先级比它高的任务就绪时,该任务就会从新运行。
2.2、代码从main函数开始运行,一般的启动过程是:进入main函数、配置时钟、初始化外设IO口、初始化系统OSInit();、创建初始任务、启动系统OSStart();、创建用户任务、挂起本任务(初始任务)【下划线为初始任务的工作】

任务创建过程:
一、打开模板后,要创建一个新任务需要在main.c中设置这个任务的:
1、调用相应的头文件
2、任务优先级      
3、设置堆栈大小
4、创建任务堆栈
5、任务声明
6、在本任务内再初始化本硬件

比如创建一个LCD5110显示的任务:
创建过程:首先要创建一个起始任务Task_start
1、引用头文件 #include "lCD5110.h"

2、任务优先级:数值越小优先级越高
#define LCD5110_TASK_Prio  8

3、设置定义堆栈大小
#define  LCD5110_STK_SIZE  64

4、创建任务的堆栈数组。堆栈数组必须是 OS_STK类型
staticOS_STK  TASK_LCD5110_STK[LED_STK_SIZE];

5、任务声明
voidTaskLCD5110(void *pdata);
#include"includes.h" //包含各种头文件
#include"lCD5110.h"

#defineSTARTUP_TASK_PRIO       10  //起始任务
#defineLCD5110_TASK_Prio      8   //5110显示优先级

#defineSTARTUP_TASK_STK_SIZE   128   //起始任务堆栈大小
#defineLCD5110_STK_SIZE     64  //5110堆栈大小

static OS_STK  startup_task_stk[STARTUP_TASK_STK_SIZE];
static OS_STK  TASK_LCD5110_STK[LED_STK_SIZE]; //5110

voidTask_start(void *p_arg);
voidTaskLCD5110(void *pdata);

unsigned intchang,dy,dl,dltemp=0,Power,Res,delay=0;
unsigned charONOFF;

int main(void)
{
   SysTick_Config(SystemCoreClock/OS_TICKS_PER_SEC);//设置stm32的SysTick中断

   LCD5110_IO_Init();  // LCD5110 IO口配置

   OSInit();  //调用OS初始化
   OSTaskCreate(Task_start,(void *)0,&startup_task_stk[STARTUP_TASK_STK_SIZE-1], STARTUP_TASK_PRIO);//创建起始任务
   OSStart();  //启动OS

   return 0;
}

voidTask_start(void *p_arg)
{
   OS_CPU_SR  cpu_sr=0;   //进入临界区,需要本定义

   OS_ENTER_CRITICAL();    //进入临界区(无法被中断)

   OSTaskCreate(TaskLCD5110, (void * )0, (OS_STK *)&TASK_LCD5110_STK[LCD5110_STK_SIZE-1], LCD5110_TASK_Prio);    //创建LCD5110的任务
   OSTaskSuspend(STARTUP_TASK_PRIO);  //挂起本任务
   OS_EXIT_CRITICAL();    //退出临界区
}


voidTaskLCD5110(void *pdata)
{
   LCD5110_Init();  //LCD初始化
   LCD5110_ShowString(0,0," ON"); //显示固定界面
   while(1)
{      
       LCD_Write_V(0,0,dy);        //显示
      OSTimeDlyHMSM(0,0,1,20);   //OS系统延时1.02s,让出CPU
   }
}

常用系统函数介绍
一、任务创建的函数
OSTaskCreate(TaskLCD5110,
(void * )0,
(OS_STK *)&TASK_LCD5110_STK[LCD5110_STK_SIZE-1],  
LCD5110_TASK_Prio);

OSTaskCreate(任务指针(名),(void * )0,堆栈大小,优先级);
二、任务挂起
OSTaskSuspend(LCD5110_TASK_Prio);
OSTaskSuspend(需要挂起的优先级);挂起后任务将会不在运行。

三、挂起任务后的恢复
OSTaskResume(LCD5110_TASK_Prio);
OSTaskResume(需要恢复的优先级);回复后任务重新就绪,等待运行

------------2016-02-25--广东佛山—-by:JiaYu ---------

四、互斥信号
多个任务可能使用同一资源,或变量,并且有些工作需要共同协作来完成,所以需要相互支持和限制。
1、在os_cfg.h内开启功能,1为开启
#define OS_MUTEX_EN               0   
#define OS_MUTEX_ACCEPT_EN      1   
#define OS_MUTEX_DEL_EN          1  
#define OS_MUTEX_QUERY_EN       1

2、定义需要的变量
OS_EVENT *Sem_Event;  //定义一个事件
u8 err;

3、起始任务中
Sem_Event=OSMutexCreate(1,&err);  //创建信号量

4、任务中
OSMutexPend(Sem_Event,0,&err); //查询互斥信号,没有占用,继续运行,有占用则等待
OSMutexPost(Sem_Event);  //释放信号,释放控制权

沙发
500days| | 2016-4-23 22:12 | 只看该作者
这个互斥信号量一般在什么时候才用到呢?

使用特权

评论回复
板凳
whtwhtw| | 2016-4-24 01:04 | 只看该作者
UCOSIII支持时间片调度了

使用特权

评论回复
地板
wenshijian| | 2016-4-24 15:30 | 只看该作者
你的是UCOSII 的什么版本?v2.86有没有问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

117

帖子

3

粉丝