### 嵌入式系统实验知识点总结
#### 实验背景与目标
本次实验报告由北邮研究生邝坚完成,主题是“支持消息驱动模式的实时软件框架”。该实验旨在通过构建一个实时系统的软件框架,加深学生对嵌入式处理器特性、实时操作系统(RTOS)以及强实时嵌入式系统软件设计规范的理解。
#### 实验环境
本实验采用的是VxWorks的VxSim仿真环境或基于ARM920T内核的2440平台作为开发环境。VxWorks是一款成熟的商用RTOS,广泛应用于航空航天、军事和工业控制等领域。2440平台则是基于ARM920T内核的一款典型开发板,适合进行嵌入式系统的设计与开发。
#### 必选功能实现
##### 消息驱动的Task统一框架
1. **统一消息格式定义**:为了实现消息驱动的Task统一框架,首先需要定义统一的消息格式,以确保不同Task之间的消息传递可以高效、准确地进行。消息格式如下所示:
```c
typedef struct _MESSAGE {
int mType; /* 消息类型:0:timer->client, 1:client->server, 2:server->client */
int mSendId; /* 发送任务的MESSAGEID */
int mRecvId; /* 接收任务的MESSAGEID */
int mData; /* 消息中传递的数据 */
} MESSAGE;
```
这里定义了一个`MESSAGE`结构体,用于表示消息的基本信息。消息类型分为三种:定时器到客户端(`0`)、客户端到服务端(`1`)和服务端到客户端(`2`)。消息中还包括发送者和接收者的标识符以及具体的数据内容。
2. **使用规范**:定义了消息格式后,接下来是规范其使用方法。每个Task都需要遵循一定的规则来发送和接收消息,以保证系统的稳定运行。示例代码如下:
```c
STATUS Task() {
Initialization(MBox, DataStructure, Timer, etc.);
Forever {
MsgReceive
If(…) {
…
} else if (…) {
…
}
…
}
}
```
##### 支持消息驱动模式的软定时器机制
为了实现消息驱动模式下的软定时器机制,设计了一个名为`timer`的函数,它会根据指定的时间间隔向客户端消息队列发送消息。具体实现如下:
```c
STATUS timer(int id) {
MESSAGE *txMsg; /* 用于从消息队列中接收消息 */
int tick; /* 创建一个定时,用于提醒发送者任务定时发送消息 */
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%d send message to tClient%d!\n", id, id);
if (msgQSend(msgQIdClient[id], (char *)&txMsg, MAX_MSG_LEN, WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR) {
return(ERROR);
}
}
return(OK);
}
```
此段代码首先获取系统时钟频率,然后进入无限循环,在每次循环中延迟一段时间后向指定客户端的消息队列发送一条消息。
##### Task启动同步功能
为确保各个Task能够按照预期的方式启动,需要实现一个Task启动同步功能。这个功能的核心是由一个称为`manager()`的Task创建其他Task,并确保这些Task都处于等待状态,直到`manager()`Task发出信号后,所有Task才同时启动。具体实现方法如下:
1. **初始化阶段**:创建所有Task并让它们等待信号量`semSynStart`。这可以通过调用`semTake()`函数实现,当没有信号时,Task会被阻塞。
2. **同步启动**:`manager()`Task最后创建,当它启动时,首先会等待所有其他Task就绪并处于等待状态,然后通过释放信号量`semSynStart`来通知其他Task可以启动。
3. **示例代码**:
```c
/* progStart() 启动实例程序 */
STATUS progStart(void) {
int id; /* 用来区分不同的定时器或者客户任务 */
mallocPtr = &sysMalloc;
mallocPtr->frontBlock = 0;
initialPtr = initial();
tidServer = tidManager = 0;
for (id = 0; id < NUM_CLIENT; id++) {
tidClient[id] = 0;
}
for (id = 0; id < NUM_TIMER; 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 < NUM_CLIENT; id++) {
msgQIdClient[id] = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_FIFO | MSG_Q_EVENTSEND_ERR_NOTIFY);
if (msgQIdClient[id] == NULL) {
return(ERROR);
}
}
/* 创建Task */
// ...省略创建Task的代码...
/* manager() Task */
tidManager = taskCreate(manager, (char *)"Manager", WPRI, (char *)&initialPtr, STACK_SIZE, T_JOINABLE);
// ...省略其他细节...
return(OK);
}
```
#### 可选功能实现
除了上述必选功能外,还提供了可选功能供进一步探索。这些功能包括但不限于:
- **无信号量(互斥)支持的临界资源访问方式**:通过采用原子操作或其他技术实现在不使用信号量的情况下访问共享资源。
- **ZeroCopy机制**:减少数据拷贝次数,提高系统性能。
以上内容涵盖了实验报告中的主要知识点,包括消息驱动的Task统一框架设计、软定时器机制实现以及Task启动同步策略等方面。通过这些实践,不仅能够深入理解嵌入式系统的设计原理,还能掌握RTOS的实际应用技巧。