uC/OS-II源码分析(二)
1)使用信号量
#define N_TASKS 10 /* 任务数*/
OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; /*任务堆栈*/
OS_STK TaskStartStk[TASK_STK_SIZE]; //开始任务的堆栈
char TaskData[N_TASKS]; /*传给每个任务的数据*/
OS_EVENT *RandomSem; //互斥型信号量
void main (void)
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /*清空屏幕*/
OSInit(); /* 初始化uC/OS-II*/
PC_DOSSaveReturn(); /* 保存环境以便稍后可以返回DOS环境*/
PC_VectSet(uCOS, OSCtxSw); /*设置uC/OS-II的切换处理函数*/
RandomSem = OSSemCreate(1); /* 建立一个信号量*/
OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 0);//创建第一个任务,优先级设置为最大值
OSStart(); /* 开始多任务*/
}
void TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU的状态寄存器分配内存*/
OS_CPU_SR cpu_sr;
#endif
char s[100];
INT16S key;
pdata = pdata; /* 这步是为了防止编译错误*/
TaskStartDispInit(); /* 初始化显示屏*/
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); /*替换机器的时钟中断函数为uC/OS-II所需要的中断函数*/
PC_SetTickRate(OS_TICKS_PER_SEC); /* 调整时钟频率*/
OS_EXIT_CRITICAL();
OSStatInit(); /* 初始化统计任务*/
TaskStartCreateTasks(); /*创建其他任务*/
for (;;) {
TaskStartDisp();
if (PC_GetKey(&key) == TRUE) { /* 是否按键*/
if (key == 0x1B) { /* ESCAPE按下了*/
PC_DOSReturn(); /* 返回DOS*/
}
}
OSCtxSwCtr = 0; /* 切换次数计数器清零*/
OSTimeDlyHMSM(0, 0, 1, 0); /*挂起秒,让给其他任务运行*/
}
}
static void TaskStartCreateTasks (void)
{
INT8U i;
for (i = 0; i < N_TASKS; i++) { /* 创建N_TASKS个任务*/
TaskData[i] = '0' + i; /* 每个任务显示其数据*/
OSTaskCreate(Task, (void *)&TaskData[i], &TaskStk[i][TASK_STK_SIZE - 1], i + 1);
}
}
void Task (void *pdata)
{
INT8U x;
INT8U y;
INT8U err;
for (;;) {
OSSemPend(RandomSem, 0, &err); /* 获取信号量*/
x = random(80); /* 计算X坐标*/
y = random(16); /* 计算Y坐标*/
OSSemPost(RandomSem); /* 释放信号量*/
/* Display the task number on the screen */
PC_DispChar(x, y + 5, *(char *)pdata, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
OSTimeDly(1); /* 挂起秒,让给其他任务运行*/
}
}
2)使用消息邮箱
#define TASK_START_ID 0 /* 任务ID*/
#define TASK_CLK_ID 1
#define TASK_1_ID 2
#define TASK_2_ID 3
#define TASK_3_ID 4
#define TASK_4_ID 5
#define TASK_5_ID 6
#define TASK_START_PRIO 10 /* 任务优先级*/
#define TASK_CLK_PRIO 11
#define TASK_1_PRIO 12
#define TASK_2_PRIO 13
#define TASK_3_PRIO 14
#define TASK_4_PRIO 15
#define TASK_5_PRIO 16
OS_STK TaskStartStk[TASK_STK_SIZE];
OS_STK TaskClkStk[TASK_STK_SIZE];
OS_STK Task1Stk[TASK_STK_SIZE];
OS_STK Task2Stk[TASK_STK_SIZE];
OS_STK Task3Stk[TASK_STK_SIZE];
OS_STK Task4Stk[TASK_STK_SIZE];
OS_STK Task5Stk[TASK_STK_SIZE];
OS_EVENT *AckMbox; /* 任务和使用的消息邮箱*/
OS_EVENT *TxMbox;
void main (void)
{
OS_STK *ptos;
OS_STK *pbos;
INT32U size;
PC_DispClrScr(DISP_FGND_WHITE);
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
PC_ElapsedInit();
ptos = &TaskStartStk[TASK_STK_SIZE - 1];
pbos = &TaskStartStk[0];
size = TASK_STK_SIZE;
OSTaskStkInit_FPE_x86(&ptos, &pbos, &size);
OSTaskCreateExt(TaskStart,
(void *)0,
ptos,
TASK_START_PRIO,
TASK_START_ID,
pbos,
size,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSStart();
}
void TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
INT16S key;
pdata = pdata;
TaskStartDispInit();
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSStatInit();
AckMbox = OSMboxCreate((void *)0); /* 创建两个消息邮箱*/
TxMbox = OSMboxCreate((void *)0);
TaskStartCreateTasks();
for (;;) {
TaskStartDisp();
if (PC_GetKey(&key)) {
if (key == 0x1B) {
PC_DOSReturn();
}
}
OSCtxSwCtr = 0;
OSTimeDly(OS_TICKS_PER_SEC);
}
}
void Task1 (void *pdata)
{
INT8U err;
OS_STK_DATA data; /* 任务堆栈数据*/
INT16U time;
INT8U i;
char s[80];
pdata = pdata;
for (;;) {
for (i = 0; i < 7; i++) {
PC_ElapsedStart();
err = OSTaskStkChk(TASK_START_PRIO + i, &data);//执行堆栈检查
time = PC_ElapsedStop();
if (err == OS_NO_ERR) {
sprintf(s, "%4ld %4ld %4ld %6d",
data.OSFree + data.OSUsed,
data.OSFree,
data.OSUsed,
time);
PC_DispStr(19, 12 + i, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
}
}
OSTimeDlyHMSM(0, 0, 0, 100); /* 挂起mS*/
}
}
void Task4 (void *data)
{
char txmsg;
INT8U err;
data = data;
txmsg = 'A';
for (;;) {
OSMboxPost(TxMbox, (void *)&txmsg); /* 发消息给Task #5*/
OSMboxPend(AckMbox, 0, &err); /* 等待Task #5的应答消息*/
txmsg++; /*下一个要发的消息数据*/
if (txmsg == 'Z') {
txmsg = 'A'; /* 循环发送A-Z*/
}
}
}
void Task5 (void *data)
{
char *rxmsg;
INT8U err;
data = data;
for (;;) {
rxmsg = (char *)OSMboxPend(TxMbox, 0, &err); /* 等待来自Task #4的数据*/
PC_DispChar(70, 18, *rxmsg, DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDlyHMSM(0, 0, 1, 0); /* 挂起秒,让给其他任务运行*/
OSMboxPost(AckMbox, (void *)1); /*发送接收到数据的应答消息*/
}
}
运行结果:
3)使用消息队列
#define TASK_START_ID 0
#define TASK_CLK_ID 1
#define TASK_1_ID 2
#define TASK_2_ID 3
#define TASK_3_ID 4
#define TASK_4_ID 5
#define TASK_5_ID 6
#define TASK_START_PRIO 10
#define TASK_CLK_PRIO 11
#define TASK_1_PRIO 12
#define TASK_2_PRIO 13
#define TASK_3_PRIO 14
#define TASK_4_PRIO 15
#define TASK_5_PRIO 16
#define MSG_QUEUE_SIZE 20 /* 消息队列大小*/
typedef struct {
char TaskName[30];
INT16U TaskCtr;
INT16U TaskExecTime;
INT32U TaskTotExecTime;
} TASK_USER_DATA;
OS_STK TaskStartStk[TASK_STK_SIZE];
OS_STK TaskClkStk[TASK_STK_SIZE];
OS_STK Task1Stk[TASK_STK_SIZE];
OS_STK Task2Stk[TASK_STK_SIZE];
OS_STK Task3Stk[TASK_STK_SIZE];
OS_STK Task4Stk[TASK_STK_SIZE];
OS_STK Task5Stk[TASK_STK_SIZE];
TASK_USER_DATA TaskUserData[7];
OS_EVENT *MsgQueue; /*消息队列指针*/
void *MsgQueueTbl[20]; /*消息存储*/
void main (void)
{
PC_DispClrScr(DISP_BGND_BLACK);
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
PC_ElapsedInit();
strcpy(TaskUserData[TASK_START_ID].TaskName, "StartTask");
OSTaskCreateExt(TaskStart,
(void *)0,
&TaskStartStk[TASK_STK_SIZE - 1],
TASK_START_PRIO,
TASK_START_ID,
&TaskStartStk[0],
TASK_STK_SIZE,
&TaskUserData[TASK_START_ID],
0);
OSStart();
}
void TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
INT16S key;
pdata = pdata;
TaskStartDispInit();
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSStatInit();
MsgQueue = OSQCreate(&MsgQueueTbl[0], MSG_QUEUE_SIZE); /*创建消息队列,大小为*/
TaskStartCreateTasks();
for (;;) {
TaskStartDisp();
if (PC_GetKey(&key)) {
if (key == 0x1B) {
PC_DOSReturn();
}
}
OSCtxSwCtr = 0;
OSTimeDly(OS_TICKS_PER_SEC);
}
}
void Task1 (void *pdata)
{
char *msg;
INT8U err;
pdata = pdata;
for (;;) {
msg = (char *)OSQPend(MsgQueue, 0, &err);//从消息队列中取消息
PC_DispStr(70, 13, msg, DISP_FGND_YELLOW + DISP_BGND_BLUE);
OSTimeDlyHMSM(0, 0, 0, 100);
}
}
void Task2 (void *pdata)
{
char msg[20];
pdata = pdata;
strcpy(&msg[0], "Task 2");
for (;;) {
OSQPost(MsgQueue, (void *)&msg[0]);//发送消息到队列中
OSTimeDlyHMSM(0, 0, 0, 500);
}
}
void Task3 (void *pdata)
{
char msg[20];
pdata = pdata;
strcpy(&msg[0], "Task 3");
for (;;) {
OSQPost(MsgQueue, (void *)&msg[0]);//发送消息到队列中
OSTimeDlyHMSM(0, 0, 0, 500);
}
}
void Task4 (void *pdata)
{
char msg[20];
pdata = pdata;
strcpy(&msg[0], "Task 4");
for (;;) {
OSQPost(MsgQueue, (void *)&msg[0]);//发送消息到队列中
OSTimeDlyHMSM(0, 0, 0, 500);
}
}
void OSTaskStatHook (void)
{
char s[80];
INT8U i;
INT32U total;
INT8U pct;
total = 0L; /* Totalize TOT. EXEC. TIME for each task
for (i = 0; i < 7; i++) {
total += TaskUserData[i].TaskTotExecTime;
DispTaskStat(i); /* Display task data
}
if (total > 0) {
for (i = 0; i < 7; i++) { /* Derive percentage of each task */
pct = 100 * TaskUserData[i].TaskTotExecTime / total;
sprintf(s, "%3d %%", pct);
PC_DispStr(62, i + 11, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
}
}
if (total > 1000000000L) { /* Reset total time counters at 1 billion
for (i = 0; i < 7; i++) {
TaskUserData[i].TaskTotExecTime = 0L;
}
}
}
void OSTaskSwHook (void)
{
INT16U time;
TASK_USER_DATA *puser;
time = PC_ElapsedStop(); /* This task is done
PC_ElapsedStart(); /* Start for next task
puser = OSTCBCur->OSTCBExtPtr; /* Point to used data
if (puser != (TASK_USER_DATA *)0) {
puser->TaskCtr++; /* Increment task counter
puser->TaskExecTime = time; /* Update the task's execution time
puser->TaskTotExecTime += time; /* Update the task's total execution time
}
}
运行结果:
作者:洞庭散人
出处:http://phinecos.cnblogs.com/
uC/OS-II源码分析(二)的更多相关文章
- Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题
4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...
- 框架-springmvc源码分析(二)
框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...
- Tomcat源码分析二:先看看Tomcat的整体架构
Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...
- 十、Spring之BeanFactory源码分析(二)
Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...
- Vue源码分析(二) : Vue实例挂载
Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...
- 多线程之美8一 AbstractQueuedSynchronizer源码分析<二>
目录 AQS的源码分析 该篇主要分析AQS的ConditionObject,是AQS的内部类,实现等待通知机制. 1.条件队列 条件队列与AQS中的同步队列有所不同,结构图如下: 两者区别: 1.链表 ...
- ABP源码分析二:ABP中配置的注册和初始化
一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...
- spring源码分析(二)Aop
创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...
- ConcurrenHashMap源码分析(二)
本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...
- Docker源码分析(二):Docker Client创建与命令执行
1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...
随机推荐
- Bootstrap学习速查表(四) 栅格系统
Bootstrap框架的网格系统工作原理如下: 1.数据行(.row)必须包含在容器(.container)中,以便为其赋予合适的对齐方式和内距(padding).如: 2.在行(.row)中可以添加 ...
- 底部TabsFooter
Demo简单描述:点击底部菜单可切换页面,并且底部为共用. 这个是在设置好导航Navigator之后进行的步骤,只是我个人进行Tab切换的一种思路方法,或许不是最好的,仅供参考一下. 首先我们需要一个 ...
- 常用string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- difference between VM, Docker and Vagrant区别
VM: VirtualBox, VMware Docker Vagrant using which you can create VMs or container. It interacts wit ...
- linux memcached php 整合
http://blog.csdn.net/liruxing1715/article/details/8269563
- C++复习:位运算
与 a&b : 1010&1100=1000 或 a|b : 1010|1100=1110 异或 a^b : 101 ...
- MySQL mysqlbinlog
MySQL binlog日志记录了MySQL数据库从启用日志以来所有对当前数据库的变更.binlog日志属于二进制文件,我们可以从binlog提取出来生成可读的文本或者SQL语句来重建当前数据库以及根 ...
- 继续封装DBDA.php 加入ajax
<?php class DBDA { public $host = "localhost"; //服务器地址 public $uid = "root"; ...
- 如果数据需要被多个应用程序消费的话,推荐使用 Kafka,如果数据只是面向 Hadoop 的,可以使用 Flume
https://www.ibm.com/developerworks/cn/opensource/os-cn-kafka/index.html Kafka 与 Flume 很多功能确实是重复的.以下是 ...
- PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析(转)
sort() 函数用于对数组单元从低到高进行排序. rsort() 函数用于对数组单元从高到低进行排序. asort() 函数用于对数组单元从低到高进行排序并保持索引关系. arsort() 函数用于 ...