目录
计数信号量
信号量就是一个带事件控制的计数器,在其上定义了三个操作:
- 可以被初始化一个非负数
- wait操作:若该值为0,则执行操作的任务等待;否则将计数值减1
- notify操作:将信号量的值增1后,若该值为非正,则执行操作的任务唤醒
设计原理
- 计数器负责计数控制
- 事件控制块用于控制任务等待与唤醒
设计实现
- 定义信号量(事件控制块、计数器、最大计数值)
- 初始化信号量
tSem.c
#include "tSem.h"
/* 信号量初始化函数 */
void tSemInit(tSem *sem, uint32_t startCount, uint32_t maxCount)
{
tEventInit(&sem->event, tEventTypeSem);//事件控制块初始化
sem->maxCount = maxCount;
if(maxCount == 0)//计数值没有限制
{
sem->count = startCount;
}
else
{
sem->count = (startCount > maxCount) ? maxCount : startCount;//检查参数有没有传递正确
}
}
tSem.h
#ifndef __TSEM_H
#define __TSEM_H
#include "tEvent.h"
typedef struct _tSem
{
tEvent event; //事件控制块
uint32_t count; //计数器
uint32_t maxCount; //最大计数值
}tSem;
void tSemInit(tSem *sem, uint32_t startCount, uint32_t maxCount);
#endif
tEvent.h
#ifndef __TEVENT_H
#define __TEVENT_H
#include "tTask.h"
/* 事件控制块类型 */
typedef enum _tEventType{
tEventTypeUnknow,
tEventTypeSem, //计数信号量
}tEventType;
/* 事件控制块 */
typedef struct _tEvent{
tEventType type; //事件控制块类型
tList waitList; //等待列表
}tEvent;
void tEventInit(tEvent *event, tEventType type);
void tEventWait(tEvent *event, tTask *task, void *msg, uint32_t state, uint32_t timeout);
tTask *tEventWakeUp(tEvent *event, void *msg, uint32_t result);
void tEventRemoveTask(tTask *task, void *msg, uint32_t result);
uint32_t tEventRemoveAll(tEvent *event, void *msg, uint32_t result);
uint32_t tEventWaitCount(tEvent *event);
#endif
tinyOS.h
#ifndef __TINYOS_H
#define __TINYOS_H
#include <stdint.h>
#include "tLib.h"
#include "tConfig.h"
#include "tTask.h"
#include "tEvent.h"
#include "tSem.h"
/* 错误码 */
typedef enum _tError{
tErrorNoError = 0, //没有错误发生
tErrorTimeout = 1, //超时
}tError;
extern tTask *currentTask;
extern tTask *nextTask;
uint32_t tTaskEnterCritical(void);
void tTaskExitCritical(uint32_t status);
void tTaskSwitch(void); //和CPU相关,写在switch.c
void tTaskRunFirst(void);
void tTaskSchedInit(void);
void tTaskSchedDisable(void);
void tTaskSchedEnable(void);
void tTaskSchedRdy(tTask *task);
void tTaskSchedUnRdy(tTask *task);
void tTaskSchedRemove(tTask *task);
void tTaskSched(void);
void tTimeTaskWait(tTask *task, uint32_t ticks);
void tTimeTaskWakeUp(tTask *task);
void tTimeTaskRemove(tTask *task);
void tTaskSystemTickHandler(void);
void tTaskDelay(uint32_t delay);
void tSetSysTickPeriod(uint32_t ms);
void tInitApp(void);
#endif
app.c
#include "tinyOS.h"
//定义任务,分别为它们配备独立的堆栈空间
tTask tTask1;
tTask tTask2;
tTask tTask3;
tTask tTask4;
tTaskStack task1Env[1024];
tTaskStack task2Env[1024];
tTaskStack task3Env[1024];
tTaskStack task4Env[1024];
tSem sem;
//定义任务要执行的功能
int task1Flag;
void task1Entry(void *param)
{
tSetSysTickPeriod(10);//初始化
tSemInit(&sem, 1, 10);
for(;;)//任务里是for的死循环
{
task1Flag = 0;
tTaskDelay(1);
task1Flag = 1;
tTaskDelay(1);
}
}
int task2Flag;
void task2Entry(void *param)
{
for(;;)
{
task2Flag = 0;
tTaskDelay(1);
task2Flag = 1;
tTaskDelay(1);
}
}
int task3Flag;
void task3Entry(void *param)
{
for(;;)
{
task3Flag = 0;
tTaskDelay(1);
task3Flag = 1;
tTaskDelay(1);
}
}
int task4Flag;
void task4Entry(void *param)
{
for(;;)
{
task4Flag = 0;
tTaskDelay(1);
task4Flag = 1;
tTaskDelay(1);
}
}
/* 应用任务初始化函数 */
void tInitApp(void)
{
//最后一个参数:传堆栈末端地址,因为堆栈是向下生长的,初始堆栈地址是堆栈空间最后一个单元地址的末端
tTaskInit(&tTask1, task1Entry, (void *)0x11111111, 0, &task1Env[1024]);
tTaskInit(&tTask2, task2Entry, (void *)0x22222222, 1, &task2Env[1024]);
tTaskInit(&tTask3, task3Entry, (void *)0x22222222, 1, &task3Env[1024]);
tTaskInit(&tTask4, task4Entry, (void *)0x22222222, 1, &task4Env[1024]);
}
标签:tTask,创建,void,信号量,计数,tEvent,include,uint32
From: https://blog.csdn.net/daybydayby/article/details/144472847