uCOSii中的互斥信号量
一、互斥型信号量项管理 (MUTUAL EXCLUSION SEMAPHORE MANAGEMENT)
OSMutexAccept() 无条件等待地获取互斥型信号量
OSMutexCreate() 建立并初始化一个互斥型信号量
OSMutexDel() 删除互斥型信号量
OSMutexPend() 等待一个互斥型信号量
OSMutexPost() 释放一个互斥型信号量
OSMutexQuery() 查询一个互斥型信号量的当前状态
OS_EVENT *MutualExclusionSemaphores_Event; //定义事件控制模块指针
#define MutualExclusionSemaphores_PRIO 4
//继承优先级,互斥信号量专有的
/*当某个任务已经获取到这个互斥信号量时,却发现"另外一个更高优先级的任务"也在试图获得"这个互斥信号量",这时,需要将拥有"这个互斥信号量的任务"的优先级被提升到这个"继承优先级",防止任务之间产生竞争。
必须确保MutualExclusionSemaphores_PRIO的值小于所有"需要请求这个互斥信号量的任务"的优先级;
*/
MutualExclusionSemaphores_Event=OSMutexCreate(MutualExclusionSemaphores_PRIO,&err);
//创建并初始化一个互斥信号量,用于使任务获得对共享资源的独占式访问权
//相比较而言,FreeRTOS创建互斥信号量比uCOSii更简单更容易
二、互斥信号量的创建,发送和拾取
1、My_Task_Priority.c文件
__align(8) OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈
__align(8) OS_STK SaveDATA1_TASK_STACK[SaveDATA1_TASK_STACK_SIZE]; //SaveDATA1_TASK任务堆栈
__align(8) OS_STK ReadDATA1_TASK_STACK[ReadDATA1_TASK_STACK_SIZE]; //ReadDATA1_TASK任务堆栈
//如果任务中使用printf来打印浮点数据的话一点要8字节对齐
OS_EVENT *MutualExclusionSemaphores_Event; //定义事件控制模块指针
2、My_Task_Priority.h文件
//My_Task_Priority.h
#ifndef __MY_TASK_PRIORITY_H
#define __MY_TASK_PRIORITY_H
#include "includes.h"
//当OS_LOWEST_PRIO=63时,μC/OS-II有64个优先级,优先级的高低按编号从0(最高)到63(最低)排序;
//OS_TASK_IDLE_PRIO为63,是空闲任务优先级,OS_TASK_IDLE_ID为65535
//OS_TASK_STAT_PRIO为62,是统计任务优先级,OS_TASK_STAT_ID为65534
//uCOSii至少有两个任务,分别是"空闲任务"和"统计任务"
/*
为了保证“启动任务”能够连续运行,必须将“启动任务”的优先级选择为最高。
否则,当“启动任务”创建一个优先级高于自己的任务时,刚刚创建的任务就
会立即进入运行状态,而与这个任务关联的其它任务可能还没有创建,它使
用的通信工具也还没有创建,系统必然出错。
*/
#define START_TASK_PRIORITY 3 //设置START_TASK任务优先级,开始任务的优先级设置为最高
#define START_TASK_STACK_SIZE 192 //设置START_TASK任务堆栈大小,为8的倍数
extern OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈
#define MutualExclusionSemaphores_PRIO 4 //继承优先级,互斥信号量专有的
//当某个任务已经获取到这个互斥信号量时,却发现"另外一个更高优先级的任务"也在试图获得"这个互斥信号量",
//这时,需要将拥有"这个互斥信号量的任务"的优先级被提升到这个"继承优先级",防止任务之间产生竞争。
//必须确保MutualExclusionSemaphores_PRIO的值小于所有"需要请求这个互斥信号量的任务"的优先级
//在访问互斥信号量时,使用的优先级。
#define SaveDATA1_TASK_PRIORITY 5 //设置SaveDATA1_TASK任务优先级为5
#define SaveDATA1_TASK_STACK_SIZE 56 //设置SaveDATA1_TASK任务堆栈大小为56,为8的倍数
extern OS_STK SaveDATA1_TASK_STACK[SaveDATA1_TASK_STACK_SIZE]; //SaveDATA1_TASK任务堆栈
#define ReadDATA1_TASK_PRIORITY 6 //设置ReadDATA1_TASK任务优先级为6
#define ReadDATA1_TASK_STACK_SIZE 72 //设置ReadDATA1_TASK任务堆栈大小为72,为8的倍数
extern OS_STK ReadDATA1_TASK_STACK[ReadDATA1_TASK_STACK_SIZE]; //ReadDATA1_TASK任务堆栈
extern OS_EVENT *MutualExclusionSemaphores_Event;
#endif
3、Start_Task.c文件
#include "Start_Task.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "My_Task_Priority.h"
#include "SaveDATA1_Task.h"
#include "ReadDATA1_Task.h"
void Start_Task(void *pdata);
const char Start_Task_rn_REG[]="\r\n";
const char Start_Task_Initialise_REG[]="Start_Task Initialise";
//Start_Task任务
void Start_Task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
u8 err;
pdata = pdata;
printf("%s",Start_Task_rn_REG);
printf("%s",Start_Task_Initialise_REG);
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断),需要定义cpu_sr变量
MutualExclusionSemaphores_Event=OSMutexCreate(MutualExclusionSemaphores_PRIO,&err);
//创建并初始化一个互斥信号量,用于使任务获得对共享资源的独占式访问权
// OSMutexPost(MutualExclusionSemaphores_Event);//释放一个互斥型信号量
OSTaskCreate( SaveDATA1_Task,/* 函数指针*/
(void *)0,/* 建立任务时,传递的参数*/
(OS_STK*)&SaveDATA1_TASK_STACK[SaveDATA1_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
SaveDATA1_TASK_PRIORITY/* 任务优先级*/
);
OSTaskCreate( ReadDATA1_Task,/* 函数指针*/
(void *)0,/* 建立任务时,传递的参数*/
(OS_STK*)&ReadDATA1_TASK_STACK[ReadDATA1_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
ReadDATA1_TASK_PRIORITY/* 任务优先级*/
);
//OSTaskSuspend(START_TASK_PRIO); //挂起起始任务Start_Task(),但不删除
OSTaskDel(OS_PRIO_SELF); //删除自己
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
4、SaveDATA1_Task.c文件
#include "SaveDATA1_Task.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "My_Task_Priority.h"
#include "AT24cxxDriver.h"
void SaveDATA1_Task(void *pdata);
const char SaveDATA1_Task_rn_REG[]="\r\n";
const char SaveDATA1_Task_Initialise_REG[]="SaveDATA1_Task Initialise";
const char WriteDATA1_REG[]="WriteDATA1=";
//SaveDATA1_Task任务
void SaveDATA1_Task(void *pdata)
{
u16 SaveDATA1_Cnt;
u8 err;
u8 DATA1;
printf("%s",SaveDATA1_Task_rn_REG);
printf("%s",SaveDATA1_Task_Initialise_REG);
while(1)
{
OSTimeDlyHMSM(0,0,0,1000);//延时1秒
SaveDATA1_Cnt++;
if(SaveDATA1_Cnt >60)//60秒时间到,则保存DATA1
{
OSMutexPend(MutualExclusionSemaphores_Event,0,&err);
//等待一个互斥型信号量,waits for a mutual exclusion semaphore.
EEPROM_U8_Data_Write(DATA1, DATA1_EEPROM_Address);
printf("%s",SaveDATA1_Task_rn_REG);
printf("%s",WriteDATA1_REG);
printf("%u",DATA1);
OSMutexPost(MutualExclusionSemaphores_Event);//释放一个互斥型信号量
SaveDATA1_Cnt =0;
}
}
}
5、ReadDATA1_Task.c文件
#include "ReadDATA1_Task.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "My_Task_Priority.h"
#include "AT24cxxDriver.h"
void ReadDATA1_Task(void *pdata);
const char ReadDATA1_Task_rn_REG[]="\r\n";
const char ReadDATA1_Task_Initialise_REG[]="ReadDATA1_Task Initialise";
const char ReadDATA1_REG[]="ReadDATA1=";
//ReadDATA1_Task任务
void ReadDATA1_Task(void *pdata)
{
u16 ReadDATA1_Cnt;
u8 err;
u8 DATA1;
printf("%s",ReadDATA1_Task_rn_REG);
printf("%s",ReadDATA1_Task_Initialise_REG);
while(1)
{
OSTimeDlyHMSM(0,0,0,1000);//延时1秒
ReadDATA1_Cnt++;
if(ReadDATA1_Cnt >60)//60小时时间到,读取DATA1
{
OSMutexPend(MutualExclusionSemaphores_Event,0,&err);
//等待一个互斥型信号量,waits for a mutual exclusion semaphore.
DATA1=EEPROM_U8_Data_Read1(DATA1_EEPROM_Address);
printf("%s",ReadDATA1_Task_rn_REG);
printf("%s",ReadDATA1_REG);
printf("%u",DATA1);
OSMutexPost(MutualExclusionSemaphores_Event);//释放一个互斥型信号量
ReadDATA1_Cnt =0;
}
}
}