邝坚_北邮嵌入式实验报告_第1页
邝坚_北邮嵌入式实验报告_第2页
邝坚_北邮嵌入式实验报告_第3页
邝坚_北邮嵌入式实验报告_第4页
邝坚_北邮嵌入式实验报告_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、嵌入式系统期末实验一、实验要求题目:支持消息驱动模式的实时软件框架目的:在充分理解嵌入式处理器特点、RTOS 及强实时嵌入式系统软件设计规范的基础上,构建自己的实时系统软件框架基本功能,并在其上自拟应用(如部分模拟TCP 的C/S两端通信流程),测试软件框架的相关功能。环境:VxWorks 的VxSim 仿真环境或2440(ARM920T)内容:必选功能:1. 消息驱动的Task 统一框架,包含统一消息格式定义及使用规范;2. 支持消息驱动模式的软定时器的机制;3. Task 启动同步功能;4. 体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。可选功能(加分):

2、其它有利于实时处理的有效机制,如:无信号量(互斥)支持的临界资源访问方式,zero copy 等;二、实现的功能1. 消息驱动的Task 统一框架,包含统一消息格式定义及使用规范;STATUS Task()Initialization(MBox, Data Structure, Timer, etc.)ForeverMsgReceiveIf()else if()typedef struct _MESSAGE int mType;/* 消息类型 0:timer->client *1:client->server 2:server->client*/ int mSendId; /

3、* 发送任务的MESSAGE ID */ int mRecvId; /* 接收任务的MESSAGE ID */ int mData; /* 消息中传递的数据 */MESSAGE;2. 支持消息驱动模式的软定时器的机制;/* timer(id)向客户端消息队列定时发送的定时器*/STATUS timer(int id) MESSAGE* txMsg;/* 用于从消息队列中接收消息 */ int tick;/*创建一个定时,用于提醒发送者任务定时发送消息*/ tick=sysClkRateGet(); semTake(semSynStart,WAIT_FOREVER); FOREVER taskD

4、elay(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%d send message to tClient%d!n",id,id);if(msgQSend(msgQIdClientid,(char*)&txMsg,MAX_MSG

5、_LEN,WAIT_FOREVER,MSG_PRI_NORMAL) = ERROR ) return (ERROR); return (OK);3. Task 启动同步功能;由manager()创建的任务优先级最高,先创建timer()、server()、client()的任务,让他们都在等待信号量semSynStart而被阻塞,最后创建manager()的任务,占据CPU,等待其他所有任务都被阻塞,解锁所有等待信号量的任务,让它们同时启动。/* progStart()启动实例程序*/STATUS progStart(void)int id; /* 用来区分不同的定时器或者客户任务 */mal

6、locPtr=&sysMalloc;mallocPtr->frontBlock = 0;initialPtr = initial();tidServer = tidManager = 0;for (id = 0; id < NUM_CLIENT; id+)tidClientid = 0; for (id = 0; id < NUM_TIMER; id+) tidTimerid = 0; /* 创建消息队列 */ msgQIdServer = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR

7、_NOTIFY); if (msgQIdServer = NULL) return (ERROR); for (id = 0; id < NUM_CLIENT; id+) msgQIdClientid = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY); if (msgQIdClientid = NULL) return (ERROR); semSynStart = semBCreate(SEM_Q_FIFO | SEM_EVENTSEND_ERR_NOTIFY,SEM_EMPTY); se

8、mMalloc = 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 < NUM_CLIENT; id+) char tempName20; sprintf(tempName, "tClient%d",

9、 id); tidClientid = taskSpawn(tempName, 210, 0, STACK_SIZE, (FUNCPTR)client,id,0,0,0,0,0,0,0,0,0); for (id = 0; id < NUM_TIMER; id+) char tempName20; sprintf(tempName, "tTimer%d", id); tidTimerid = taskSpawn(tempName, 230, 0, STACK_SIZE, (FUNCPTR)timer,id,0,0,0,0,0,0,0,0,0); tidManager

