首页 > 其他分享 >事件控制块的清空与状态查询

事件控制块的清空与状态查询

时间:2024-12-14 19:29:06浏览次数:6  
标签:event task tTask void 查询 事件 清空 tEvent uint32

目录

事件控制块的清空

事件控制块的状态查询


事件控制块的清空

        将事件控制块中的所有任务从它的等待队列中移除,再将这些任务插入就绪队列。

事件控制块的状态查询

        仅需知道事件状态块中有多少个任务需要等待。

tEvent.c

#include "tinyOS.h"

/* 事件控制块初始化函数 */
void tEventInit(tEvent *event, tEventType type)
{
	event->type = tEventTypeUnknow;
	tListInit(&event->waitList);
}

/* 事件控制块等待函数 */
//参数:事件控制块,任务,消息(传入消息来源,在事件发生以后存放具体的消息),等待的状态,超时时间
void tEventWait(tEvent *event, tTask *task, void *msg, uint32_t state, uint32_t timeout)
{
	uint32_t status = tTaskEnterCritical();
		
	task->state |= state;
	task->waitEvent = event;
	task->eventMsg = msg;
	task->waitEventResult = tErrorNoError;
	
	tTaskSchedUnRdy(task);//移出就绪队列
	
	tListAddLast(&event->waitList, &task->linkNode);//插入事件控制块等待队列的尾部
	
	if(timeout)
	{
		tTimeTaskWait(task, timeout);//设置了超时事件,插入延时队列
	}
	
	tTaskExitCritical(status);
}


/* 事件控制块通知函数(将任务从事件控制块中唤醒) */
tTask *tEventWakeUp(tEvent *event, void *msg, uint32_t result)
{
	tNode *node;
	tTask *task = (tTask *)0;
	
	uint32_t status = tTaskEnterCritical();
		
	if((node = tListRemoveFirst(&event->waitList)) != (tNode *)0)
	{
		task = (tTask *)tNodeParent(node, tTask, linkNode);//插入到事件控制块是用linknode
		task->waitEvent = (tEvent *)0;//不等待任何事件
		task->eventMsg = msg;
		task->waitEventResult = result;
		task->state &= ~TINYOS_TASK_WAIT_MASK;
		
		if(task->delayTicks != 0)//有延时
		{
			tTimeTaskWakeUp(task);//强制将任务从延时队列中移除
		}
		tTaskSchedRdy(task);//插入就绪队列
	}
	
	tTaskExitCritical(status);
	
	return task;
}


/* 事件控制块移除函数 */
void tEventRemoveTask(tTask *task, void *msg, uint32_t result)
{
	uint32_t status = tTaskEnterCritical();
	
	tListRemove(&task->waitEvent->waitList, &task->linkNode);
	task->waitEvent = (tEvent *)0;
	task->eventMsg = msg;
	task->waitEventResult = result;
	task->state &= ~TINYOS_TASK_WAIT_MASK;

	tTaskExitCritical(status);
}

/* 事件控制块清空函数 */
//返回值:事件任务块被清空时,它的等待队列中有多少任务
uint32_t tEventRemoveAll(tEvent *event, void *msg, uint32_t result)
{
	tNode *node;
	uint32_t count = 0;
	
	uint32_t status = tTaskEnterCritical();
	
	count = tListCount(&event->waitList);//等待队列中有多少任务
	
	while((node = tListRemoveFirst(&event->waitList)) != (tNode *)0)//移除等待队列头部任务
	{
		tTask *task = (tTask *)tNodeParent(node, tTask, linkNode);//获取task结构
		task->waitEvent = (tEvent *)0;//不再等待事件
		task->eventMsg = msg;
		task->waitEventResult = result;
		task->state &= ~TINYOS_TASK_WAIT_MASK;
		
		if(task->delayTicks != 0)//任务有延时
		{
			tTimeTaskWakeUp(task);//移出延时队列
		}
		
		tTaskSchedRdy(task);
	}
	
	tTaskExitCritical(status);
	
	return count;
}

/* 获取事件控制块中等待任务函数 */
uint32_t tEventWaitCount(tEvent *event)
{
	uint32_t count = 0;
	
	uint32_t status = tTaskEnterCritical();
	
	count = tListCount(&event->waitList);
	
	tTaskExitCritical(status);
	
	return count;
}

tEvent.h

#ifndef __TEVENT_H
#define __TEVENT_H

#include "tTask.h"

/* 事件控制块类型 */
typedef enum _tEventType{
	tEventTypeUnknow,
}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

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];

//定义事件控制块
tEvent eventWaitTimeout;
tEvent eventWaitNormal;

//定义任务要执行的功能
int task1Flag;
void task1Entry(void *param)
{
	tSetSysTickPeriod(10);//初始化
	
	tEventInit(&eventWaitNormal, tEventTypeUnknow);
	
	for(;;)//任务里是for的死循环
	{
		uint32_t count = tEventWaitCount(&eventWaitNormal);
		uint32_t waskUpCount = tEventRemoveAll(&eventWaitNormal, (void *)0, 0);
		if(waskUpCount > 0)
		{
			tTaskSched();
			count = tEventWaitCount(&eventWaitNormal);
		}
		
		task1Flag = 0;
		tTaskDelay(1);
		task1Flag = 1;
		tTaskDelay(1);
	}
}

