目录
UCOS-ii–基础-----
初稿,最新还在整理中
做点笔记:
任务: 小任务对应的程序叫任务
程序控制块:代码上来看 她是一个结构体例如:
Task control block
牛逼啊: 数组和链表的结合!!!!!
、
UCOSII的5种状态
超循环结构
为什么是 *pdata 传入的参数可以是不同类型数据甚至可以是指针。
用户应用程序结构
空闲任务
统计任务
顺序说明
任务控制块链表
数组和链表的结合:
数组和链表的结合:
事件控制块表-等待
等待到就绪函数
说明:任务等待但是具备运行的条件,那么就让他进入就绪状态
等待超时时
解释:开始时都为空事件链表,初始化时候会将空的控制块赋值。删除是又还原。
任务就绪表
下面有定义的一个 OSRdyGrp 每一位管理一OSRdyTB 8位。
所以解释了为什么UCOSII最多管理8*8=64个任务
登记
举例
注销
最高优先级查找
调度器
按照某种规律进行任务切换的工作叫任务的调度。、
任务级的调度由函数OSSched()来实现。中断级的调度器由OSIntExt()来实现
任务切换时保护断点的压栈动作
调度器在任务切换时的工作过程
任务创建-挂起-恢复
#include "includes.h"
#define TASK_STK_SIZE 512 //任务堆栈长度
OS_STK StartTastStk[TASK_STK_SIZE]; //定义开始任务堆栈区
OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
void StartTast(void *pdata);
void MyTask(void *pdata); //声明任务
void YouTask(void *pdata); //声明任务
/************************主函数*********************************************/
void main(void)
{
OSInit(); //初始化uCOS_II
//ac_Key = 1; //设置信号量初值
OSTaskCreate(StartTast, //创建任务MyTask
(void *)0, //给任务传递参数
&StartTastStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针
0); //使任务MyTask的优先级别为0
OSStart(); //启动uCOS_II的多任务管理
}
/***********************任务StartTast******************/
void StartTast(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
OSStatInit(); //初始化uCOS_II的统计任务
OSTaskCreate(MyTask, //创建任务MyTask
(void *)0, //给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
5); //使任务MyTask的优先级别为0
OSTaskCreate(YouTask, //创建任务MyTask
(void *)0, //给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
6); //使任务MyTask的优先级别为0
OSTimeDlyHMSM(0,0,1,0);
}
/***********************任务MyTask*******************************************/
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
for (;;)
{
OS_Printf("1");
OSTimeDlyHMSM(0, 0, 0, 200);
}
}
/************************任务YouTask*****************************************/
INT8U time = 0;
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
for (;;)
{
if (10 == time)
{
//OSTaskSuspend(OS_PRIO_SELF); //挂起
//OSSchedLock(); //锁调度
//OSTaskChangePrio(6, 4); //更改优先级
}
if (20 == time)
{
//OSTaskResume(OS_PRIO_SELF); //挂起
//OSSchedUnlock(); //锁调度
//OSTaskChangePrio(4, 6); //更改优先级
time = 0;
}
time++;
OS_Printf("2");
OSTimeDlyHMSM(0, 0, 0, 200);
}
}
/************************End*************************************************/
(重要!!!)任务-删除
为什么不能随意删除:
1、有时任务会占用一些动态的内存或者信号量
2、我草 你自己没释放这些东西 。系统会崩溃的!!
3、OSTaskDel()
4、OSTaskDelReq() 一般使用这个 有个请求
!非常重要!UCOS II的初始化和任务的启动
1、首先调用OSInit()
对数据结构进行初始化,主要是创建包括空任务块链表的5个空数据区
初始化后结构图
Ucos II 的启动 — 首先是调用OSStart()开始前提是已经创建了一个用户任务
启动后的数据结构图
μC/OS-II系统响应中断的过程
消息之间的同步关系
1:有顺序的制约。A和B两个任务通过一个数据缓存区合作完成一件事情。A发送数据到缓存区。B接受数据缓存去数据。
2:间接制约的关系。A和B两个任务共享打印机,只能一个用。
总结:在多任务合作的时候。操作系统应该解决的两件事情,
1,具有互斥关系(即对某个资源共享时,一个任务在使用,其他的任务要等待)
2,相关的任务执行要有先后顺序。
信号量
信号量:说白了就是就是一个信号,比如你去拉屎的时候,有人在拉粑粑的时候,门上一般都有标记(有人,或无人)。
假如:一个厕所只有一个坑,只有两个人上,因为情况最后是:要么你上,要么我上,值为0或一,城这个为互斥信号量。
假如:一个厕所好多人在等,那我们统计的时候是一个计数器,有人进去了就-1,出去了就进去+1.如计数器大于0,就可以进去拉屎
代码演示
#include "includes.h"
#define TASK_STK_SIZE 512 //任务堆栈长度
OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
char *s;
BOOLEAN ac_Key; //定义信号量
void MyTask(void *data); //声明任务
void YouTask(void *data); //声明任务
/************************主函数*********************************************/
void main(void)
{
OSInit(); //初始化uCOS_II
ac_Key = 1; //设置信号量初值
OSTaskCreate(MyTask, //创建任务MyTask
(void *)0, //给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针
0); //使任务MyTask的优先级别为0
OSStart(); //启动uCOS_II的多任务管理
}
/***********************任务MyTask*******************************************/
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
OSStatInit(); //初始化uCOS_II的统计任务
OSTaskCreate(YouTask, //创建任务MyTask
(void *)0, //给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
2); //使任务MyTask的优先级别为0
for (;;)
{
if (ac_Key) //判断信号量的值 1空闲 0忙
{
ac_Key = FALSE;
s = "Mystask";
OS_Printf(" s=%s\n", s);
ac_Key = TRUE;
OSTimeDly(20);
}
}
}
/************************任务YouTask************************/
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
for (;;)
{
if (ac_Key) //判断信号量的值 1空闲 0忙
{
ac_Key = FALSE;
s = "Youstask";
OS_Printf("s=%s\n", s);
ac_Key = TRUE;
OSTimeDly(20);
}
}
}
/************************End***********************************/
消息邮箱
应用:当任务与任务之间数据通行时。
可以在内存中创建一个储存空间作为数据缓存区,后面调用一般
以指针来使用。
代码演示
下面展示一些 内联代码片
。
// A code block
var foo = 'bar';
#include "includes.h"
#define TASK_STK_SIZE 512 //任务堆栈长度
OS_STK StartTastStk[TASK_STK_SIZE]; //定义开始任务堆栈区
OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
void *msg_p; //定义邮箱指针
//BOOLEAN ac_Key; //定义信号量
void StartTast(void *pdata);
void MyTask(void *pdata); //声明任务
void YouTask(void *pdata); //声明任务
/************************主函数*********************************************/
void main(void)
{
OSInit(); //初始化uCOS_II
//ac_Key = 1; //设置信号量初值
OSTaskCreate(StartTast, //创建任务MyTask
(void *)0, //给任务传递参数
&StartTastStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针
0); //使任务MyTask的优先级别为0
OSStart(); //启动uCOS_II的多任务管理
}
/***********************任务StartTast******************/
void StartTast(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
OSStatInit(); //初始化uCOS_II的统计任务
OSTaskCreate(MyTask, //创建任务MyTask
(void *)0, //给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
1); //使任务MyTask的优先级别为0
OSTaskCreate(YouTask, //创建任务MyTask
(void *)0, //给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
2); //使任务MyTask的优先级别为0
OSTimeDlyHMSM(0,0,3,0);
}
/***********************任务MyTask*******************************************/
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
OS_ENTER_CRITICAL();
OS_EXIT_CRITICAL();
OSStatInit(); //初始化uCOS_II的统计任务
OSTaskCreate(YouTask, //创建任务MyTask
(void *)0, //给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
2); //使任务MyTask的优先级别为0
for (;;)
{
if (msg_p != (void *)0)
{
OS_Printf("msg_p=%s\n", msg_p);
msg_p = (void *)0;
}
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
/************************任务YouTask*****************************************/
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
char *str = "11111";
pdata = pdata;
for (;;)
{
if (OSTimeGet()>500 && msg_p == (void *)0)
{
OS_Printf("这是要发送的msg:%s\n", str);
msg_p = str;
}
OSTimeDlyHMSM(0, 0, 2, 0);
}
}
/************************End*************************************************/
消息队列
将msg_p 这个替换成一个指针数组。
信号量事件控制块
代码分析:要求:一个函数Fun()和两个任务,两个任务只能一个调用Fun()han函数。
下面展示一些 内联代码片
。
// A code block
var foo = 'bar';
#include "includes.h"
#define TASK_STK_SIZE 512 //任务堆栈长度
OS_STK StartTastStk[TASK_STK_SIZE]; //定义开始任务堆栈区
OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
OS_EVENT *Fun_Semp; 定义OS_EVENT类型的信号量计数器
INT8U err;
//BOOLEAN ac_Key; //定义简单的信号量
void Fun(INT8U x,INT8U y);
void StartTast(void *pdata);
void MyTask(void *pdata); //声明任务
void YouTask(void *pdata); //声明任务
/************************主函数*********************************************/
void main(void)
{
OSInit(); //初始化uCOS_II
Fun_Semp = OSSemCreate(1); //初始化计数器为1
OSTaskCreate(StartTast, //创建任务MyTask
(void *)0, //给任务传递参数
&StartTastStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针
0); //使任务MyTask的优先级别为0
OSStart(); //启动uCOS_II的多任务管理
}
/***********************任务StartTast******************/
void StartTast(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
OSStatInit(); //初始化uCOS_II的统计任务
OSTaskCreate(MyTask, //创建任务MyTask
(void *)0, //给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
1); //使任务MyTask的优先级别为0
OSTaskCreate(YouTask, //创建任务MyTask
(void *)0, //给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
2); //使任务MyTask的优先级别为0
OSTimeDlyHMSM(0,0,3,0);
}
/***********************任务MyTask*******************************************/
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
char *s1 = "MyTask";
for (;;)
{
OSSemPend(Fun_Semp, 0, &err);
OS_Printf("%s\n", s1);
Fun(7, 8);
OSSemPost(Fun_Semp);
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
/************************任务YouTask*****************************************/
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
char *s2 = "Youtask";
pdata = pdata;
for (;;)
{
OSSemPend(Fun_Semp, 0, &err);
OS_Printf("%s\n", s2);
Fun(7, 8);
OSSemPost(Fun_Semp);
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
void Fun(INT8U x, INT8U y)
{
OS_Printf("调用了Fun函数\n");
}
/************************End*************************************************/
1.创建信号量。
2.请求一个信号量
3.发送信号量