邝坚北邮嵌入式实验报告.docx
《邝坚北邮嵌入式实验报告.docx》由会员分享,可在线阅读,更多相关《邝坚北邮嵌入式实验报告.docx(17页珍藏版)》请在冰点文库上搜索。
邝坚北邮嵌入式实验报告
嵌入式系统期末实验
一、实验要求
题目:
支持消息驱动模式的实时软件框架
目的:
在充分理解嵌入式处理器特点、RTOS及强实时嵌入式系统软件设计规范的基础上,构建自己的实时系统软件框架基本功能,并在其上自拟应用(如部分模拟TCP的C/S两端通信流程),测试软件框架的相关功能。
环境:
VxWorks的VxSim仿真环境或2440(ARM920T)
内容:
必选功能:
1.消息驱动的Task统一框架,包含统一消息格式定义及使用规范;
2.支持消息驱动模式的软定时器的机制;
3.Task启动同步功能;
4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。
可选功能(加分):
其它有利于实时处理的有效机制,如:
无信号量(互斥)支持的临界资源访问方式,zerocopy等;
二、实现的功能
STATUSTask()
{
Initialization(MBox,DataStructure,Timer,etc.)
Forever{
MsgReceive
If(…)
……
}elseif(…)
}
typedefstruct_MESSAGE
intmType;/*消息类型0:
timer->client
*1:
client->server2:
server->client*/
intmSendId;/*发送任务的MESSAGEID*/
intmRecvId;/*接收任务的MESSAGEID*/
intmData;/*消息中传递的数据*/
}MESSAGE;
/*timer(id)向客户端消息队列定时发送的定时器*/
STATUStimer(intid)
MESSAGE*txMsg;/*用于从消息队列中接收消息*/
inttick;/*创建一个定时,用于提醒发送者任务定时发送消息*/
tick=sysClkRateGet();
semTake(semSynStart,WAIT_FOREVER);
FOREVER
taskDelay((int)(tick*DELAY_SECOND));
txMsg=(MESSAGE*)memMalloc(MAX_MSG_LEN);
txMsg->mType=0;
txMsg->mSendId=MID_TIMER(id);
txMsg->mRecvId=MID_CLIENT(id);
txMsg->mData=0;
printf("tTimer%dsendmessagetotClient%d!
\n",id,id);
if(msgQSend(msgQIdClient[id],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL)==ERROR)
return(ERROR);
return(OK);
由manager()创建的任务优先级最高,先创建timer()、server()、client()的任务,让他们都在等待信号量semSynStart而被阻塞,最后创建manager()的任务,占据CPU,等待其他所有任务都被阻塞,解锁所有等待信号量的任务,让它们同时启动。
/*progStart()启动实例程序*/
STATUSprogStart(void)
intid;/*用来区分不同的定时器或者客户任务*/
mallocPtr=&sysMalloc;
mallocPtr->frontBlock=0;
initialPtr=initial();
tidServer=tidManager=0;
for(id=0;id{tidClient[id]=0;}for(id=0;id{tidTimer[id]=0;}/*创建消息队列*/msgQIdServer=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);if(msgQIdServer==NULL){return(ERROR);}for(id=0;id{msgQIdClient[id]=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);if(msgQIdClient[id]==NULL){return(ERROR);}}semSynStart=semBCreate(SEM_Q_FIFO|SEM_EVENTSEND_ERR_NOTIFY,SEM_EMPTY);semMalloc=semBCreate(SEM_Q_PRIORITY,SEM_FULL);semFree=semBCreate(SEM_Q_PRIORITY,SEM_FULL);/*创建任务*/tidServer=taskSpawn("tServer",220,0,STACK_SIZE,(FUNCPTR)server,0,0,0,0,0,0,0,0,0,0);for(id=0;id{chartempName[20];sprintf(tempName,"tClient%d",id);tidClient[id]=taskSpawn(tempName,210,0,STACK_SIZE,(FUNCPTR)client,id,0,0,0,0,0,0,0,0,0);}for(id=0;id{chartempName[20];sprintf(tempName,"tTimer%d",id);tidTimer[id]=taskSpawn(tempName,230,0,STACK_SIZE,(FUNCPTR)timer,id,0,0,0,0,0,0,0,0,0);}tidManager=taskSpawn("tMannager",200,0,STACK_SIZE,(FUNCPTR)manager,0,0,0,0,0,0,0,0,0,0);printf("programestart!\n");return(OK);}/*manager()管理进程,实现task同步*/STATUSmanager(){intid;while(taskIsSuspended(tidServer)||taskIsReady(tidServer))taskDelay(10);for(id=0;id{while(taskIsSuspended(tidClient[id])||taskIsReady(tidClient[id]))taskDelay(10);}for(id=0;id{while(taskIsSuspended(tidTimer[id])||taskIsReady(tidTimer[id]))taskDelay(10);}semFlush(semSynStart);return(OK);}/*server()处理来自各个客户任务的消息*/STATUSserver(void){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*timer(id)向客户端定时发送的定时器*/STATUStimer(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*client(id)向服务器任务发请求消息*/STATUSclient(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。/*initial()初始化内存池*/pool*initial(void){inti;pool*mem;pool*poolPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*//*初始化pool*/poolPtr=(pool*)mem;poolPtr->poolNum=2;poolPtr->pool=(poolHead*)((char*)mem+sizeof(pool));/*pool指向申请内存区尾*//*初始化pool1该内存池分配大小为16B的内存*/poolHeadPtr=(poolHead*)((char*)mem+sizeof(pool));/*初始化内存池的首位置*/poolHeadPtr->available=32;/*初始化可用块数32*/poolHeadPtr->blockSize=16;/*块大小16B*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));/*初始化块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*初始化第一块可用块的位置*/poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr+sizeof(poolHeadPtr)+32*(sizeof(blockHead)+16));/*next指向第二个内存池*/blockHeadPtr->poolId=1;blockHeadPtr->frontBlock=0;for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/blockHeadPtr->poolId=1;/*pool号为1,表示他是16B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*当前首个可用块位置赋给frontBlock*/poolHeadPtr->firstavailable=blockHeadPtr;/*求下一首个可用块位置*/}/*初始化pool2该内存池分配大小为256B的内存*/poolHeadPtr=poolHeadPtr->next;poolHeadPtr->available=16;/*初始化可用块数16*/poolHeadPtr->blockSize=256;/*块大小256*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));poolHeadPtr->firstavailable=blockHeadPtr;poolHeadPtr->next=0;blockHeadPtr->poolId=2;blockHeadPtr->frontBlock=0;for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+256));blockHeadPtr->poolId=2;/*pool号为2,表示他是256B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;poolHeadPtr->firstavailable=blockHeadPtr;}return(pool*)mem;} /*memMalloc()分配内存*/void*memMalloc(intSize){void*mem;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semMalloc,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;if((Size<=16)&&(poolHeadPtr->available!=0))/*长度小于16时,分配长度为16的内存空间*/{blockHeadPtr=poolHeadPtr->firstavailable;/*首个可用块位置赋给分配块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr->frontBlock;/*改变下一第一可用块的位置*/poolHeadPtr->available--;/*可用块数减一*/semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));/*分配内存时加入块头开销*/}elseif((Size<=256)&&((poolHeadPtr->next)->available!=0))/*长度大于16小于256时,分配长度为256的内存空间*/{blockHeadPtr=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr->frontBlock;(poolHeadPtr->next)->available--;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}else/*其他情况用系统的内存分配函数malloc分配*/{printf("\n[Warning]:Toolargeforblocksortheblocksareexhausted\n");mem=malloc(Size);/*采用系统函数malloc()分配内存*/blockHeadPtr=(blockHead*)mem;blockHeadPtr->poolId=(initialPtr->poolNum+1);blockHeadPtr->frontBlock=mallocPtr;mallocPtr=blockHeadPtr;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}}/*memFree()释放内存空间*/voidmemFree(void*dataPtr){char*mem=(char*)dataPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semFree,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;/*恢复内存池首址*/blockHeadPtr=(blockHead*)((char*)mem-sizeof(blockHead));/*恢复内存块首址*/if(blockHeadPtr->poolId==1)/*释放16B的内存块*/{blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*恢复frontBlock位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*恢复第一可用块位置*/poolHeadPtr->available++;/*恢复可用块数*/}elseif(blockHeadPtr->poolId==2)/*释放256B的内存块*/{blockHeadPtr->frontBlock=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr;(poolHeadPtr->next)->available++;}else/*释放由系统分配的内存块*/{blockHeadPtr=mallocPtr;mallocPtr=blockHeadPtr->frontBlock;free((char*)mem-sizeof(blockHead));}semGive(semFree);return;}/*memDel()删除内存块*/voidmemDel(void){void*mem;blockHead*blockHeadPtr;mem=(void*)(initialPtr);free(mem);while(mallocPtr->frontBlock!=0){mem=(void*)(mallocPtr);free(mem);mallocPtr=mallocPtr->frontBlock;}semDelete(semMalloc);/*删除信号量*/semDelete(semFree);}5.无信号量(互斥)支持的临界资源访问方式有一个server任务,有10个client任务,10个client任务定时给server的消息队列发送消息,server任务接收到消息后,发送ACK消息到client的消息队列,如图:6.zerocopy消息队列存储的是指向消息的指针,从而实现了零拷贝。#defineMAX_MSG_LENsizeof(MESSAGE*)MESSAGE*rxMsg;/*用于从消息队列中接收消息*/MESSAGE*txMsg;/*用于向消息队列中发送消息*/msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);三、运行结果在shell中输入progStart,观察VxSim,输入progStop结束。四、心得实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。由于正值期末,考试任务繁重,时间紧迫,自身水平有限,难免会有疏漏,请老师指正。[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]
tidClient[id]=0;
for(id=0;id{tidTimer[id]=0;}/*创建消息队列*/msgQIdServer=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);if(msgQIdServer==NULL){return(ERROR);}for(id=0;id{msgQIdClient[id]=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);if(msgQIdClient[id]==NULL){return(ERROR);}}semSynStart=semBCreate(SEM_Q_FIFO|SEM_EVENTSEND_ERR_NOTIFY,SEM_EMPTY);semMalloc=semBCreate(SEM_Q_PRIORITY,SEM_FULL);semFree=semBCreate(SEM_Q_PRIORITY,SEM_FULL);/*创建任务*/tidServer=taskSpawn("tServer",220,0,STACK_SIZE,(FUNCPTR)server,0,0,0,0,0,0,0,0,0,0);for(id=0;id{chartempName[20];sprintf(tempName,"tClient%d",id);tidClient[id]=taskSpawn(tempName,210,0,STACK_SIZE,(FUNCPTR)client,id,0,0,0,0,0,0,0,0,0);}for(id=0;id{chartempName[20];sprintf(tempName,"tTimer%d",id);tidTimer[id]=taskSpawn(tempName,230,0,STACK_SIZE,(FUNCPTR)timer,id,0,0,0,0,0,0,0,0,0);}tidManager=taskSpawn("tMannager",200,0,STACK_SIZE,(FUNCPTR)manager,0,0,0,0,0,0,0,0,0,0);printf("programestart!\n");return(OK);}/*manager()管理进程,实现task同步*/STATUSmanager(){intid;while(taskIsSuspended(tidServer)||taskIsReady(tidServer))taskDelay(10);for(id=0;id{while(taskIsSuspended(tidClient[id])||taskIsReady(tidClient[id]))taskDelay(10);}for(id=0;id{while(taskIsSuspended(tidTimer[id])||taskIsReady(tidTimer[id]))taskDelay(10);}semFlush(semSynStart);return(OK);}/*server()处理来自各个客户任务的消息*/STATUSserver(void){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*timer(id)向客户端定时发送的定时器*/STATUStimer(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*client(id)向服务器任务发请求消息*/STATUSclient(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。/*initial()初始化内存池*/pool*initial(void){inti;pool*mem;pool*poolPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*//*初始化pool*/poolPtr=(pool*)mem;poolPtr->poolNum=2;poolPtr->pool=(poolHead*)((char*)mem+sizeof(pool));/*pool指向申请内存区尾*//*初始化pool1该内存池分配大小为16B的内存*/poolHeadPtr=(poolHead*)((char*)mem+sizeof(pool));/*初始化内存池的首位置*/poolHeadPtr->available=32;/*初始化可用块数32*/poolHeadPtr->blockSize=16;/*块大小16B*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));/*初始化块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*初始化第一块可用块的位置*/poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr+sizeof(poolHeadPtr)+32*(sizeof(blockHead)+16));/*next指向第二个内存池*/blockHeadPtr->poolId=1;blockHeadPtr->frontBlock=0;for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/blockHeadPtr->poolId=1;/*pool号为1,表示他是16B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*当前首个可用块位置赋给frontBlock*/poolHeadPtr->firstavailable=blockHeadPtr;/*求下一首个可用块位置*/}/*初始化pool2该内存池分配大小为256B的内存*/poolHeadPtr=poolHeadPtr->next;poolHeadPtr->available=16;/*初始化可用块数16*/poolHeadPtr->blockSize=256;/*块大小256*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));poolHeadPtr->firstavailable=blockHeadPtr;poolHeadPtr->next=0;blockHeadPtr->poolId=2;blockHeadPtr->frontBlock=0;for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+256));blockHeadPtr->poolId=2;/*pool号为2,表示他是256B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;poolHeadPtr->firstavailable=blockHeadPtr;}return(pool*)mem;} /*memMalloc()分配内存*/void*memMalloc(intSize){void*mem;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semMalloc,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;if((Size<=16)&&(poolHeadPtr->available!=0))/*长度小于16时,分配长度为16的内存空间*/{blockHeadPtr=poolHeadPtr->firstavailable;/*首个可用块位置赋给分配块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr->frontBlock;/*改变下一第一可用块的位置*/poolHeadPtr->available--;/*可用块数减一*/semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));/*分配内存时加入块头开销*/}elseif((Size<=256)&&((poolHeadPtr->next)->available!=0))/*长度大于16小于256时,分配长度为256的内存空间*/{blockHeadPtr=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr->frontBlock;(poolHeadPtr->next)->available--;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}else/*其他情况用系统的内存分配函数malloc分配*/{printf("\n[Warning]:Toolargeforblocksortheblocksareexhausted\n");mem=malloc(Size);/*采用系统函数malloc()分配内存*/blockHeadPtr=(blockHead*)mem;blockHeadPtr->poolId=(initialPtr->poolNum+1);blockHeadPtr->frontBlock=mallocPtr;mallocPtr=blockHeadPtr;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}}/*memFree()释放内存空间*/voidmemFree(void*dataPtr){char*mem=(char*)dataPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semFree,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;/*恢复内存池首址*/blockHeadPtr=(blockHead*)((char*)mem-sizeof(blockHead));/*恢复内存块首址*/if(blockHeadPtr->poolId==1)/*释放16B的内存块*/{blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*恢复frontBlock位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*恢复第一可用块位置*/poolHeadPtr->available++;/*恢复可用块数*/}elseif(blockHeadPtr->poolId==2)/*释放256B的内存块*/{blockHeadPtr->frontBlock=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr;(poolHeadPtr->next)->available++;}else/*释放由系统分配的内存块*/{blockHeadPtr=mallocPtr;mallocPtr=blockHeadPtr->frontBlock;free((char*)mem-sizeof(blockHead));}semGive(semFree);return;}/*memDel()删除内存块*/voidmemDel(void){void*mem;blockHead*blockHeadPtr;mem=(void*)(initialPtr);free(mem);while(mallocPtr->frontBlock!=0){mem=(void*)(mallocPtr);free(mem);mallocPtr=mallocPtr->frontBlock;}semDelete(semMalloc);/*删除信号量*/semDelete(semFree);}5.无信号量(互斥)支持的临界资源访问方式有一个server任务,有10个client任务,10个client任务定时给server的消息队列发送消息,server任务接收到消息后,发送ACK消息到client的消息队列,如图:6.zerocopy消息队列存储的是指向消息的指针,从而实现了零拷贝。#defineMAX_MSG_LENsizeof(MESSAGE*)MESSAGE*rxMsg;/*用于从消息队列中接收消息*/MESSAGE*txMsg;/*用于向消息队列中发送消息*/msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);三、运行结果在shell中输入progStart,观察VxSim,输入progStop结束。四、心得实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。由于正值期末,考试任务繁重,时间紧迫,自身水平有限,难免会有疏漏,请老师指正。[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]
tidTimer[id]=0;
/*创建消息队列*/
msgQIdServer=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);
if(msgQIdServer==NULL)
for(id=0;id{msgQIdClient[id]=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);if(msgQIdClient[id]==NULL){return(ERROR);}}semSynStart=semBCreate(SEM_Q_FIFO|SEM_EVENTSEND_ERR_NOTIFY,SEM_EMPTY);semMalloc=semBCreate(SEM_Q_PRIORITY,SEM_FULL);semFree=semBCreate(SEM_Q_PRIORITY,SEM_FULL);/*创建任务*/tidServer=taskSpawn("tServer",220,0,STACK_SIZE,(FUNCPTR)server,0,0,0,0,0,0,0,0,0,0);for(id=0;id{chartempName[20];sprintf(tempName,"tClient%d",id);tidClient[id]=taskSpawn(tempName,210,0,STACK_SIZE,(FUNCPTR)client,id,0,0,0,0,0,0,0,0,0);}for(id=0;id{chartempName[20];sprintf(tempName,"tTimer%d",id);tidTimer[id]=taskSpawn(tempName,230,0,STACK_SIZE,(FUNCPTR)timer,id,0,0,0,0,0,0,0,0,0);}tidManager=taskSpawn("tMannager",200,0,STACK_SIZE,(FUNCPTR)manager,0,0,0,0,0,0,0,0,0,0);printf("programestart!\n");return(OK);}/*manager()管理进程,实现task同步*/STATUSmanager(){intid;while(taskIsSuspended(tidServer)||taskIsReady(tidServer))taskDelay(10);for(id=0;id{while(taskIsSuspended(tidClient[id])||taskIsReady(tidClient[id]))taskDelay(10);}for(id=0;id{while(taskIsSuspended(tidTimer[id])||taskIsReady(tidTimer[id]))taskDelay(10);}semFlush(semSynStart);return(OK);}/*server()处理来自各个客户任务的消息*/STATUSserver(void){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*timer(id)向客户端定时发送的定时器*/STATUStimer(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*client(id)向服务器任务发请求消息*/STATUSclient(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。/*initial()初始化内存池*/pool*initial(void){inti;pool*mem;pool*poolPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*//*初始化pool*/poolPtr=(pool*)mem;poolPtr->poolNum=2;poolPtr->pool=(poolHead*)((char*)mem+sizeof(pool));/*pool指向申请内存区尾*//*初始化pool1该内存池分配大小为16B的内存*/poolHeadPtr=(poolHead*)((char*)mem+sizeof(pool));/*初始化内存池的首位置*/poolHeadPtr->available=32;/*初始化可用块数32*/poolHeadPtr->blockSize=16;/*块大小16B*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));/*初始化块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*初始化第一块可用块的位置*/poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr+sizeof(poolHeadPtr)+32*(sizeof(blockHead)+16));/*next指向第二个内存池*/blockHeadPtr->poolId=1;blockHeadPtr->frontBlock=0;for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/blockHeadPtr->poolId=1;/*pool号为1,表示他是16B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*当前首个可用块位置赋给frontBlock*/poolHeadPtr->firstavailable=blockHeadPtr;/*求下一首个可用块位置*/}/*初始化pool2该内存池分配大小为256B的内存*/poolHeadPtr=poolHeadPtr->next;poolHeadPtr->available=16;/*初始化可用块数16*/poolHeadPtr->blockSize=256;/*块大小256*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));poolHeadPtr->firstavailable=blockHeadPtr;poolHeadPtr->next=0;blockHeadPtr->poolId=2;blockHeadPtr->frontBlock=0;for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+256));blockHeadPtr->poolId=2;/*pool号为2,表示他是256B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;poolHeadPtr->firstavailable=blockHeadPtr;}return(pool*)mem;} /*memMalloc()分配内存*/void*memMalloc(intSize){void*mem;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semMalloc,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;if((Size<=16)&&(poolHeadPtr->available!=0))/*长度小于16时,分配长度为16的内存空间*/{blockHeadPtr=poolHeadPtr->firstavailable;/*首个可用块位置赋给分配块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr->frontBlock;/*改变下一第一可用块的位置*/poolHeadPtr->available--;/*可用块数减一*/semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));/*分配内存时加入块头开销*/}elseif((Size<=256)&&((poolHeadPtr->next)->available!=0))/*长度大于16小于256时,分配长度为256的内存空间*/{blockHeadPtr=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr->frontBlock;(poolHeadPtr->next)->available--;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}else/*其他情况用系统的内存分配函数malloc分配*/{printf("\n[Warning]:Toolargeforblocksortheblocksareexhausted\n");mem=malloc(Size);/*采用系统函数malloc()分配内存*/blockHeadPtr=(blockHead*)mem;blockHeadPtr->poolId=(initialPtr->poolNum+1);blockHeadPtr->frontBlock=mallocPtr;mallocPtr=blockHeadPtr;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}}/*memFree()释放内存空间*/voidmemFree(void*dataPtr){char*mem=(char*)dataPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semFree,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;/*恢复内存池首址*/blockHeadPtr=(blockHead*)((char*)mem-sizeof(blockHead));/*恢复内存块首址*/if(blockHeadPtr->poolId==1)/*释放16B的内存块*/{blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*恢复frontBlock位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*恢复第一可用块位置*/poolHeadPtr->available++;/*恢复可用块数*/}elseif(blockHeadPtr->poolId==2)/*释放256B的内存块*/{blockHeadPtr->frontBlock=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr;(poolHeadPtr->next)->available++;}else/*释放由系统分配的内存块*/{blockHeadPtr=mallocPtr;mallocPtr=blockHeadPtr->frontBlock;free((char*)mem-sizeof(blockHead));}semGive(semFree);return;}/*memDel()删除内存块*/voidmemDel(void){void*mem;blockHead*blockHeadPtr;mem=(void*)(initialPtr);free(mem);while(mallocPtr->frontBlock!=0){mem=(void*)(mallocPtr);free(mem);mallocPtr=mallocPtr->frontBlock;}semDelete(semMalloc);/*删除信号量*/semDelete(semFree);}5.无信号量(互斥)支持的临界资源访问方式有一个server任务,有10个client任务,10个client任务定时给server的消息队列发送消息,server任务接收到消息后,发送ACK消息到client的消息队列,如图:6.zerocopy消息队列存储的是指向消息的指针,从而实现了零拷贝。#defineMAX_MSG_LENsizeof(MESSAGE*)MESSAGE*rxMsg;/*用于从消息队列中接收消息*/MESSAGE*txMsg;/*用于向消息队列中发送消息*/msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);三、运行结果在shell中输入progStart,观察VxSim,输入progStop结束。四、心得实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。由于正值期末,考试任务繁重,时间紧迫,自身水平有限,难免会有疏漏,请老师指正。[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]
msgQIdClient[id]=msgQCreate(MAX_MSGS,MAX_MSG_LEN,MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);
if(msgQIdClient[id]==NULL)
semSynStart=semBCreate(SEM_Q_FIFO|SEM_EVENTSEND_ERR_NOTIFY,SEM_EMPTY);
semMalloc=semBCreate(SEM_Q_PRIORITY,SEM_FULL);
semFree=semBCreate(SEM_Q_PRIORITY,SEM_FULL);
/*创建任务*/
tidServer=taskSpawn("tServer",220,0,STACK_SIZE,(FUNCPTR)server,0,0,0,0,0,0,0,0,0,0);
for(id=0;id{chartempName[20];sprintf(tempName,"tClient%d",id);tidClient[id]=taskSpawn(tempName,210,0,STACK_SIZE,(FUNCPTR)client,id,0,0,0,0,0,0,0,0,0);}for(id=0;id{chartempName[20];sprintf(tempName,"tTimer%d",id);tidTimer[id]=taskSpawn(tempName,230,0,STACK_SIZE,(FUNCPTR)timer,id,0,0,0,0,0,0,0,0,0);}tidManager=taskSpawn("tMannager",200,0,STACK_SIZE,(FUNCPTR)manager,0,0,0,0,0,0,0,0,0,0);printf("programestart!\n");return(OK);}/*manager()管理进程,实现task同步*/STATUSmanager(){intid;while(taskIsSuspended(tidServer)||taskIsReady(tidServer))taskDelay(10);for(id=0;id{while(taskIsSuspended(tidClient[id])||taskIsReady(tidClient[id]))taskDelay(10);}for(id=0;id{while(taskIsSuspended(tidTimer[id])||taskIsReady(tidTimer[id]))taskDelay(10);}semFlush(semSynStart);return(OK);}/*server()处理来自各个客户任务的消息*/STATUSserver(void){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*timer(id)向客户端定时发送的定时器*/STATUStimer(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*client(id)向服务器任务发请求消息*/STATUSclient(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。/*initial()初始化内存池*/pool*initial(void){inti;pool*mem;pool*poolPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*//*初始化pool*/poolPtr=(pool*)mem;poolPtr->poolNum=2;poolPtr->pool=(poolHead*)((char*)mem+sizeof(pool));/*pool指向申请内存区尾*//*初始化pool1该内存池分配大小为16B的内存*/poolHeadPtr=(poolHead*)((char*)mem+sizeof(pool));/*初始化内存池的首位置*/poolHeadPtr->available=32;/*初始化可用块数32*/poolHeadPtr->blockSize=16;/*块大小16B*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));/*初始化块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*初始化第一块可用块的位置*/poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr+sizeof(poolHeadPtr)+32*(sizeof(blockHead)+16));/*next指向第二个内存池*/blockHeadPtr->poolId=1;blockHeadPtr->frontBlock=0;for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/blockHeadPtr->poolId=1;/*pool号为1,表示他是16B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*当前首个可用块位置赋给frontBlock*/poolHeadPtr->firstavailable=blockHeadPtr;/*求下一首个可用块位置*/}/*初始化pool2该内存池分配大小为256B的内存*/poolHeadPtr=poolHeadPtr->next;poolHeadPtr->available=16;/*初始化可用块数16*/poolHeadPtr->blockSize=256;/*块大小256*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));poolHeadPtr->firstavailable=blockHeadPtr;poolHeadPtr->next=0;blockHeadPtr->poolId=2;blockHeadPtr->frontBlock=0;for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+256));blockHeadPtr->poolId=2;/*pool号为2,表示他是256B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;poolHeadPtr->firstavailable=blockHeadPtr;}return(pool*)mem;} /*memMalloc()分配内存*/void*memMalloc(intSize){void*mem;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semMalloc,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;if((Size<=16)&&(poolHeadPtr->available!=0))/*长度小于16时,分配长度为16的内存空间*/{blockHeadPtr=poolHeadPtr->firstavailable;/*首个可用块位置赋给分配块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr->frontBlock;/*改变下一第一可用块的位置*/poolHeadPtr->available--;/*可用块数减一*/semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));/*分配内存时加入块头开销*/}elseif((Size<=256)&&((poolHeadPtr->next)->available!=0))/*长度大于16小于256时,分配长度为256的内存空间*/{blockHeadPtr=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr->frontBlock;(poolHeadPtr->next)->available--;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}else/*其他情况用系统的内存分配函数malloc分配*/{printf("\n[Warning]:Toolargeforblocksortheblocksareexhausted\n");mem=malloc(Size);/*采用系统函数malloc()分配内存*/blockHeadPtr=(blockHead*)mem;blockHeadPtr->poolId=(initialPtr->poolNum+1);blockHeadPtr->frontBlock=mallocPtr;mallocPtr=blockHeadPtr;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}}/*memFree()释放内存空间*/voidmemFree(void*dataPtr){char*mem=(char*)dataPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semFree,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;/*恢复内存池首址*/blockHeadPtr=(blockHead*)((char*)mem-sizeof(blockHead));/*恢复内存块首址*/if(blockHeadPtr->poolId==1)/*释放16B的内存块*/{blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*恢复frontBlock位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*恢复第一可用块位置*/poolHeadPtr->available++;/*恢复可用块数*/}elseif(blockHeadPtr->poolId==2)/*释放256B的内存块*/{blockHeadPtr->frontBlock=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr;(poolHeadPtr->next)->available++;}else/*释放由系统分配的内存块*/{blockHeadPtr=mallocPtr;mallocPtr=blockHeadPtr->frontBlock;free((char*)mem-sizeof(blockHead));}semGive(semFree);return;}/*memDel()删除内存块*/voidmemDel(void){void*mem;blockHead*blockHeadPtr;mem=(void*)(initialPtr);free(mem);while(mallocPtr->frontBlock!=0){mem=(void*)(mallocPtr);free(mem);mallocPtr=mallocPtr->frontBlock;}semDelete(semMalloc);/*删除信号量*/semDelete(semFree);}5.无信号量(互斥)支持的临界资源访问方式有一个server任务,有10个client任务,10个client任务定时给server的消息队列发送消息,server任务接收到消息后,发送ACK消息到client的消息队列,如图:6.zerocopy消息队列存储的是指向消息的指针,从而实现了零拷贝。#defineMAX_MSG_LENsizeof(MESSAGE*)MESSAGE*rxMsg;/*用于从消息队列中接收消息*/MESSAGE*txMsg;/*用于向消息队列中发送消息*/msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);三、运行结果在shell中输入progStart,观察VxSim,输入progStop结束。四、心得实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。由于正值期末,考试任务繁重,时间紧迫,自身水平有限,难免会有疏漏,请老师指正。[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]
chartempName[20];
sprintf(tempName,"tClient%d",id);
tidClient[id]=taskSpawn(tempName,210,0,STACK_SIZE,(FUNCPTR)client,id,0,0,0,0,0,0,0,0,0);
for(id=0;id{chartempName[20];sprintf(tempName,"tTimer%d",id);tidTimer[id]=taskSpawn(tempName,230,0,STACK_SIZE,(FUNCPTR)timer,id,0,0,0,0,0,0,0,0,0);}tidManager=taskSpawn("tMannager",200,0,STACK_SIZE,(FUNCPTR)manager,0,0,0,0,0,0,0,0,0,0);printf("programestart!\n");return(OK);}/*manager()管理进程,实现task同步*/STATUSmanager(){intid;while(taskIsSuspended(tidServer)||taskIsReady(tidServer))taskDelay(10);for(id=0;id{while(taskIsSuspended(tidClient[id])||taskIsReady(tidClient[id]))taskDelay(10);}for(id=0;id{while(taskIsSuspended(tidTimer[id])||taskIsReady(tidTimer[id]))taskDelay(10);}semFlush(semSynStart);return(OK);}/*server()处理来自各个客户任务的消息*/STATUSserver(void){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*timer(id)向客户端定时发送的定时器*/STATUStimer(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*client(id)向服务器任务发请求消息*/STATUSclient(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。/*initial()初始化内存池*/pool*initial(void){inti;pool*mem;pool*poolPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*//*初始化pool*/poolPtr=(pool*)mem;poolPtr->poolNum=2;poolPtr->pool=(poolHead*)((char*)mem+sizeof(pool));/*pool指向申请内存区尾*//*初始化pool1该内存池分配大小为16B的内存*/poolHeadPtr=(poolHead*)((char*)mem+sizeof(pool));/*初始化内存池的首位置*/poolHeadPtr->available=32;/*初始化可用块数32*/poolHeadPtr->blockSize=16;/*块大小16B*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));/*初始化块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*初始化第一块可用块的位置*/poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr+sizeof(poolHeadPtr)+32*(sizeof(blockHead)+16));/*next指向第二个内存池*/blockHeadPtr->poolId=1;blockHeadPtr->frontBlock=0;for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/blockHeadPtr->poolId=1;/*pool号为1,表示他是16B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*当前首个可用块位置赋给frontBlock*/poolHeadPtr->firstavailable=blockHeadPtr;/*求下一首个可用块位置*/}/*初始化pool2该内存池分配大小为256B的内存*/poolHeadPtr=poolHeadPtr->next;poolHeadPtr->available=16;/*初始化可用块数16*/poolHeadPtr->blockSize=256;/*块大小256*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));poolHeadPtr->firstavailable=blockHeadPtr;poolHeadPtr->next=0;blockHeadPtr->poolId=2;blockHeadPtr->frontBlock=0;for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+256));blockHeadPtr->poolId=2;/*pool号为2,表示他是256B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;poolHeadPtr->firstavailable=blockHeadPtr;}return(pool*)mem;} /*memMalloc()分配内存*/void*memMalloc(intSize){void*mem;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semMalloc,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;if((Size<=16)&&(poolHeadPtr->available!=0))/*长度小于16时,分配长度为16的内存空间*/{blockHeadPtr=poolHeadPtr->firstavailable;/*首个可用块位置赋给分配块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr->frontBlock;/*改变下一第一可用块的位置*/poolHeadPtr->available--;/*可用块数减一*/semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));/*分配内存时加入块头开销*/}elseif((Size<=256)&&((poolHeadPtr->next)->available!=0))/*长度大于16小于256时,分配长度为256的内存空间*/{blockHeadPtr=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr->frontBlock;(poolHeadPtr->next)->available--;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}else/*其他情况用系统的内存分配函数malloc分配*/{printf("\n[Warning]:Toolargeforblocksortheblocksareexhausted\n");mem=malloc(Size);/*采用系统函数malloc()分配内存*/blockHeadPtr=(blockHead*)mem;blockHeadPtr->poolId=(initialPtr->poolNum+1);blockHeadPtr->frontBlock=mallocPtr;mallocPtr=blockHeadPtr;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}}/*memFree()释放内存空间*/voidmemFree(void*dataPtr){char*mem=(char*)dataPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semFree,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;/*恢复内存池首址*/blockHeadPtr=(blockHead*)((char*)mem-sizeof(blockHead));/*恢复内存块首址*/if(blockHeadPtr->poolId==1)/*释放16B的内存块*/{blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*恢复frontBlock位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*恢复第一可用块位置*/poolHeadPtr->available++;/*恢复可用块数*/}elseif(blockHeadPtr->poolId==2)/*释放256B的内存块*/{blockHeadPtr->frontBlock=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr;(poolHeadPtr->next)->available++;}else/*释放由系统分配的内存块*/{blockHeadPtr=mallocPtr;mallocPtr=blockHeadPtr->frontBlock;free((char*)mem-sizeof(blockHead));}semGive(semFree);return;}/*memDel()删除内存块*/voidmemDel(void){void*mem;blockHead*blockHeadPtr;mem=(void*)(initialPtr);free(mem);while(mallocPtr->frontBlock!=0){mem=(void*)(mallocPtr);free(mem);mallocPtr=mallocPtr->frontBlock;}semDelete(semMalloc);/*删除信号量*/semDelete(semFree);}5.无信号量(互斥)支持的临界资源访问方式有一个server任务,有10个client任务,10个client任务定时给server的消息队列发送消息,server任务接收到消息后,发送ACK消息到client的消息队列,如图:6.zerocopy消息队列存储的是指向消息的指针,从而实现了零拷贝。#defineMAX_MSG_LENsizeof(MESSAGE*)MESSAGE*rxMsg;/*用于从消息队列中接收消息*/MESSAGE*txMsg;/*用于向消息队列中发送消息*/msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);三、运行结果在shell中输入progStart,观察VxSim,输入progStop结束。四、心得实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。由于正值期末,考试任务繁重,时间紧迫,自身水平有限,难免会有疏漏,请老师指正。[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]
sprintf(tempName,"tTimer%d",id);
tidTimer[id]=taskSpawn(tempName,230,0,STACK_SIZE,(FUNCPTR)timer,id,0,0,0,0,0,0,0,0,0);
tidManager=taskSpawn("tMannager",200,0,STACK_SIZE,(FUNCPTR)manager,0,0,0,0,0,0,0,0,0,0);
printf("programestart!
\n");
/*manager()管理进程,实现task同步*/
STATUSmanager()
intid;
while(taskIsSuspended(tidServer)||taskIsReady(tidServer))
taskDelay(10);
for(id=0;id{while(taskIsSuspended(tidClient[id])||taskIsReady(tidClient[id]))taskDelay(10);}for(id=0;id{while(taskIsSuspended(tidTimer[id])||taskIsReady(tidTimer[id]))taskDelay(10);}semFlush(semSynStart);return(OK);}/*server()处理来自各个客户任务的消息*/STATUSserver(void){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*timer(id)向客户端定时发送的定时器*/STATUStimer(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*client(id)向服务器任务发请求消息*/STATUSclient(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。/*initial()初始化内存池*/pool*initial(void){inti;pool*mem;pool*poolPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*//*初始化pool*/poolPtr=(pool*)mem;poolPtr->poolNum=2;poolPtr->pool=(poolHead*)((char*)mem+sizeof(pool));/*pool指向申请内存区尾*//*初始化pool1该内存池分配大小为16B的内存*/poolHeadPtr=(poolHead*)((char*)mem+sizeof(pool));/*初始化内存池的首位置*/poolHeadPtr->available=32;/*初始化可用块数32*/poolHeadPtr->blockSize=16;/*块大小16B*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));/*初始化块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*初始化第一块可用块的位置*/poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr+sizeof(poolHeadPtr)+32*(sizeof(blockHead)+16));/*next指向第二个内存池*/blockHeadPtr->poolId=1;blockHeadPtr->frontBlock=0;for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/blockHeadPtr->poolId=1;/*pool号为1,表示他是16B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*当前首个可用块位置赋给frontBlock*/poolHeadPtr->firstavailable=blockHeadPtr;/*求下一首个可用块位置*/}/*初始化pool2该内存池分配大小为256B的内存*/poolHeadPtr=poolHeadPtr->next;poolHeadPtr->available=16;/*初始化可用块数16*/poolHeadPtr->blockSize=256;/*块大小256*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));poolHeadPtr->firstavailable=blockHeadPtr;poolHeadPtr->next=0;blockHeadPtr->poolId=2;blockHeadPtr->frontBlock=0;for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+256));blockHeadPtr->poolId=2;/*pool号为2,表示他是256B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;poolHeadPtr->firstavailable=blockHeadPtr;}return(pool*)mem;} /*memMalloc()分配内存*/void*memMalloc(intSize){void*mem;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semMalloc,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;if((Size<=16)&&(poolHeadPtr->available!=0))/*长度小于16时,分配长度为16的内存空间*/{blockHeadPtr=poolHeadPtr->firstavailable;/*首个可用块位置赋给分配块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr->frontBlock;/*改变下一第一可用块的位置*/poolHeadPtr->available--;/*可用块数减一*/semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));/*分配内存时加入块头开销*/}elseif((Size<=256)&&((poolHeadPtr->next)->available!=0))/*长度大于16小于256时,分配长度为256的内存空间*/{blockHeadPtr=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr->frontBlock;(poolHeadPtr->next)->available--;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}else/*其他情况用系统的内存分配函数malloc分配*/{printf("\n[Warning]:Toolargeforblocksortheblocksareexhausted\n");mem=malloc(Size);/*采用系统函数malloc()分配内存*/blockHeadPtr=(blockHead*)mem;blockHeadPtr->poolId=(initialPtr->poolNum+1);blockHeadPtr->frontBlock=mallocPtr;mallocPtr=blockHeadPtr;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}}/*memFree()释放内存空间*/voidmemFree(void*dataPtr){char*mem=(char*)dataPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semFree,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;/*恢复内存池首址*/blockHeadPtr=(blockHead*)((char*)mem-sizeof(blockHead));/*恢复内存块首址*/if(blockHeadPtr->poolId==1)/*释放16B的内存块*/{blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*恢复frontBlock位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*恢复第一可用块位置*/poolHeadPtr->available++;/*恢复可用块数*/}elseif(blockHeadPtr->poolId==2)/*释放256B的内存块*/{blockHeadPtr->frontBlock=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr;(poolHeadPtr->next)->available++;}else/*释放由系统分配的内存块*/{blockHeadPtr=mallocPtr;mallocPtr=blockHeadPtr->frontBlock;free((char*)mem-sizeof(blockHead));}semGive(semFree);return;}/*memDel()删除内存块*/voidmemDel(void){void*mem;blockHead*blockHeadPtr;mem=(void*)(initialPtr);free(mem);while(mallocPtr->frontBlock!=0){mem=(void*)(mallocPtr);free(mem);mallocPtr=mallocPtr->frontBlock;}semDelete(semMalloc);/*删除信号量*/semDelete(semFree);}5.无信号量(互斥)支持的临界资源访问方式有一个server任务,有10个client任务,10个client任务定时给server的消息队列发送消息,server任务接收到消息后,发送ACK消息到client的消息队列,如图:6.zerocopy消息队列存储的是指向消息的指针,从而实现了零拷贝。#defineMAX_MSG_LENsizeof(MESSAGE*)MESSAGE*rxMsg;/*用于从消息队列中接收消息*/MESSAGE*txMsg;/*用于向消息队列中发送消息*/msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);三、运行结果在shell中输入progStart,观察VxSim,输入progStop结束。四、心得实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。由于正值期末,考试任务繁重,时间紧迫,自身水平有限,难免会有疏漏,请老师指正。[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]
while(taskIsSuspended(tidClient[id])||taskIsReady(tidClient[id]))
for(id=0;id{while(taskIsSuspended(tidTimer[id])||taskIsReady(tidTimer[id]))taskDelay(10);}semFlush(semSynStart);return(OK);}/*server()处理来自各个客户任务的消息*/STATUSserver(void){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*timer(id)向客户端定时发送的定时器*/STATUStimer(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}/*client(id)向服务器任务发请求消息*/STATUSclient(intid){……semTake(semSynStart,WAIT_FOREVER);FOREVER{……}return(OK);}4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。/*initial()初始化内存池*/pool*initial(void){inti;pool*mem;pool*poolPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*//*初始化pool*/poolPtr=(pool*)mem;poolPtr->poolNum=2;poolPtr->pool=(poolHead*)((char*)mem+sizeof(pool));/*pool指向申请内存区尾*//*初始化pool1该内存池分配大小为16B的内存*/poolHeadPtr=(poolHead*)((char*)mem+sizeof(pool));/*初始化内存池的首位置*/poolHeadPtr->available=32;/*初始化可用块数32*/poolHeadPtr->blockSize=16;/*块大小16B*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));/*初始化块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*初始化第一块可用块的位置*/poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr+sizeof(poolHeadPtr)+32*(sizeof(blockHead)+16));/*next指向第二个内存池*/blockHeadPtr->poolId=1;blockHeadPtr->frontBlock=0;for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/blockHeadPtr->poolId=1;/*pool号为1,表示他是16B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*当前首个可用块位置赋给frontBlock*/poolHeadPtr->firstavailable=blockHeadPtr;/*求下一首个可用块位置*/}/*初始化pool2该内存池分配大小为256B的内存*/poolHeadPtr=poolHeadPtr->next;poolHeadPtr->available=16;/*初始化可用块数16*/poolHeadPtr->blockSize=256;/*块大小256*/blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));poolHeadPtr->firstavailable=blockHeadPtr;poolHeadPtr->next=0;blockHeadPtr->poolId=2;blockHeadPtr->frontBlock=0;for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/{blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+256));blockHeadPtr->poolId=2;/*pool号为2,表示他是256B容量的*/blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;poolHeadPtr->firstavailable=blockHeadPtr;}return(pool*)mem;} /*memMalloc()分配内存*/void*memMalloc(intSize){void*mem;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semMalloc,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;if((Size<=16)&&(poolHeadPtr->available!=0))/*长度小于16时,分配长度为16的内存空间*/{blockHeadPtr=poolHeadPtr->firstavailable;/*首个可用块位置赋给分配块的首位置*/poolHeadPtr->firstavailable=blockHeadPtr->frontBlock;/*改变下一第一可用块的位置*/poolHeadPtr->available--;/*可用块数减一*/semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));/*分配内存时加入块头开销*/}elseif((Size<=256)&&((poolHeadPtr->next)->available!=0))/*长度大于16小于256时,分配长度为256的内存空间*/{blockHeadPtr=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr->frontBlock;(poolHeadPtr->next)->available--;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}else/*其他情况用系统的内存分配函数malloc分配*/{printf("\n[Warning]:Toolargeforblocksortheblocksareexhausted\n");mem=malloc(Size);/*采用系统函数malloc()分配内存*/blockHeadPtr=(blockHead*)mem;blockHeadPtr->poolId=(initialPtr->poolNum+1);blockHeadPtr->frontBlock=mallocPtr;mallocPtr=blockHeadPtr;semGive(semMalloc);return(void*)((char*)blockHeadPtr+sizeof(blockHead));}}/*memFree()释放内存空间*/voidmemFree(void*dataPtr){char*mem=(char*)dataPtr;poolHead*poolHeadPtr;blockHead*blockHeadPtr;semTake(semFree,WAIT_FOREVER);poolHeadPtr=initialPtr->pool;/*恢复内存池首址*/blockHeadPtr=(blockHead*)((char*)mem-sizeof(blockHead));/*恢复内存块首址*/if(blockHeadPtr->poolId==1)/*释放16B的内存块*/{blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*恢复frontBlock位置*/poolHeadPtr->firstavailable=blockHeadPtr;/*恢复第一可用块位置*/poolHeadPtr->available++;/*恢复可用块数*/}elseif(blockHeadPtr->poolId==2)/*释放256B的内存块*/{blockHeadPtr->frontBlock=(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable=blockHeadPtr;(poolHeadPtr->next)->available++;}else/*释放由系统分配的内存块*/{blockHeadPtr=mallocPtr;mallocPtr=blockHeadPtr->frontBlock;free((char*)mem-sizeof(blockHead));}semGive(semFree);return;}/*memDel()删除内存块*/voidmemDel(void){void*mem;blockHead*blockHeadPtr;mem=(void*)(initialPtr);free(mem);while(mallocPtr->frontBlock!=0){mem=(void*)(mallocPtr);free(mem);mallocPtr=mallocPtr->frontBlock;}semDelete(semMalloc);/*删除信号量*/semDelete(semFree);}5.无信号量(互斥)支持的临界资源访问方式有一个server任务,有10个client任务,10个client任务定时给server的消息队列发送消息,server任务接收到消息后,发送ACK消息到client的消息队列,如图:6.zerocopy消息队列存储的是指向消息的指针,从而实现了零拷贝。#defineMAX_MSG_LENsizeof(MESSAGE*)MESSAGE*rxMsg;/*用于从消息队列中接收消息*/MESSAGE*txMsg;/*用于向消息队列中发送消息*/msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);三、运行结果在shell中输入progStart,观察VxSim,输入progStop结束。四、心得实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。由于正值期末,考试任务繁重,时间紧迫,自身水平有限,难免会有疏漏,请老师指正。[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]
while(taskIsSuspended(tidTimer[id])||taskIsReady(tidTimer[id]))
semFlush(semSynStart);
/*server()处理来自各个客户任务的消息*/
STATUSserver(void)
/*timer(id)向客户端定时发送的定时器*/
/*client(id)向服务器任务发请求消息*/
STATUSclient(intid)
静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:
静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。
/*initial()初始化内存池*/
pool*initial(void)
inti;
pool*mem;
pool*poolPtr;
poolHead*poolHeadPtr;
blockHead*blockHeadPtr;
mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*/
/*初始化pool*/
poolPtr=(pool*)mem;
poolPtr->poolNum=2;
poolPtr->pool=(poolHead*)((char*)mem+sizeof(pool));/*pool指向申请内存区尾*/
/*初始化pool1该内存池分配大小为16B的内存*/
poolHeadPtr=(poolHead*)((char*)mem+sizeof(pool));/*初始化内存池的首位置*/
poolHeadPtr->available=32;/*初始化可用块数32*/
poolHeadPtr->blockSize=16;/*块大小16B*/
blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));/*初始化块的首位置*/
poolHeadPtr->firstavailable=blockHeadPtr;/*初始化第一块可用块的位置*/
poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr+sizeof(poolHeadPtr)+32*(sizeof(blockHead)+16));/*next指向第二个内存池*/
blockHeadPtr->poolId=1;
blockHeadPtr->frontBlock=0;
for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/
blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/
blockHeadPtr->poolId=1;/*pool号为1,表示他是16B容量的*/
blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*当前首个可用块位置赋给frontBlock*/
poolHeadPtr->firstavailable=blockHeadPtr;/*求下一首个可用块位置*/
/*初始化pool2该内存池分配大小为256B的内存*/
poolHeadPtr=poolHeadPtr->next;
poolHeadPtr->available=16;/*初始化可用块数16*/
poolHeadPtr->blockSize=256;/*块大小256*/
blockHeadPtr=(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));
poolHeadPtr->firstavailable=blockHeadPtr;
poolHeadPtr->next=0;
blockHeadPtr->poolId=2;
for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/
blockHeadPtr=(blockHead*)((char*)blockHeadPtr+(sizeof(blockHead)+256));
blockHeadPtr->poolId=2;/*pool号为2,表示他是256B容量的*/
blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;
return(pool*)mem;
/*memMalloc()分配内存*/
void*memMalloc(intSize)
void*mem;
semTake(semMalloc,WAIT_FOREVER);
poolHeadPtr=initialPtr->pool;
if((Size<=16)&&(poolHeadPtr->available!
=0))/*长度小于16时,分配长度为16的内存空间*/
blockHeadPtr=poolHeadPtr->firstavailable;/*首个可用块位置赋给分配块的首位置*/
poolHeadPtr->firstavailable=blockHeadPtr->frontBlock;/*改变下一第一可用块的位置*/
poolHeadPtr->available--;/*可用块数减一*/
semGive(semMalloc);
return(void*)((char*)blockHeadPtr+sizeof(blockHead));/*分配内存时加入块头开销*/
elseif((Size<=256)&&((poolHeadPtr->next)->available!
=0))
/*长度大于16小于256时,分配长度为256的内存空间*/
blockHeadPtr=(poolHeadPtr->next)->firstavailable;
(poolHeadPtr->next)->firstavailable=blockHeadPtr->frontBlock;
(poolHeadPtr->next)->available--;
return(void*)((char*)blockHeadPtr+sizeof(blockHead));
else/*其他情况用系统的内存分配函数malloc分配*/
printf("\n[Warning]:
Toolargeforblocksortheblocksareexhausted\n");
mem=malloc(Size);/*采用系统函数malloc()分配内存*/
blockHeadPtr=(blockHead*)mem;
blockHeadPtr->poolId=(initialPtr->poolNum+1);
blockHeadPtr->frontBlock=mallocPtr;
mallocPtr=blockHeadPtr;
/*memFree()释放内存空间*/
voidmemFree(void*dataPtr)
char*mem=(char*)dataPtr;
semTake(semFree,WAIT_FOREVER);
poolHeadPtr=initialPtr->pool;/*恢复内存池首址*/
blockHeadPtr=(blockHead*)((char*)mem-sizeof(blockHead));/*恢复内存块首址*/
if(blockHeadPtr->poolId==1)/*释放16B的内存块*/
blockHeadPtr->frontBlock=poolHeadPtr->firstavailable;/*恢复frontBlock位置*/
poolHeadPtr->firstavailable=blockHeadPtr;/*恢复第一可用块位置*/
poolHeadPtr->available++;/*恢复可用块数*/
elseif(blockHeadPtr->poolId==2)/*释放256B的内存块*/
blockHeadPtr->frontBlock=(poolHeadPtr->next)->firstavailable;
(poolHeadPtr->next)->firstavailable=blockHeadPtr;
(poolHeadPtr->next)->available++;
else/*释放由系统分配的内存块*/
blockHeadPtr=mallocPtr;
mallocPtr=blockHeadPtr->frontBlock;
free((char*)mem-sizeof(blockHead));
semGive(semFree);
return;
/*memDel()删除内存块*/
voidmemDel(void)
mem=(void*)(initialPtr);
free(mem);
while(mallocPtr->frontBlock!
=0)
mem=(void*)(mallocPtr);
mallocPtr=mallocPtr->frontBlock;
semDelete(semMalloc);/*删除信号量*/
semDelete(semFree);
5.无信号量(互斥)支持的临界资源访问方式
有一个server任务,有10个client任务,10个client任务定时给server的消息队列发送消息,server任务接收到消息后,发送ACK消息到client的消息队列,如图:
6.zerocopy
消息队列存储的是指向消息的指针,从而实现了零拷贝。
#defineMAX_MSG_LENsizeof(MESSAGE*)
MESSAGE*rxMsg;/*用于从消息队列中接收消息*/
MESSAGE*txMsg;/*用于向消息队列中发送消息*/
msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);
msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);
三、运行结果
在shell中输入progStart,观察VxSim,输入progStop结束。
四、心得
实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。
由于正值期末,考试任务繁重,时间紧迫,自身水平有限,难免会有疏漏,请老师指正。
[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!
]
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2