因为ucos-II是基于多任务的操作系统
本节说一下任务中很重要的三个概念
在之前先科普几个重要函数:
(1)OSStart();:操作系统多任务启动
(2)OSinit()l:操作系统全局变量,数据结构初始化,建立空闲、统计、定时任务
(1)创建了几个用户任务,优先级
OSTaskCreate(任务处理函数首地址指针,任务处理函数传参,任务分配的堆栈栈顶指针,任务优先级号);
有几句该程序就有几个任务
优先级号代表该任务优先级,从0开始,越小优先级越高,ucos-II总运行进入就绪态的优先级最高的任务
OSTimeOlg(1)//延时一个时钟节拍
OSTimeDlyHMSM(0,0,1,0)//延时 时,分,秒,毫秒
下面正式开始
1、信号量的使用方法
(1)定义事件指针,例如”OS_EVENT *LedSem”;这里LedSem为一个事件指针
(2)调用OSSemCreate();函数创建信号量
例如”LedSem = OSSemCreate(0);”,此时LedSem被装入一个信号量,初始计算数值为0,。
(4)在另一个任务中请求该信号量,例如”OSSedPend(LedSem,0,&err)”
#include <stdio.h>
#include"includes.h"
#include"system.h"//宏定义PIO_LED_BASE
#include"altera_avalon_pio_regs.h"
OS_STK task1_stk[TASK_STACKSIZE];//为要创建的任务定义堆栈
OS_STK task2_stk[TASK_STACKSIZE];
#define TASK1_PRIORITY 1//为创建的任务指定优先级号
#define TASK1_PRIORITY 2
#define TASK_STACKSIZE 2048//定义2048kb
OS_EVENT *RandomSem;//定义一个指向信号量RandomSem的指针(定义事件指针)
INT8U err;
void task1(void* pdata)//定义用户任务1{
while(1)//必须死循环{
OSSemPend(RandomSem,0,&err);//请求信号量[os_sem.c中]
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,0X00);//#define PIO_LED_BASE 0X4001000
usleep(500000);//任务挂起500000微秒,即0.5秒
OSSePost(RandomSem);//在一个任务中周期性地释放信号量
OSTimeDly(1);//调用该函数的任务被延时一个时钟节拍([位于os_time.c中])
}
}
void task2(void* pdata)//定义用户任务2{
while(1)//必须死循环{
OSSemPend(RandomSem,0,&err);//请求信号量[os_sem.c中]
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,0X0F);//#define PIO_LED_BASE 0X4001000
usleep(500000);//任务挂起500000微秒,即0.5秒
OSSePost(RandomSem);//在一个任务中周期性地释放信号量
OSTimeDly(1);//调用该函数的任务被延时一个时钟节拍([位于os_time.c中])
}
}
int main(void){
OSInit();//对ucos-II操作系统初始化(初始化全局变量或数据结构,建立空闲任务、统计任务和定时任务等系统服务)
//调用OSStart函数之前必调用该函数(位于os_core.c中)
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,0X00);
RandomSem = OSSemCreate(1);//调用OSSemCreate();创建信号量,信号量初始值设置为1
//创建用户任务[los_task.c]
OSTaskCrateExt(task1,//函数名 NULL,//函数参数
(void *)&task1_stk[TASK_STACKSIZE-1],//栈顶指针
TASK1_PRIORITY,//优先级号TASK1_PRIORITY,//任务ID号
task1_stk,//栈底指针ASK_STACKSIZE,//栈大小
NULL,//用户定义空间指针0//任务选项参数
);
OSTaskCrateExt(task1,//函数名
NULL,//函数参数(void *)&task2_stk[TASK_STACKSIZE-1],//栈顶指针
TASK2_PRIORITY,//优先级号TASK2_PRIORITY,//任务ID号
task2_stk,//栈底指针TASK_STACKSIZE,//栈大小
NULL,//用户定义空间指针0//任务选项参数
);
OSStart();//启动ucos-II操作系统多任务调度[必须在调用OSInit函数后使用(位于os_core.c)中]
}
2、互斥信号量使用方法
(1)定义事件控制模块指针,例如”OS_EVENT *LedMutex;”
(2)指定一个优先级号mx_prio作为优先级继承优先级(PIP)
该PIP的数值应小于所有请求共享资源的任务的优先级号
(3)调用OSMutexCreate();函数创建互斥信号量,例如”LedMutex = OSMutexCreate (mx_prio,&err);”
(4)如果一个任务要使用共享资源,应先调用OSMutexPend();函数请求互斥信号量,请求道互斥信号量后,使用共享资源,使用完后再调用OSMutexPost();函数释放互斥信号量
#include <stdio.h>
#include"includes.h"
#include"system.h"//宏定义PIO_LED_BASE
#include"altera_avalon_pio_regs.h"
OS_STK task1_stk[TASK_STACKSIZE];//为要创建的任务定义堆栈
OS_STK task2_stk[TASK_STACKSIZE];
#define TASK1_PRIORITY 1//为创建的任务指定优先级号
#define TASK1_PRIORITY 2
#define TASK_STACK_SIZE 512;
OS_EVENT *RandomMutex;
INT8U my_prio = 2;//my_pario称为优先级继承优先级(pip)[os_mutex.c中]
INT8U my_err;
void task1(void* pdata);
void task2(void* pdata);
void main(void){
OSInit();
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,0X00);
RandomMutex = OSMutexCreate(my_prio,&my_err);//创建并初始化一个互斥信号量,用于使任务获得对共享资源的独占式访问权
//必须确保my_prio的值小于所有可能请求互斥信号量的任务优先级
OSTaskCreate(task1,//函数名NULL,//函数参数&task1_stk[TASK_STACK_SIZE-1],//栈顶指针
TASK1_PRIO//优先级号
);
OSTaskCreate(task2,//函数名NULL,//函数参数&task2_stk[TASK_STACK_SIZE-1],//栈顶指针
TASK2_PRIO//优先级号
);
OSStart();
}
void task1(void* pdata){
while(1){
OSMutexPend(RandomMutex,0,&my_err);//请求互斥信号量[os_mutex.c中]
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,0Xff);
OSTimeDlyHMSM(0,0,1,0);
OSMutexPost(RandomMutex);//释放互斥信号量
}
}
void task1(void* pdata){
while(1){
OSMutexPend(RandomMutex,0,&my_err);//请求互斥信号量[os_mutex.c中]
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,0X00);
OSTimeDlyHMSM(0,0,1,0);
OSMutexPost(RandomMutex);//释放互斥信号量
}
}
3、消息邮箱使用方法
(1)定义事件指针,例如”OS_EVENT *LedMbox;”,这里LedMbox为一个事件指针
(2)使用消息邮箱前,必须调用OSMboxCreate();函数创建消息邮箱
例如”LedMbox = OSMboxCreate(NULL);”,表示创建一个空的消息邮箱,也可以在创建消息邮箱时给消息赋初值。
(3)首先在一个任务中定义一个一维数组,例如”INI8U myMessage[80];”,然后将要传递出去的消息存入myMessage数组中,例如”strcpy((char *)myMessage,’Led 1 Light’)”,接着调用函数OSMboxPost周期地释放该消息。例如”OSMboxPost(LedMbox,(void *)&myMessage[0]);”
(4)首先在另一个任务中定义局部一维指针变量存放收到的消息,例如”void *pmsg;”,然后调用函数OSMboxPend请求消息邮箱中的消息。
例如”pmsg = OSMboxPend(edMbox,OS_TICKS_PER_SEC,&err);”,这样消息”Led 1 Light!”就从别的任务传递到该任务中来。
#include <stdio.h>
#include"includes.h"
#include"system.h"//宏定义PIO_LED_BASE
#include"altera_avalon_pio_regs.h"
OS_STK task1_stk[TASK_STACKSIZE];//为要创建的任务定义堆栈
OS_STK task2_stk[TASK_STACKSIZE];
#define TASK1_PRIORITY 1//为创建的任务指定优先级号
#define TASK1_PRIORITY 2
#define TASK_STACKSIZE 2048
OS_EVENT *RandomSem;
INT8U my_err;
OS_EVENT *MsgMbox;//定义消息邮箱指针
void task1(void* pdata){
int txMsg = 0;
while(1){
OSMboxPost(MsgMbox,&txMsg);//向邮箱传入消息(发消息给TASK2)[os_mbox.c]
txMsg++;
if(txMsg == 5)txMsg = 0;
OSTimeDlyHMSM(0,0,1,0);
}
}
void task2(void* pdata){
int * rxMsg = 0;
while(1){
rxMsg = (int *)OSMboxPend(MsgMbox,0,&my_err);//向邮箱请求消息[os_mbox.c](返回消息指针,据该指针可获取消息)
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,*rxMsg);
OSTimeDlyHMSM(0,0,1,0);
}
}
int main(void){
OSInit();
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,0X00);
MsgBox = OSMboxCreate((void *)0);//创建并初始化一个消息邮箱(如果参数不为空,则新建的邮箱将包含消息)[os_mbox.c]
OSTaskCreate(task1,//建立任务NULL,&task1_stk[TASK_STACKSIZE-1],TASK1_PRIOPITY);
OSTaskCreate(task2,//建立任务NULL,&task2_stk[TASK_STACKSIZE-1],TASK2_PRIOPITY);
OSStart();
return 0;
}