uCOS-II实验

多任务调度实验

实验目的

编写延时分别为3s、1s和1s的三个任务,观察任务之间的交替运行次序,熟悉任务调度的过程。要求三个任务的输出分别为:M、Y和H,连续不换行显示。

实验代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "includes.h"
#define TASK1_PRO 1
#define TASK2_PRO 2
#define TASK3_PRO 3
OS_STK Task1Stk[TASK_STK_SIZE];
OS_STK Task2Stk[TASK_STK_SIZE];
OS_STK Task3Stk[TASK_STK_SIZE];
static void Task1(void *p_arg);
static void Task2(void *p_arg);
static void Task3(void *p_arg);

void TaskCreate(void){
OSTaskCreate(Task1, NULL, &Task1Stk, TASK1_PRO);
OSTaskCreate(Task2, NULL, &Task2Stk, TASK2_PRO);
OSTaskCreateExt(Task3, NULL, &Task3Stk, TASK3_PRO, TASK3_PRO, &Task3Stk[TASK_STK_SIZE - 1], TASK_STK_SIZE, NULL, 0);
}
static void Task1(void *p_arg){
p_arg = p_arg;
while (1){
printf("M");
OSTimeDlyHMSM(0, 0, 3, 0);
}
}
static void Task2(void *p_arg){
p_arg = p_arg;
while (1){
printf("Y");
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
static void Task3(void *p_arg){
p_arg = p_arg;
while (1){
printf("H");
OSTimeDlyHMSM(0, 0, 1, 0);
}
}

实验结果

Scheduling

analysisScheduling

实验体会

第一次对操作系统的代码进行编写调试,深入了解了任务堆栈、创建任务和任务调度,任务间的调度是由cpu在就绪任务中选择最高优先级的任务。调用函数OSStart()之前先创建一个任务,并赋予它最高的优先级别,从而使它成为起始任务。

利用消息队列进行任务间通信实验

实验目的

仿照《嵌入式实时操作系统uCOS-II原理及应用》(第4版)例4-9,利用先进先出的方式组织消息,由任务一发送消息,任务二和任务三请求消息,三个任务的延时时间均为1s。

实验代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "includes.h"
#define N_MESSAGES 128 //定义消息队列长度
OS_STK TaskStk1[TASK_STK_SIZE]; //定义任务堆栈区
OS_STK TaskStk2[TASK_STK_SIZE]; //定义任务堆栈区
OS_STK TaskStk3[TASK_STK_SIZE]; //定义任务堆栈区

char *ss;
char *s100;
char *s0;
char *s1;
char *s500;
void *MsgGrp[N_MESSAGES]; //定义消息指针数组
INT8U err;

OS_EVENT *Str_Q; //定义事件控制块
void Task1(void *data); //声明任务
void Task2(void *data); //声明任务
void Task3(void *data); //声明任务

void TaskCreate(void){
Str_Q = OSQCreate(&MsgGrp[0], N_MESSAGES); //创建消息队列
OSTaskCreate(Task1, //创建任务Task1
(void*)0, //给任务传递参数
&TaskStk1[TASK_STK_SIZE - 1], //设置任务堆栈栈顶
0); //使任务的优先级别为0
OSTaskCreate(Task2, //创建任务Task2
(void*)0, //给任务传递参数
&TaskStk2[TASK_STK_SIZE - 1], //设置任务堆栈栈顶
3); //使任务的优先级别为3
OSTaskCreate(Task3, //创建任务Task3
(void*)0, //给任务传递参数
&TaskStk3[TASK_STK_SIZE - 1], //设置任务堆栈栈顶
4); //使任务的优先级别为4
}
/***********************任务Task1*******************************/
void Task1(void *pdata){
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
s0 = "这个串能收到几次?";
OSQPostFront(Str_Q, s0); //发送消息
for (;;){
if (OSTimeGet() > 0 && OSTimeGet() < 200){ //可以满足两次条件
s100 = "现在OSTime的值在0到200之间";
OSQPostFront(Str_Q, s100); //发送消息
s1 = "这个串是哪个任务收到的?";
OSQPostFront(Str_Q, s1); //发送消息
}
if (OSTimeGet() > 2000 && OSTimeGet() < 2300){
s500 = "现在OSTime的值在2000到2300之间";
OSQPostFront(Str_Q, s500); //发送消息
}
OSTimeDlyHMSM(0, 0, 1, 0); //等待1秒
}
}
/************************任务Task2*******************************/
void Task2(void *pdata){
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;

for (;;){
ss = OSQPend(Str_Q, 0, &err); //请求消息队列
printf("%s\n", ss);
printf("Task2 is running!\n");
OSTimeDlyHMSM(0, 0, 1, 0); //等待1秒
}
}
/************************任务Task3******************************/
void Task3(void *pdata){
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;

for (;;){
ss = OSQPend(Str_Q, 0, &err); //请求消息队列
printf("%s\n", ss);
printf("Task3 is running!\n");
OSTimeDlyHMSM(0, 0, 1, 0); //等待1秒
}
}

实验结果

Communication

analysisCommunication

实验体会

通过本次实验进一步掌握了消息队列相当于共用一个任务等待表的消息邮箱数组,向指针数组插入消息指针有两种方式:FIFO和 LIFO,本实验采用的是LIFO(后进先出),任务请求消息队列需要调用函数OSQPend()。

文章作者: gzwangu
文章链接: https://gzwangu.github.io/2020/04/25/uCOS-II实验/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Clousbin の Blog
支付宝打赏
微信打赏