10、= taskSpawn("tMannager", 200, 0, STACK_SIZE, (FUNCPTR)manager,0,0,0,0,0,0,0,0,0,0); printf("programe start!n"); return (OK);/* manager() 管理进程,实现task同步*/STATUS manager() int id; while(taskIsSuspended(tidServer) | taskIsReady(tidServer) taskDelay(10); for (id = 0; id < NUM_CLIEN

11、T; id+) while(taskIsSuspended(tidClientid) | taskIsReady(tidClientid) taskDelay(10); for (id = 0; id < NUM_TIMER; id+) while(taskIsSuspended(tidTimerid) | taskIsReady(tidTimerid) taskDelay(10); semFlush(semSynStart); return (OK);/* server()处理来自各个客户任务的消息*/STATUS server(void) semTake(semSynStart,WA

12、IT_FOREVER); FOREVER return (OK);/* timer(id)向客户端定时发送的定时器*/STATUS timer(int id) semTake(semSynStart,WAIT_FOREVER); FOREVER return (OK);/*client(id)向服务器任务发请求消息*/STATUS client(int id) semTake(semSynStart,WAIT_FOREVER); FOREVER return (OK);4. 体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。静态内存的数据结构为单链表,采用头插法,

13、申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示:静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。/*initial() 初始化内存池*/pool* initial(void)int i;pool* mem;pool* poolPtr;poolHead* poolHeadPtr;blockHead* blockHeadPtr;

14、mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*/ /*初始化pool*/poolPtr = (pool*)mem;poolPtr->poolNum = 2;poolPtr->pool = (poolHead*)(char*)mem + sizeof(pool); /*pool指向申请内存区尾*/ /*初始化pool 1 该内存池分配大小为16B的内存*/poolHeadPtr = (poolHead*)(char*)mem + sizeof(pool);/*初始化内存池的首地址*/poolHeadPtr->available = 32; /

15、*初始化可用块数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); /*nex

16、t指向第二个内存池 */ 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 = poolHeadP

17、tr->firstavailable; /* 当前首个可用块地址赋给frontBlock */poolHeadPtr->firstavailable = blockHeadPtr; /* 求下一首个可用块地址*/*初始化pool 2 该内存池分配大小为256B的内存*/poolHeadPtr = poolHeadPtr->next;poolHeadPtr->available = 16; /*初始化可用块数16*/poolHeadPtr->blockSize = 256; /*块大小256*/blockHeadPtr = (blockHead*)(char*)po

18、olHeadPtr+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 =

19、2; /* pool号为2,表示他是256B容量的*/blockHeadPtr->frontBlock = poolHeadPtr->firstavailable;poolHeadPtr->firstavailable = blockHeadPtr;return (pool*)mem;/*memMalloc() 分配内存*/void* memMalloc(int Size)void* mem;poolHead* poolHeadPtr;blockHead* blockHeadPtr;semTake(semMalloc,WAIT_FOREVER);poolHeadPtr = i

20、nitialPtr->pool;if(Size <= 16)&&(poolHeadPtr->available != 0) /*长度小于16时,分配长度为16的内存空间*/blockHeadPtr = poolHeadPtr->firstavailable; /*首个可用块地址赋给分配块的首地址*/poolHeadPtr->firstavailable = blockHeadPtr->frontBlock; /*改变下一第一可用块的地址*/poolHeadPtr->available -; /*可用块数减一*/semGive(semMa

21、lloc); return (void*)(char*)blockHeadPtr + sizeof(blockHead); /*分配内存时加入块头开销*/else if(Size <= 256)&&(poolHeadPtr->next)->available != 0) /*长度大于16小于256时,分配长度为256的内存空间*/blockHeadPtr = (poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable = blockHeadPtr->

22、;frontBlock; (poolHeadPtr->next)->available -; semGive(semMalloc);return (void*)(char*)blockHeadPtr + sizeof(blockHead);else/*其他情况用系统的内存分配函数malloc分配*/printf("nWarning : Too large for blocks or the blocks are exhausted n");mem = malloc(Size); /*采用系统函数malloc()分配内存*/blockHeadPtr = (bloc

23、kHead*)mem;blockHeadPtr->poolId = (initialPtr->poolNum +1);blockHeadPtr->frontBlock = mallocPtr;mallocPtr = blockHeadPtr;semGive(semMalloc);return (void*)(char*)blockHeadPtr + sizeof(blockHead);/*memFree() 释放内存空间*/void memFree(void* dataPtr)char* mem= (char*) dataPtr;poolHead* poolHeadPtr;b

24、lockHead* blockHeadPtr;semTake(semFree,WAIT_FOREVER);poolHeadPtr = initialPtr->pool; /*恢复内存池首址*/blockHeadPtr = (blockHead*)(char*)mem - sizeof(blockHead); /*恢复内存块首址*/if(blockHeadPtr->poolId = 1) /*释放16B的内存块*/ blockHeadPtr->frontBlock = poolHeadPtr->firstavailable; /*恢复frontBlock地址*/poolH

25、eadPtr->firstavailable = blockHeadPtr; /*恢复第一可用块地址*/poolHeadPtr->available+; /*恢复可用块数*/else if(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;/*memD

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论