本综合演示涵盖了VxWorks核心机制的各个方面任务管理与调度多优先级任务创建、抢占调度、轮转调度同步与通信信号量、消息队列、互斥锁、事件寄存器中断与异常中断服务程序、异常处理、看门狗定时器内存管理动态分配、内存池、内存跟踪、泄漏检测时间管理高精度定时、周期任务、时间同步、漂移校正实时数据采集系统/* 综合实战实时数据采集系统 */ #include vxWorks.h #include taskLib.h #include semLib.h #include msgQLib.h #include intLib.h #include memLib.h #include sysLib.h #include wdLib.h #include logLib.h #include string.h #include stdio.h #include stdlib.h /* 系统配置 */ #define NUM_SENSORS 3 #define SAMPLE_RATE_HZ 1000 /* 采样率1kHz */ #define BUFFER_SIZE 1000 /* 每个传感器缓冲区大小 */ #define QUEUE_SIZE 100 /* 消息队列大小 */ #define PROCESSING_DEADLINE_MS 5 /* 处理截止时间5ms */ /* 数据结构 */ typedef enum { SENSOR_TEMP, SENSOR_PRESSURE, SENSOR_HUMIDITY } SENSOR_TYPE; typedef struct { SENSOR_TYPE type; int sensorId; TIME timestamp; float value; float rawValue; int sequence; } SENSOR_DATA; typedef struct { int sensorId; BOOL active; int sampleCount; int missedSamples; ULONG minSamplingInterval; /* 纳秒 */ ULONG maxSamplingInterval; ULONG totalSamplingTime; SEM_ID dataReadySem; MSG_Q_ID dataQueue; } SENSOR_INFO; typedef struct { int processedCount; int missedDeadlines; ULONG minProcessingTime; ULONG maxProcessingTime; ULONG totalProcessingTime; int bufferOverflows; } PROCESSING_STATS; /* 全局变量 */ SENSOR_INFO g_sensors[NUM_SENSORS]; PROCESSING_STATS g_processingStats {0}; SEM_ID g_systemMutex NULL; WD_ID g_systemWatchdog NULL; volatile BOOL g_systemRunning FALSE; int g_sysClkRate 0; int g_sampleIntervalTicks 0; /* 模拟传感器读取在实际系统中会替换为真实硬件访问 */ float readSensorValue(int sensorId, SENSOR_TYPE type) { static int callCount 0; float value 0.0; /* 模拟不同类型的传感器读数 */ switch (type) { case SENSOR_TEMP: value 20.0 5.0 * sin(callCount * 0.1) (rand() % 100) * 0.01; break; case SENSOR_PRESSURE: value 1013.25 10.0 * sin(callCount * 0.05) (rand() % 100) * 0.1; break; case SENSOR_HUMIDITY: value 50.0 20.0 * sin(callCount * 0.03) (rand() % 100) * 0.05; break; } callCount; return value; } /* 传感器采样任务 */ void sensorSamplingTask(int sensorId) { SENSOR_INFO *sensor g_sensors[sensorId]; ULONG lastSampleTime 0; int sequence 0; logMsg(传感器%d采样任务启动采样率%d Hz\n, sensorId, SAMPLE_RATE_HZ,0,0,0,0); /* 计算采样间隔纳秒 */ ULONG targetIntervalNs 1000000000ULL / SAMPLE_RATE_HZ; /* 等待系统启动信号 */ while (!g_systemRunning) { taskDelay(1); } lastSampleTime tickGet() * (1000000000ULL / g_sysClkRate); while (g_systemRunning sensor-active) { ULONG startTime, endTime, actualInterval; /* 记录开始时间 */ startTime tickGet() * (1000000000ULL / g_sysClkRate); /* 创建传感器数据 */ SENSOR_DATA data; data.sensorId sensorId; data.type (SENSOR_TYPE)sensorId; data.timestamp tickGet(); data.sequence sequence; data.rawValue readSensorValue(sensorId, data.type); /* 模拟简单滤波移动平均 */ static float filterBuffer[NUM_SENSORS][10] {0}; static int filterIndex[NUM_SENSORS] {0}; filterBuffer[sensorId][filterIndex[sensorId]] data.rawValue; filterIndex[sensorId] (filterIndex[sensorId] 1) % 10; float sum 0; for (int i 0; i 10; i) { sum filterBuffer[sensorId][i]; } data.value sum / 10.0; /* 发送数据到消息队列 */ STATUS status msgQSend(sensor-dataQueue, (char *)data, sizeof(SENSOR_DATA), NO_WAIT, MSG_PRI_NORMAL); if (status OK) { sensor-sampleCount; /* 发送数据就绪信号 */ semGive(sensor-dataReadySem); } else { sensor-missedSamples; logMsg(传感器%d: 消息队列已满丢弃样本%d\n, sensorId, sequence,0,0,0,0); } /* 记录结束时间并更新统计 */ endTime tickGet() * (1000000000ULL / g_sysClkRate); ULONG samplingTime endTime - startTime; sensor-totalSamplingTime samplingTime; if (samplingTime sensor-minSamplingInterval || sensor-minSamplingInterval 0) { sensor-minSamplingInterval samplingTime; } if (samplingTime sensor-maxSamplingInterval) { sensor-maxSamplingInterval samplingTime; } /* 计算实际间隔 */ actualInterval endTime - lastSampleTime; /* 检查采样间隔是否稳定 */ if (actualInterval targetIntervalNs * 1.1) { /* 超过10%误差 */ logMsg(传感器%d: 采样间隔不稳定! 目标%.3f ms, 实际%.3f ms\n, sensorId, targetIntervalNs/1000000.0, actualInterval/1000000.0,0,0,0); } lastSampleTime endTime; /* 计算需要等待的时间 */ if (samplingTime targetIntervalNs) { ULONG waitTimeNs targetIntervalNs - samplingTime; ULONG waitTicks (waitTimeNs * g_sysClkRate) / 1000000000ULL; if (waitTicks 0) { taskDelay(waitTicks); } else { /* 短时间忙等待 */ while ((tickGet() * (1000000000ULL / g_sysClkRate) - endTime) waitTimeNs) { /* 忙等待 */ } } } else { /* 采样时间超过间隔无法按时完成 */ logMsg(传感器%d: 采样超时! 需要%.3f ms, 实际%.3f ms\n, sensorId, targetIntervalNs/1000000.0, samplingTime/1000000.0,0,0,0); } /* 定期报告状态 */ if (sequence % 1000 0) { logMsg(传感器%d: 已采样%d次丢失%d个样本\n, sensorId, sequence, sensor-missedSamples,0,0,0); } } logMsg(传感器%d采样任务停止\n, sensorId,0,0,0,0,0); } /* 数据处理任务 */ void dataProcessingTask(int processorId) { SENSOR_DATA sensorData; int processedCount 0; char taskName[32]; sprintf(taskName, Processor%d, processorId); taskOpen(taskName); logMsg(数据处理任务%d启动\n, processorId,0,0,0,0,0); while (g_systemRunning) { BOOL dataProcessed FALSE; /* 检查所有传感器的数据 */ for (int i 0; i NUM_SENSORS; i) { if (g_sensors[i].active) { /* 尝试非阻塞获取数据 */ STATUS status msgQReceive(g_sensors[i].dataQueue, (char *)sensorData, sizeof(SENSOR_DATA), NO_WAIT); if (status ! ERROR) { ULONG startTime tickGet() * (1000000000ULL / g_sysClkRate); /* 处理传感器数据 */ processSensorData(sensorData, processorId); processedCount; ULONG endTime tickGet() * (1000000000ULL / g_sysClkRate); ULONG processingTime endTime - startTime; /* 更新统计 */ semTake(g_systemMutex, WAIT_FOREVER); g_processingStats.processedCount; g_processingStats.totalProcessingTime processingTime; if (processingTime g_processingStats.minProcessingTime || g_processingStats.minProcessingTime 0) { g_processingStats.minProcessingTime processingTime; } if (processingTime g_processingStats.maxProcessingTime) { g_processingStats.maxProcessingTime processingTime; } /* 检查是否错过截止时间 */ if (processingTime PROCESSING_DEADLINE_MS * 1000000ULL) { g_processingStats.missedDeadlines; logMsg(处理器%d: 错过截止时间! 传感器%d, 耗时%.3f ms\n, processorId, i, processingTime/1000000.0,0,0,0); } semGive(g_systemMutex); dataProcessed TRUE; break; /* 处理一个数据后重新循环 */ } } } if (!dataProcessed) { /* 没有数据可处理短暂休眠 */ taskDelay(1); } /* 定期报告状态 */ if (processedCount % 500 0) { logMsg(处理器%d: 已处理%d个数据\n, processorId, processedCount,0,0,0,0); } } taskClose(0); logMsg(数据处理任务%d停止共处理%d个数据\n, processorId, processedCount,0,0,0,0); } /* 处理传感器数据实际处理逻辑 */ void processSensorData(SENSOR_DATA *data, int processorId) { /* 模拟数据处理 */ switch (data-type) { case SENSOR_TEMP: /* 温度校准和补偿 */ data-value data-value 0.5; /* 简单校准 */ break; case SENSOR_PRESSURE: /* 压力单位转换 */ data-value data-value * 0.986923; /* hPa 到 atm */ break; case SENSOR_HUMIDITY: /* 湿度范围限制 */ if (data-value 0.0) data-value 0.0; if (data-value 100.0) data-value 100.0; break; } /* 模拟数据记录在实际系统中可能写入文件或数据库 */ if (data-sequence % 100 0) { logMsg(处理器%d: 处理传感器%d数据[%d]: %.2f\n, processorId, data-sensorId, data-sequence, data-value,0,0); } } /* 系统监控任务 */ void systemMonitorTask(void) { int monitorInterval 5; /* 监控间隔秒 */ int elapsedTime 0; logMsg(系统监控任务启动\n,0,0,0,0,0,0); while (g_systemRunning) { taskDelay(sysClkRateGet() * monitorInterval); elapsedTime monitorInterval; semTake(g_systemMutex, WAIT_FOREVER); logMsg(\n 系统监控报告 (运行%d秒) \n, elapsedTime,0,0,0,0,0); /* 显示传感器状态 */ for (int i 0; i NUM_SENSORS; i) { if (g_sensors[i].active) { float avgSamplingTime 0; if (g_sensors[i].sampleCount 0) { avgSamplingTime (float)g_sensors[i].totalSamplingTime / g_sensors[i].sampleCount / 1000000.0; } logMsg(传感器%d: 采样%d, 丢失%d, 平均采样时间%.3f ms\n, i, g_sensors[i].sampleCount, g_sensors[i].missedSamples, avgSamplingTime,0,0); } } /* 显示处理统计 */ if (g_processingStats.processedCount 0) { float avgProcessingTime (float)g_processingStats.totalProcessingTime / g_processingStats.processedCount / 1000000.0; float minProcessingTime g_processingStats.minProcessingTime / 1000000.0; float maxProcessingTime g_processingStats.maxProcessingTime / 1000000.0; float missRate 0; if (g_processingStats.processedCount 0) { missRate (float)g_processingStats.missedDeadlines / g_processingStats.processedCount * 100.0; } logMsg(数据处理: 总数%d, 平均时间%.3f ms\n, g_processingStats.processedCount, avgProcessingTime,0,0,0,0); logMsg( 最短%.3f ms, 最长%.3f ms, 错过截止时间%.1f%%\n, minProcessingTime, maxProcessingTime, missRate,0,0,0); } /* 检查系统健康状况 */ if (g_processingStats.missedDeadlines 100) { logMsg(警告: 错过截止时间次数过多系统可能过载!\n,0,0,0,0,0,0); } /* 检查消息队列状态 */ for (int i 0; i NUM_SENSORS; i) { if (g_sensors[i].active) { int msgsQueued msgQNumMsgs(g_sensors[i].dataQueue); if (msgsQueued QUEUE_SIZE * 0.8) { logMsg(警告: 传感器%d消息队列接近满 (%d/%d)\n, i, msgsQueued, QUEUE_SIZE,0,0,0); } } } /* 喂系统看门狗 */ if (g_systemWatchdog ! NULL) { wdStart(g_systemWatchdog, sysClkRateGet() * 10, NULL, 0); } semGive(g_systemMutex); /* 运行1分钟后自动停止演示目的 */ if (elapsedTime 60) { logMsg(系统已运行1分钟准备停止...\n,0,0,0,0,0,0); g_systemRunning FALSE; } } logMsg(系统监控任务停止\n,0,0,0,0,0,0); } /* 看门狗回调 */ void systemWatchdogCallback(int param) { logMsg([系统看门狗] 超时! 系统可能挂起\n,0,0,0,0,0,0); /* 尝试恢复系统 */ for (int i 0; i NUM_SENSORS; i) { if (g_sensors[i].active) { logMsg( 重启传感器%d采样任务...\n, i,0,0,0,0,0); /* 在实际系统中这里可能会重启任务 */ } } } /* 初始化系统 */ STATUS initDataAcquisitionSystem(void) { STATUS status OK; logMsg(初始化数据采集系统...\n,0,0,0,0,0,0); /* 1. 获取系统时钟频率 */ g_sysClkRate sysClkRateGet(); g_sampleIntervalTicks g_sysClkRate / SAMPLE_RATE_HZ; if (g_sampleIntervalTicks 0) { g_sampleIntervalTicks 1; } logMsg(系统时钟: %d Hz, 采样间隔: %d ticks\n, g_sysClkRate, g_sampleIntervalTicks,0,0,0,0); /* 2. 创建系统互斥信号量 */ g_systemMutex semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE); if (g_systemMutex NULL) { logMsg(错误: 创建系统互斥信号量失败\n,0,0,0,0,0,0); return ERROR; } /* 3. 创建系统看门狗 */ g_systemWatchdog wdCreate(); if (g_systemWatchdog ! NULL) { wdStart(g_systemWatchdog, sysClkRateGet() * 15, systemWatchdogCallback, 0); logMsg(系统看门狗已启动超时时间15秒\n,0,0,0,0,0,0); } /* 4. 初始化传感器 */ for (int i 0; i NUM_SENSORS; i) { g_sensors[i].sensorId i; g_sensors[i].active TRUE; g_sensors[i].sampleCount 0; g_sensors[i].missedSamples 0; g_sensors[i].minSamplingInterval 0; g_sensors[i].maxSamplingInterval 0; g_sensors[i].totalSamplingTime 0; /* 创建数据就绪信号量 */ g_sensors[i].dataReadySem semBCreate(SEM_Q_FIFO, SEM_EMPTY); if (g_sensors[i].dataReadySem NULL) { logMsg(错误: 创建传感器%d数据就绪信号量失败\n, i,0,0,0,0,0); status ERROR; break; } /* 创建消息队列 */ g_sensors[i].dataQueue msgQCreate(QUEUE_SIZE, sizeof(SENSOR_DATA), MSG_Q_FIFO); if (g_sensors[i].dataQueue NULL) { logMsg(错误: 创建传感器%d消息队列失败\n, i,0,0,0,0,0); semDelete(g_sensors[i].dataReadySem); status ERROR; break; } logMsg(传感器%d初始化完成\n, i,0,0,0,0,0); } if (status ! OK) { cleanupDataAcquisitionSystem(); return ERROR; } logMsg(数据采集系统初始化完成\n,0,0,0,0,0,0); return OK; } /* 启动系统 */ void startDataAcquisitionSystem(void) { logMsg(启动数据采集系统...\n,0,0,0,0,0,0); /* 1. 启动传感器采样任务 */ for (int i 0; i NUM_SENSORS; i) { char taskName[32]; sprintf(taskName, tSensor%d, i); taskSpawn(taskName, 180 - i*5, 0, 4096, (FUNCPTR)sensorSamplingTask, i, 0,0,0,0,0,0,0,0,0); logMsg(启动传感器%d采样任务优先级%d\n, i, 180 - i*5,0,0,0,0,0); } /* 2. 启动数据处理任务2个处理器 */ for (int i 0; i 2; i) { char taskName[32]; sprintf(taskName, tProcessor%d, i); taskSpawn(taskName, 170 - i*5, 0, 4096, (FUNCPTR)dataProcessingTask, i, 0,0,0,0,0,0,0,0,0); logMsg(启动数据处理任务%d优先级%d\n, i, 170 - i*5,0,0,0,0,0); } /* 3. 启动系统监控任务 */ taskSpawn(tMonitor, 160, 0, 4096, (FUNCPTR)systemMonitorTask, 0, 0,0,0,0,0,0,0,0,0); /* 4. 设置系统运行标志 */ g_systemRunning TRUE; logMsg(数据采集系统已启动\n,0,0,0,0,0,0); } /* 停止系统 */ void stopDataAcquisitionSystem(void) { logMsg(停止数据采集系统...\n,0,0,0,0,0,0); /* 1. 设置停止标志 */ g_systemRunning FALSE; /* 2. 等待任务停止 */ taskDelay(sysClkRateGet() * 2); /* 3. 清理资源 */ cleanupDataAcquisitionSystem(); logMsg(数据采集系统已停止\n,0,0,0,0,0,0); } /* 清理系统资源 */ void cleanupDataAcquisitionSystem(void) { /* 1. 停止看门狗 */ if (g_systemWatchdog ! NULL) { wdCancel(g_systemWatchdog); wdDelete(g_systemWatchdog); g_systemWatchdog NULL; } /* 2. 删除传感器资源 */ for (int i 0; i NUM_SENSORS; i) { if (g_sensors[i].dataReadySem ! NULL) { semDelete(g_sensors[i].dataReadySem); g_sensors[i].dataReadySem NULL; } if (g_sensors[i].dataQueue ! NULL) { msgQDelete(g_sensors[i].dataQueue); g_sensors[i].dataQueue NULL; } } /* 3. 删除系统互斥信号量 */ if (g_systemMutex ! NULL) { semDelete(g_systemMutex); g_systemMutex NULL; } /* 4. 显示最终统计 */ showFinalStatistics(); } /* 显示最终统计 */ void showFinalStatistics(void) { semTake(g_systemMutex, WAIT_FOREVER); logMsg(\n 数据采集系统最终统计 \n,0,0,0,0,0,0); /* 传感器统计 */ logMsg(\n传感器统计:\n,0,0,0,0,0,0); for (int i 0; i NUM_SENSORS; i) { if (g_sensors[i].active) { float avgSamplingTime 0; float avgSamplingRate 0; if (g_sensors[i].sampleCount 0) { avgSamplingTime (float)g_sensors[i].totalSamplingTime / g_sensors[i].sampleCount / 1000000.0; avgSamplingRate 1000.0 / avgSamplingTime; /* Hz */ } float lossRate 0; if (g_sensors[i].sampleCount g_sensors[i].missedSamples 0) { lossRate (float)g_sensors[i].missedSamples / (g_sensors[i].sampleCount g_sensors[i].missedSamples) * 100.0; } logMsg(传感器%d: 成功采样%d, 丢失%d, 丢失率%.1f%%\n, i, g_sensors[i].sampleCount, g_sensors[i].missedSamples, lossRate,0,0); logMsg( 平均采样时间%.3f ms, 等效采样率%.1f Hz\n, avgSamplingTime, avgSamplingRate,0,0,0,0); } } /* 处理统计 */ logMsg(\n数据处理统计:\n,0,0,0,0,0,0); if (g_processingStats.processedCount 0) { float avgProcessingTime (float)g_processingStats.totalProcessingTime / g_processingStats.processedCount / 1000000.0; float minProcessingTime g_processingStats.minProcessingTime / 1000000.0; float maxProcessingTime g_processingStats.maxProcessingTime / 1000000.0; float missRate (float)g_processingStats.missedDeadlines / g_processingStats.processedCount * 100.0; logMsg(处理总数: %d\n, g_processingStats.processedCount,0,0,0,0,0); logMsg(平均处理时间: %.3f ms\n, avgProcessingTime,0,0,0,0,0); logMsg(最短处理时间: %.3f ms\n, minProcessingTime,0,0,0,0,0); logMsg(最长处理时间: %.3f ms\n, maxProcessingTime,0,0,0,0,0); logMsg(错过截止时间: %d 次 (%.1f%%)\n, g_processingStats.missedDeadlines, missRate,0,0,0,0); /* 系统性能评估 */ if (missRate 1.0) { logMsg(系统性能评估: 优秀 (错过截止时间 1%%)\n,0,0,0,0,0,0); } else if (missRate 5.0) { logMsg(系统性能评估: 良好 (错过截止时间 5%%)\n,0,0,0,0,0,0); } else if (missRate 10.0) { logMsg(系统性能评估: 一般 (错过截止时间 10%%)\n,0,0,0,0,0,0); } else { logMsg(系统性能评估: 较差 (错过截止时间 10%%)\n,0,0,0,0,0,0); } } semGive(g_systemMutex); } /* 主演示函数 */ void integratedSystemDemo(void) { logMsg(\n VxWorks实时数据采集系统综合演示开始 \n,0,0,0,0,0,0); /* 1. 初始化系统 */ STATUS status initDataAcquisitionSystem(); if (status ! OK) { logMsg(系统初始化失败\n,0,0,0,0,0,0); return; } /* 2. 启动系统 */ startDataAcquisitionSystem(); /* 3. 等待系统运行完成 */ while (g_systemRunning) { taskDelay(sysClkRateGet()); } /* 4. 停止系统 */ stopDataAcquisitionSystem(); logMsg(\n 实时数据采集系统综合演示完成 \n,0,0,0,0,0,0); }总结个模块都包含详细的理论解析和完整的C代码示例可以直接在VxWorks系统中运行和测试。这些示例代码展示了实时系统开发的最佳实践包括错误处理、性能监控、系统恢复等关键方面。通过学习和实践这些示例开发人员可以深入理解VxWorks实时操作系统的核心机制掌握构建高可靠性、高性能嵌入式系统的关键技术。