int task2Flag;
void task2Entry(void *param)
{
	for(;;)
	{
		tEventWait(&eventWaitNormal, currentTask, (void *)0, 0, 0);
		tTaskSched();
		
		task2Flag = 0;
		tTaskDelay(1);
		task2Flag = 1;
		tTaskDelay(1);
	}
}
int task3Flag;
void task3Entry(void *param)
{
	for(;;)
	{
		tEventWait(&eventWaitNormal, currentTask, (void *)0, 0, 0);
		tTaskSched();
		
		task3Flag = 0;
		tTaskDelay(1);
		task3Flag = 1;
		tTaskDelay(1);
	}
}
int task4Flag;
void task4Entry(void *param)
{
	for(;;)
	{
		tEventWait(&eventWaitNormal, currentTask, (void *)0, 0, 0);
		tTaskSched();
		
		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]);
}

标签:event,task,tTask,void,查询,事件,清空,tEvent,uint32
From: https://blog.csdn.net/daybydayby/article/details/144436125

相关文章

  • 数据库查询性能优化-正确使用索引避免全表扫描
    优化查询最重要的就是,尽量使语句符合查询优化器的规则避免全表扫描而使用索引查询。具体要注意的:1.应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描。如:selectidfromtwherenumisnull可以在num上设置默认值0,确保表中num列没......
  • MySQL Limit 分页查询优化
    前言在各类系统的表格类信息展示的功能中,经常会用到“翻页”这个操作,在页面上每次只展示有限的数据,需要看其他数据的时候则像翻书一样翻到后面的“页”。在MySQL支持的SQL语法中对此有特殊的支持,开发人员在实现这类功能的时候很方便:select*fromxxxlimitM,Nselect*f......
  • 统计所有地区的人员人数并排序,优化查询速度
    #背景:person_info表存放用户信息中有1千万数据,ID为主键,addr存放省份ID;addr_table表存放省份数据,有34条数据,ID为主键;#统计所有地区的人员人数selectad.name,count(pio.id)aspidfromaddr_tableadinnerjoinperson_infopioonad.id=pio.addrgroupbyad.nameor......
  • sql注入与联合查询基础
    sql注入在ctf中十分常见对与sql注入一般用一套相对稳定的注入流程:1.找到注入点2.测试闭合3.查询数据库的列数4.查询回显位5.查询库表名6.查询字段名7.查询数据通过以上流程,结合绕过测试,大多都可以成功!这里我们用一道题来详细讲一下: 这是NSSCTF的一道简单的注入题:......
  • 达梦DM.Microsoft.EntityFreameworkCore查询报错invalid cast from DateTime to DateT
    1.问题达梦dotnetefcore的驱动DM.Microsoft.EntityFreameworkCore。如果实体中存在DateTimeOffset类型字段时,查询报错:invalidcastfromDateTimetoDateTimeOffset。Invalidcastfrom'System.DateTime'to'System.DateTimeOffset'System.Convert.DefaultToType(Sy......
  • 【分布式】超低耦合,事件驱动架构是什么?
    文章目录1.概述2.事件的传递模式3.事件总线4.事件编排模式4.1调停者模式4.2管道和过滤器模式5.事件驱动的优缺点5.1优点5.2缺点1.概述事件驱动架构以Kubernetes为基础设施的云原生技术,彻底改变了我们的开发和思维模式。事件作为云原生领域......
  • Vue 3 中的 `update:modelValue` 事件详解
    在Vue3中,update:modelValue​事件通常与v-model​指令一起使用,以实现自定义组件的双向数据绑定。以下是对该事件的详细分析:事件定义首先,我们需要在组件中定义update:modelValue​事件。可以使用defineEmits​函数来声明组件可以发出的事件:constemit=defineEmits([......
  • Vue 3 中的 `update:modelValue` 事件详解
    在Vue3中,update:modelValue​事件通常与v-model​指令一起使用,以实现自定义组件的双向数据绑定。以下是对该事件的详细分析:事件定义首先,我们需要在组件中定义update:modelValue​事件。可以使用defineEmits​函数来声明组件可以发出的事件:constemit=defineEmits([......
  • 解释下点击一个input输入框,依次会触发哪些事件?
    在前端开发中,当用户点击一个<input>输入框时,会依次触发一系列事件。这些事件按照发生的顺序,通常包括以下几个阶段:mousedown:当用户按下鼠标按钮时触发。这是鼠标交互的起始事件,表明用户开始与元素进行交互。focus(可能紧接着mousedown或稍后,取决于浏览器和具体的实现):当......
  • HTML5拖拽事件的顺序是什么?
    HTML5拖拽事件的顺序取决于拖拽过程中的不同阶段,以及事件的目标元素。没有一个单一的、绝对的顺序,因为事件的触发取决于用户交互和页面元素的结构。但是,一个典型的拖拽流程中,事件发生的顺序大致如下:在源元素上(被拖拽的元素):dragstart:用户开始拖拽元素时触发。这是......