存储块的删除与状态查询

ops/2024/12/27 6:47:01/

目录

存储块的删除

设计实现


存储块的删除

仅需删除任务列表所有任务无需在意空闲存储块

设计实现

  • 存储块的删除(清空过程中可能有任务就绪,需执行一次调度)
  • 存储块的状态查询(当前存储块的计数、允许的最大计数、每个存储块的大小、当前等待的任务计数)

tMemBlock.c

#include "tinyOS.h"/* 存储块初始化函数 */
//参数:存储块,存储块分配空间的起始地址,存储块的大小,存储块的数量
void tMemBlockInit(tMemBlock *memBlock, uint8_t *memStart, uint32_t blockSize, uint32_t blockCnt)
{uint8_t *memBlockStart = (uint8_t *)memStart;									//存储空间的起始地址uint8_t *memBlockEnd = memBlockStart + blockSize * blockCnt;	//存储空间的结束地址//对存储空间进行划分时,划分的每一个存储块的大小会作为链表的结点插入链表中,这个链表结点会占用存储块开始的一部分空间,所以要求blockSize不能小于结点大小if(blockSize < sizeof(tNode)){return;}tEventInit(&memBlock->event, tEventTypeMemBlock);memBlock->memStart = memStart;memBlock->blockSize = blockSize;memBlock->maxCount = blockCnt;tListInit(&memBlock->blockList);//初始化存放存储块的链表//从存储区的起始地址,依次划分各个存储块while(memBlockStart < memBlockEnd)//从开始去找到尾部{tNodeInit((tNode *)memBlockStart);//对每一个存储块是要它最开始的存储区作为一个结点,进行初始化tListAddLast(&memBlock->blockList, (tNode *)memBlockStart);//将存储块加到存储块链表中memBlockStart += blockSize;//指针前移}
}/* 存储块获取函数 */
//参数:存储块,用于获取存储块时将存储块存入其中的指针,最大的等待计数
uint32_t tMemBlockWait(tMemBlock *memBlock, uint8_t **mem, uint32_t waitTicks)
{uint32_t status = tTaskEnterCritical();if(tListCount(&memBlock->blockList) > 0)//是否有空闲存储块{*mem = (uint8_t *)tListRemoveFirst(&memBlock->blockList);//从列表头部移出一个存储块tTaskExitCritical(status);return tErrorNoError;//返回没有错误}else{tEventWait(&memBlock->event, currentTask, (void *)0, tEventTypeMemBlock, waitTicks);//任务在事件控制块上等待tTaskExitCritical(status);tTaskSched();//切换到其他任务运行*mem = currentTask->eventMsg;//取出分配到的存储块return currentTask->waitEventResult;//返回等待结果}
}/* 存储块无等待获取函数 */
uint32_t tMemBlockWaitGet(tMemBlock *memBlock, void **mem)
{uint32_t status = tTaskEnterCritical();if(tListCount(&memBlock->blockList) > 0){*mem = (uint8_t *)tListRemoveFirst(&memBlock->blockList);tTaskExitCritical(status);return tErrorNoError;}else{tTaskExitCritical(status);return tErrorResourceUnavailable;//返回资源不可用}
}/* 存储块释放函数 */
void tMemBlockNotify(tMemBlock *memBlock, uint8_t *mem)
{uint32_t status = tTaskEnterCritical();if(tEventWaitCount(&memBlock->event) > 0)//是否有任务在事件控制块上等待{tTask *task = tEventWakeUp(&memBlock->event, (void *)mem, tErrorNoError);//移出一个任务if(task->prio < currentTask->prio)//判断优先级{tTaskSched();}}else{tListAddLast(&memBlock->blockList, (tNode *)mem);//将存储块插入空闲存储块列表}tTaskExitCritical(status);
}/* 存储块状态查询函数 */
void tMemBlockGetInfo(tMemBlock *memBlock, tMemBlockInfo *info)
{uint32_t status = tTaskEnterCritical();info->count = tListCount(&memBlock->blockList);info->maxCount = memBlock->maxCount;info->blockSize = memBlock->blockSize;info->taskCount = tEventWaitCount(&memBlock->event);tTaskExitCritical(status);
}/* 存储块删除函数 */
uint32_t tMemBlockDestroy(tMemBlock *memBlock)
{uint32_t status = tTaskEnterCritical();uint32_t count = tEventRemoveAll(&memBlock->event, (void *)0, tErrorDel);tTaskExitCritical(status);if(count > 0)//判断是否有任务就绪{tTaskSched();}return count;
}

tMemBlock.h

#ifndef __TMEMBOLCK_H
#define __TMEMBOLCK_H#include "tEvent.h"/* 存储块结构 */
typedef struct _tMemBlock
{tEvent event;				//事件控制块void *memStart;			//存储区的起始地址uint32_t blockSize;	//每个存储块的大小uint32_t maxCount;	//最大存储块数量tList blockList;		//存储块列表
}tMemBlock;/* 存储块状态查询结构 */
typedef struct _tMemBlockInfo
{uint32_t count;			//当前存储块的计数uint32_t maxCount;	//允许的最大计数uint32_t blockSize;	//每个存储块的大小uint32_t taskCount;	//当前等待的任务计数
}tMemBlockInfo;void tMemBlockInit(tMemBlock *memBlock, uint8_t *memStart, uint32_t blockSize, uint32_t blockCnt);
uint32_t tMemBlockWait(tMemBlock *memBlock, uint8_t **mem, uint32_t waitTicks);
uint32_t tMemBlockWaitGet(tMemBlock *memBlock, void **mem);
void tMemBlockNotify(tMemBlock *memBlock, uint8_t *mem);
void tMemBlockGetInfo(tMemBlock *memBlock, tMemBlockInfo *info);
uint32_t tMemBlockDestroy(tMemBlock *memBlock);#endif

app.c

#include "tinyOS.h"
#include "string.h"//定义任务,分别为它们配备独立的堆栈空间
tTask tTask1;
tTask tTask2;
tTask tTask3;
tTask tTask4;
tTaskStack task1Env[1024];
tTaskStack task2Env[1024];
tTaskStack task3Env[1024];
tTaskStack task4Env[1024];uint8_t mem1[20][100];//20个存储块,每个块是100字节
tMemBlock memBlock1;//定义任务要执行的功能
int task1Flag;
void task1Entry(void *param)
{uint8_t *mem;tMemBlockInfo info;tSetSysTickPeriod(10);//初始化tMemBlockInit(&memBlock1, (uint8_t *)mem1, 100, 20);tMemBlockGetInfo(&memBlock1, &info);for(int i = 0; i <20; i++){tMemBlockWait(&memBlock1, (uint8_t **)&mem, 0);}tMemBlockWait(&memBlock1, (uint8_t **)&mem, 0);for(;;)//任务里是for的死循环{task1Flag = 0; tTaskDelay(1);task1Flag = 1;tTaskDelay(1);}
}int task2Flag;
void task2Entry(void *param)
{int destroy = 0;for(;;){task2Flag = 0;tTaskDelay(1);task2Flag = 1;tTaskDelay(1);if(!destroy){tMemBlockDestroy(&memBlock1);destroy = 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]);
}


http://www.ppmy.cn/ops/145306.html

相关文章

报表工具DevExpress Reporting v24.2亮点 - AI功能进一步强化

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 报表工具DevExpress Reporting v24.2将于近期发…

基于矩阵乘积态的生成模型:量子力学与生成任务的结合

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月23日11点02分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 文章源链接(有视频)&#xff1a;Aspir…

【Select 语法全解密】.NET开源ORM框架 SqlSugar 系列

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录前言一、Select 执行位置二、返回一个字段和多个字段三、单表返回DTO四、多表返回DTO4.1 手动DTO4.2 实体自动映射14.…

【Golang 面试题】每日 3 题(五)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

mac远程控制另一台mac怎么操作?

远程协助是指通过网络从一台电脑远程控制另一台电脑&#xff0c;从而提供远程帮助。比如&#xff0c;当父母的电脑遇到了一些问题&#xff0c;就可以通过远程协助进行解决。那么&#xff0c;如何实现对Mac电脑的远程控制呢&#xff1f; 要远程控制Mac电脑屏幕&#xff0c;可以…

Docker下sward安装配置指南

sward是一个开源免费企业级知识库管理软件&#xff0c;我们在上篇文章简单介绍过它的功能与优势&#xff0c;今天来介绍一下怎么安装私有部署版本。 1. 安装 点击官网 -> 演示与下载 ->下载&#xff0c;&#xfeff;下载Docket安装包&#xff0c; 安装包名字为tiklab-sw…

Bash 脚本教程

注&#xff1a;本文为 “Bash 脚本编写” 相关文章合辑。 BASH 脚本编写教程 as good as well于 2017-08-04 22:04:28 发布 这里有个老 American 写的 BASH 脚本编写教程&#xff0c;非常不错&#xff0c;至少没接触过 BASH 的也能看懂&#xff01; 建立一个脚本 Linux 中有…

青少年科普教学系统平台的设计与实现springboot

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对高校教师成果信息管理混乱&#xff0c;出错率高&#xff0c;信息安…