Task2

本文详细介绍了文本情感分析中常用的评估指标,包括准确率、精确率、召回率、F1值、P-R曲线和ROC曲线。通过这些指标,可以全面评估机器学习模型在情感分析任务上的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Overview

  • 数据集
  • 数据基础认识
  • 常用评价指标

数据集

下载链接:http://ai.stanford.edu/~amaas/data/sentiment/

数据

数据集中包含四个文本文件:cnews.test.txt,cnews.train.txt,cnews.val.txt,cnews.vocab.txt,包括训练集,验证集,测试集,和词典 (基本的处理放在后面)

常用的评价指标

  • 准确率(accuracy) :预测准确的在所有样本中的比例,其计算如下:
    在这里插入图片描述
  • 精确率(precision):所有预测为positive的结果中,预测正确的比重
    在这里插入图片描述
  • 召回率(recall):
    在这里插入图片描述
  • F1值
    在这里插入图片描述
    • P-R曲线
      PR曲线中的P(Precision)和R(Recall)分布意为“查准率”和“查全率”。以“查准率”为纵坐标,“查全率”为横坐标所做的曲线即为PR曲线。
      在这里插入图片描述
    • ROC曲线:
      ROC曲线中,以FPR为x轴,TPR为y轴。FPR指实际负样本中被错误预测为正样本的概率。TPR指实际正样本中被预测正确的概率。
      在这里插入图片描述

(1)曲线与FP_rate轴围成的面积(记作AUC)越大,说明性能越好,即图上L2曲线对应的性能优于曲线L1对应的性能。即:曲线越靠近A点(左上方)性能越好,曲线越靠近B点(右下方)曲线性能越差。
(2)A点是最完美的performance点,B处是性能最差点。
(3)位于C-D线上的点说明算法性能和random猜测是一样的–如C、D、E点。位于C-D之上(即曲线位于白色的三角形内)说明算法性能优于随机猜测–如G点,位于C-D之下(即曲线位于灰色的三角形内)说明算法性能差于随机猜测–如F点。
(4)虽然ROC曲线相比较于Precision和Recall等衡量指标更加合理,但是其在高不平衡数据条件下的的表现仍然过于理想,不能够很好的展示实际情况

参考网址:
[1] :https://blog.youkuaiyun.com/quiet_girl/article/details/70830796

#include "includes.h" #include "stm32f10x_gpio.h" #include "xxGpio.h" //任务优先级 #define START_TASK_PRIO 3 //任务堆栈大小 #define START_STK_SIZE 128 //任务控制块 OS_TCB StartTaskTCB; //任务堆栈 CPU_STK START_TASK_STK[START_STK_SIZE]; //任务函数 void start_task(void *p_arg); #define LED0_PIN GPIO_Pin_1 // #define LED0_PORT GPIOA /* GPIOB */ #define LED0_ON() GPIO_SetLow(LED0_PORT, LED0_PIN); //0 #define LED0_OFF() GPIO_SetHigh(LED0_PORT, LED0_PIN); //0 #define LED1_PIN GPIO_Pin_2 // #define LED1_PORT GPIOA /* GPIOB */ #define LED1_ON() GPIO_SetLow(LED1_PORT, LED1_PIN); //0 #define LED1_OFF() GPIO_SetHigh(LED1_PORT, LED1_PIN); //0 #define LED2_PIN GPIO_Pin_3 // #define LED2_PORT GPIOA /* GPIOB */ #define LED2_ON() GPIO_SetLow(LED2_PORT, LED2_PIN); //0 #define LED2_OFF() GPIO_SetHigh(LED2_PORT, LED2_PIN); //0 GpioCfg_ts LED0_Cfg = { LED0_PORT, LED0_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; GpioCfg_ts LED1_Cfg = { LED1_PORT, LED1_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; GpioCfg_ts LED2_Cfg = { LED2_PORT, LED2_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; void LEDT_Init(void) { GPIO_Config( &LED0_Cfg ); GPIO_Config( &LED1_Cfg ); GPIO_Config( &LED2_Cfg ); } OS_Q DATA_Msg; //定义一个消息队列,用于发送数据 //主函数 int main(void) { OS_ERR err; CPU_SR_ALLOC(); LEDT_Init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置 OSInit(&err); /* Init uC/OS-III. */ //创建开始任务 OSTaskCreate( (OS_TCB * )&StartTaskTCB, //任务控制块 (CPU_CHAR * )"start task", //任务名字 (OS_TASK_PTR )start_task, //任务函数 (void * )0, //传递给任务函数的参数 (OS_PRIO )START_TASK_PRIO, //任务优先级 (CPU_STK * )&START_TASK_STK[0], //任务堆栈基地址 (CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位 (CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小 (OS_MSG_QTY )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息 (OS_TICK )0, //当使能时间片轮转时的时间片长度,为0时为默认长度, (void * )0, //用户补充的存储区 (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项 (OS_ERR * )&err); //存放该函数错误时的返 OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */ } /****************************************************************************************** * * 实验(一) * *******************************************************************************************/ // 创建1个任务,任务执行完毕后自动退出 #if(0) //任务优先级 #define TASK1_TASK_PRIO 4 //任务堆栈大小 #define TASK1_STK_SIZE 128 //任务控制块 OS_TCB Task1_TaskTCB; //任务堆栈 CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE]; void task1_task(void *p_arg); //任务优先级 #define TASK2_TASK_PRIO 4 //任务堆栈大小 #define TASK2_STK_SIZE 128 //任务控制块 OS_TCB Task2_TaskTCB; //任务堆栈 CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE]; void task2_task(void *p_arg); //开始任务任务函数 void start_task(void *p_arg) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); cpu_clk_freq = BSP_CPU_ClkFreq(); /* Determine SysTick reference freq. */ cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz; /* Determine nbr SysTick increments */ OS_CPU_SysTickInit(cnts); /* Init uC/OS periodic time src (SysTick). */ // Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif //创建TASK1任务 OSTaskCreate((OS_TCB * )&Task1_TaskTCB, (CPU_CHAR * )"Task1 task", (OS_TASK_PTR )task1_task, (void * )0, (OS_PRIO )TASK1_TASK_PRIO, (CPU_STK * )&TASK1_TASK_STK[0], (CPU_STK_SIZE)TASK1_STK_SIZE/10, (CPU_STK_SIZE)TASK1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建TASK2任务 OSTaskCreate((OS_TCB * )&Task2_TaskTCB, (CPU_CHAR * )"Task2 task", (OS_TASK_PTR )task2_task, (void * )0, (OS_PRIO )TASK2_TASK_PRIO, (CPU_STK * )&TASK2_TASK_STK[0], (CPU_STK_SIZE)TASK2_STK_SIZE/10, (CPU_STK_SIZE)TASK2_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //删除start_task任务自身 // OSTaskDel( (OS_TCB*)0, &err ); } //task1任务函数 volatile uint32_t i; uint8_t LedStates = 1; void task1_task(void *p_arg) { OS_ERR err; uint8_t count = 10; while(1) { // 任务1正常运行时LED0闪烁 for(uint8_t count = 0; count < 5; count++) { LED0_ON(); for(i = 0; i < 200000; i++); // 简单延时 LED0_OFF(); for(i = 0; i < 200000; i++); // 简单延时 } // 挂起任务2(LED1将停止闪烁) OSTaskSuspend(&Task2_TaskTCB, &err); OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); // 延时2秒 // 唤醒任务2(LED1恢复闪烁) OSTaskResume(&Task2_TaskTCB, &err); OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_DLY, &err); // 延时3秒 // 删除任务2 OSTaskDel(&Task2_TaskTCB, &err); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_DLY, &err); // 延时1秒 // 删除任务1自身 OSTaskDel((OS_TCB*)0, &err); } } //task2任务函数 void task2_task(void *p_arg) { volatile uint32_t i; while(1) { // LED1持续闪烁 LED1_ON(); for(i = 0; i < 200000; i++); // 简单延时 LED1_OFF(); for(i = 0; i < 200000; i++); // 简单延时 // 让出CPU时间 OSTimeDly(1, OS_OPT_TIME_DLY, NULL); } } #endif /****************************************************************************************** * * 实验(二) * *******************************************************************************************/ // 创建1个任务,任务执行完毕后自动退出 #if(0) //任务优先级 #define TASK1_TASK_PRIO 4 //任务堆栈大小 #define TASK1_STK_SIZE 128 //任务控制块 OS_TCB Task1_TaskTCB; //任务堆栈 CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE]; void task1_task(void *p_arg); //任务优先级 #define TASK2_TASK_PRIO 4 //任务堆栈大小 #define TASK2_STK_SIZE 128 //任务控制块 OS_TCB Task2_TaskTCB; //任务堆栈 CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE]; void task2_task(void *p_arg); //任务优先级 #define TASK3_TASK_PRIO 4 //任务堆栈大小 #define TASK3_STK_SIZE 128 //任务控制块 OS_TCB Task3_TaskTCB; //任务堆栈 CPU_STK TASK3_TASK_STK[TASK3_STK_SIZE]; void task3_task(void *p_arg); // 信号量定义 OS_SEM SharedResourceSem; // 共享资源信号量 OS_SEM SyncSem; // 同步信号量 //开始任务任务函数 void start_task(void *p_arg) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); cpu_clk_freq = BSP_CPU_ClkFreq(); /* Determine SysTick reference freq. */ cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz; /* Determine nbr SysTick increments */ OS_CPU_SysTickInit(cnts); /* Init uC/OS periodic time src (SysTick). */ // Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif //创建TASK1任务 OSTaskCreate((OS_TCB * )&Task1_TaskTCB, (CPU_CHAR * )"Task1 task", (OS_TASK_PTR )task1_task, (void * )0, (OS_PRIO )TASK1_TASK_PRIO, (CPU_STK * )&TASK1_TASK_STK[0], (CPU_STK_SIZE)TASK1_STK_SIZE/10, (CPU_STK_SIZE)TASK1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建TASK2任务 OSTaskCreate((OS_TCB * )&Task2_TaskTCB, (CPU_CHAR * )"Task2 task", (OS_TASK_PTR )task2_task, (void * )0, (OS_PRIO )TASK2_TASK_PRIO, (CPU_STK * )&TASK2_TASK_STK[0], (CPU_STK_SIZE)TASK2_STK_SIZE/10, (CPU_STK_SIZE)TASK2_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建TASK3任务 OSTaskCreate((OS_TCB * )&Task3_TaskTCB, (CPU_CHAR * )"Task3 task", (OS_TASK_PTR )task3_task, (void * )0, (OS_PRIO )TASK3_TASK_PRIO, (CPU_STK * )&TASK3_TASK_STK[0], (CPU_STK_SIZE)TASK3_STK_SIZE/10, (CPU_STK_SIZE)TASK3_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //删除start_task任务自身 // OSTaskDel( (OS_TCB*)0, &err ); } // 低优先级任务函数 void task1_task(void *p_arg) { OS_ERR err; while(1) { // 获取共享资源信号量(第一次信号量接收) OSSemPend(&SharedResourceSem, 0, OS_OPT_PEND_BLOCKING, 0, &err); // 模拟处理共享资源(长时间操作) OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); // 延时2秒 // 发送同步信号量(第一次信号量发送) OSSemPost(&SyncSem, OS_OPT_POST_1, &err); // 释放共享资源信号量 OSSemPost(&SharedResourceSem, OS_OPT_POST_1, &err); OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_DLY, &err); // 延时5秒 } } // 中优先级任务函数 void task2_task(void *p_arg) { OS_ERR err; while(1) { // 执行不需要共享资源的操作 // 这个任务会抢占低优先级任务 OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_DLY, &err); // 延时1秒 } } // 高优先级任务函数 void task3_task(void *p_arg) { OS_ERR err; while(1) { // 等待同步信号量(第二次信号量接收) OSSemPend(&SyncSem, 0, OS_OPT_PEND_BLOCKING, 0, &err); // 获取共享资源信号量(第二次信号量接收) OSSemPend(&SharedResourceSem, 0, OS_OPT_PEND_BLOCKING, 0, &err); // 执行关键操作 // 这里应该快速完成... // 发送同步信号量(第二次信号量发送) OSSemPost(&SyncSem, OS_OPT_POST_1, &err); // 释放共享资源信号量 OSSemPost(&SharedResourceSem, OS_OPT_POST_1, &err); OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_DLY, &err); // 延时5秒 } } #endif /****************************************************************************************** * * 实验(二) * *******************************************************************************************/ // 创建1个任务,任务执行完毕后自动退出 #if(1) //任务优先级 #define TASK1_TASK_PRIO 4 //任务堆栈大小 #define TASK1_STK_SIZE 128 //任务控制块 OS_TCB Task1_TaskTCB; //任务堆栈 CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE]; void task1_task(void *p_arg); //任务优先级 #define TASK2_TASK_PRIO 4 //任务堆栈大小 #define TASK2_STK_SIZE 128 //任务控制块 OS_TCB Task2_TaskTCB; //任务堆栈 CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE]; void task2_task(void *p_arg); //任务优先级 #define TASK3_TASK_PRIO 4 //任务堆栈大小 #define TASK3_STK_SIZE 128 //任务控制块 OS_TCB Task3_TaskTCB; //任务堆栈 CPU_STK TASK3_TASK_STK[TASK3_STK_SIZE]; void task3_task(void *p_arg); // 信号量定义 OS_SEM SharedResourceSem; // 共享资源信号量 OS_SEM SyncSem; // 同步信号量 //开始任务任务函数 void start_task(void *p_arg) { CPU_INT32U cpu_clk_freq; CPU_INT32U cnts; OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); cpu_clk_freq = BSP_CPU_ClkFreq(); /* Determine SysTick reference freq. */ cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz; /* Determine nbr SysTick increments */ OS_CPU_SysTickInit(cnts); /* Init uC/OS periodic time src (SysTick). */ // Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif //创建TASK1任务 OSTaskCreate((OS_TCB * )&Task1_TaskTCB, (CPU_CHAR * )"Task1 task", (OS_TASK_PTR )task1_task, (void * )0, (OS_PRIO )TASK1_TASK_PRIO, (CPU_STK * )&TASK1_TASK_STK[0], (CPU_STK_SIZE)TASK1_STK_SIZE/10, (CPU_STK_SIZE)TASK1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建TASK2任务 OSTaskCreate((OS_TCB * )&Task2_TaskTCB, (CPU_CHAR * )"Task2 task", (OS_TASK_PTR )task2_task, (void * )0, (OS_PRIO )TASK2_TASK_PRIO, (CPU_STK * )&TASK2_TASK_STK[0], (CPU_STK_SIZE)TASK2_STK_SIZE/10, (CPU_STK_SIZE)TASK2_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //创建TASK3任务 OSTaskCreate((OS_TCB * )&Task3_TaskTCB, (CPU_CHAR * )"Task3 task", (OS_TASK_PTR )task3_task, (void * )0, (OS_PRIO )TASK3_TASK_PRIO, (CPU_STK * )&TASK3_TASK_STK[0], (CPU_STK_SIZE)TASK3_STK_SIZE/10, (CPU_STK_SIZE)TASK3_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); //删除start_task任务自身 // OSTaskDel( (OS_TCB*)0, &err ); } #endif   帮我生成一个UCOSⅢ消息实验代码 任务要求:设计一个消息发送、接收例程,必须包含消息发送和接收,且接收消息后必须对消息长度和数据进行处理。共三个任务。
最新发布
06-23
<think>我们将在提供的框架基础上,设计一个包含三个任务的UCOSⅢ消息实验代码。三个任务分别是:1.发送任务(SenderTask):负责创建消息并发送到消息队列。2.处理任务(ProcessorTask):负责从消息队列接收消息,处理消息(包括验证消息长度和数据),然后发送到另一个队列。3.接收任务(ReceiverTask):负责从处理任务发送的队列中接收消息,打印消息详情,然后释放消息内存。我们将使用两个消息队列:-SendQueue:用于发送任务向处理任务发送消息。-RecvQueue:用于处理任务向接收任务发送处理后的消息。消息结构体定义如下:typedefstruct{CPU_INT16Umsg_id;//消息IDCPU_INT16Udata_length;//数据长度CPU_CHARdata[MAX_MSG_LENGTH];//消息数据CPU_INT32Uchecksum;//校验和(可选,用于数据验证)}APP_MSG;任务优先级安排(数值越低优先级越高):-接收任务(最高优先级,确保及时处理)-处理任务(中等优先级)-发送任务(最低优先级)我们还需要一个内存池来管理消息内存,避免频繁动态分配内存。由于提供的代码框架中已经包含了LED初始化和一些任务创建的模板,我们将在此基础上添加三个任务。注意:由于实验要求三个任务,我们将创建三个任务,并使用两个消息队列。步骤:1.在start_task中创建两个消息队列(SendQueue和RecvQueue)和内存池。2.创建三个任务:发送任务、处理任务和接收任务。3.在发送任务中,从内存池获取消息内存,填充消息内容(包括ID、数据、长度和校验和),然后发送到SendQueue。4.在处理任务中,从SendQueue接收消息,验证消息长度和数据(例如计算校验和),然后进行一些处理(例如转换数据格式),最后发送到RecvQueue。5.在接收任务中,从RecvQueue接收消息,打印消息详情,然后将消息内存释放回内存池。下面我们开始编写代码。</think># UCOSⅢ三任务消息传递实验设计与实现 下面我将基于您提供的框架,设计一个完整的UCOSⅢ消息传递实验,包含三个任务:发送任务、处理任务和接收任务。 ```c #include "includes.h" #include "stm32f10x_gpio.h" #include "xxGpio.h" // 任务优先级定义 #define START_TASK_PRIO 3 #define SENDER_TASK_PRIO 6 #define PROCESSOR_TASK_PRIO 7 #define RECEIVER_TASK_PRIO 8 // 任务堆栈大小 #define START_STK_SIZE 128 #define SENDER_STK_SIZE 128 #define PROCESSOR_STK_SIZE 128 #define RECEIVER_STK_SIZE 128 // 任务控制块 OS_TCB StartTaskTCB; OS_TCB SenderTaskTCB; OS_TCB ProcessorTaskTCB; OS_TCB ReceiverTaskTCB; // 任务堆栈 CPU_STK START_TASK_STK[START_STK_SIZE]; CPU_STK SENDER_TASK_STK[SENDER_STK_SIZE]; CPU_STK PROCESSOR_TASK_STK[PROCESSOR_STK_SIZE]; CPU_STK RECEIVER_TASK_STK[RECEIVER_STK_SIZE]; // 消息队列 OS_Q SendQueue; // 发送->处理队列 OS_Q RecvQueue; // 处理->接收队列 // 消息结构体 typedef struct { CPU_INT16U msg_id; // 消息ID CPU_INT16U data_length; // 数据长度 CPU_CHAR data[50]; // 消息数据 CPU_INT32U checksum; // 校验和 } APP_MSG; // 内存池 OS_MEM *MsgPool; #define MSG_POOL_SIZE 5 CPU_ALIGN CPU_CHAR MsgMemory[MSG_POOL_SIZE * sizeof(APP_MSG)]; // 函数声明 void start_task(void *p_arg); void sender_task(void *p_arg); void processor_task(void *p_arg); void receiver_task(void *p_arg); void init_memory_pool(void); void process_message(APP_MSG *msg); void print_message(APP_MSG *msg); // 硬件初始化 (基于您提供的代码) #define LED0_PIN GPIO_Pin_1 #define LED0_PORT GPIOA #define LED0_ON() GPIO_SetLow(LED0_PORT, LED0_PIN) #define LED0_OFF() GPIO_SetHigh(LED0_PORT, LED0_PIN) #define LED1_PIN GPIO_Pin_2 #define LED1_PORT GPIOA #define LED1_ON() GPIO_SetLow(LED1_PORT, LED1_PIN) #define LED1_OFF() GPIO_SetHigh(LED1_PORT, LED1_PIN) #define LED2_PIN GPIO_Pin_3 #define LED2_PORT GPIOA #define LED2_ON() GPIO_SetLow(LED2_PORT, LED2_PIN) #define LED2_OFF() GPIO_SetHigh(LED2_PORT, LED2_PIN) GpioCfg_ts LED0_Cfg = { LED0_PORT, LED0_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; GpioCfg_ts LED1_Cfg = { LED1_PORT, LED1_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; GpioCfg_ts LED2_Cfg = { LED2_PORT, LED2_PIN, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, Level_High, }; void LEDT_Init(void) { GPIO_Config( &LED0_Cfg ); GPIO_Config( &LED1_Cfg ); GPIO_Config( &LED2_Cfg ); } int main(void) { OS_ERR err; CPU_SR_ALLOC(); LEDT_Init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断分组配置 OSInit(&err); // 初始化UCOS-III // 创建开始任务 OSTaskCreate((OS_TCB *)&StartTaskTCB, (CPU_CHAR *)"start task", (OS_TASK_PTR)start_task, (void *)0, (OS_PRIO )START_TASK_PRIO, (CPU_STK *)&START_TASK_STK[0], (CPU_STK_SIZE)START_STK_SIZE/10, (CPU_STK_SIZE)START_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void *)0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR *)&err); OSStart(&err); // 启动UCOS-III } // 初始化内存池 void init_memory_pool(void) { OS_ERR err; // 创建消息内存池 MsgPool = OSMemCreate((void *)&MsgMemory[0], (OS_QTY )MSG_POOL_SIZE, (OS_SIZE )sizeof(APP_MSG), (OS_ERR *)&err); if (err != OS_ERR_NONE) { // 内存池创建失败处理 while(1); } } // 起始任务函数 void start_task(void *p_arg) { OS_ERR err; (void)p_arg; // 初始化内存池 init_memory_pool(); // 创建消息队列 OSQCreate((OS_Q *)&SendQueue, (CPU_CHAR *)"Send Queue", (OS_MSG_QTY )5, (OS_ERR *)&err); OSQCreate((OS_Q *)&RecvQueue, (CPU_CHAR *)"Recv Queue", (OS_MSG_QTY )5, (OS_ERR *)&err); // 创建接收任务(最高优先级) OSTaskCreate((OS_TCB *)&ReceiverTaskTCB, (CPU_CHAR *)"Receiver Task", (OS_TASK_PTR)receiver_task, (void *)0, (OS_PRIO )RECEIVER_TASK_PRIO, (CPU_STK *)&RECEIVER_TASK_STK[0], (CPU_STK_SIZE)RECEIVER_STK_SIZE/10, (CPU_STK_SIZE)RECEIVER_STK_SIZE, (OS_MSG_QTY )5, (OS_TICK )0, (void *)0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR *)&err); // 创建处理任务(中等优先级) OSTaskCreate((OS_TCB *)&ProcessorTaskTCB, (CPU_CHAR *)"Processor Task", (OS_TASK_PTR)processor_task, (void *)0, (OS_PRIO )PROCESSOR_TASK_PRIO, (CPU_STK *)&PROCESSOR_TASK_STK[0], (CPU_STK_SIZE)PROCESSOR_STK_SIZE/10, (CPU_STK_SIZE)PROCESSOR_STK_SIZE, (OS_MSG_QTY )5, (OS_TICK )0, (void *)0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR *)&err); // 创建发送任务(最低优先级) OSTaskCreate((OS_TCB *)&SenderTaskTCB, (CPU_CHAR *)"Sender Task", (OS_TASK_PTR)sender_task, (void *)0, (OS_PRIO )SENDER_TASK_PRIO, (CPU_STK *)&SENDER_TASK_STK[0], (CPU_STK_SIZE)SENDER_STK_SIZE/10, (CPU_STK_SIZE)SENDER_STK_SIZE, (OS_MSG_QTY )5, (OS_TICK )0, (void *)0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR *)&err); // 删除起始任务自身 OSTaskDel((OS_TCB*)0, &err); } // 发送任务函数 void sender_task(void *p_arg) { OS_ERR err; static CPU_INT16U msg_counter = 0; volatile CPU_INT32U i; // 用于简单延时 while(1) { // 从内存池获取消息缓冲区 APP_MSG *new_msg = (APP_MSG*)OSMemGet(MsgPool, &err); if (err == OS_ERR_NONE && new_msg != NULL) { // 填充消息内容 new_msg->msg_id = msg_counter++; new_msg->data_length = snprintf(new_msg->data, sizeof(new_msg->data), "Message #%d", new_msg->msg_id); // 计算简单校验和 new_msg->checksum = 0; for (int i = 0; i < new_msg->data_length; i++) { new_msg->checksum += new_msg->data[i]; } // 发送消息到处理队列 OSQPost((OS_Q *)&SendQueue, (void *)new_msg, (OS_MSG_SIZE )sizeof(APP_MSG*), (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR *)&err); if (err == OS_ERR_NONE) { // 消息发送成功,闪烁LED0 LED0_ON(); for(i = 0; i < 100000; i++); // 短暂延时 LED0_OFF(); } else { // 发送失败,释放消息内存 OSMemPut(MsgPool, (void*)new_msg, &err); LED0_ON(); // 点亮LED0表示错误 } } // 延迟2秒 OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_DLY, &err); } } // 处理任务函数 void processor_task(void *p_arg) { OS_ERR err; OS_MSG_SIZE msg_size; volatile CPU_INT32U i; // 用于简单延时 while(1) { // 从发送队列接收消息 APP_MSG *received_msg = (APP_MSG*)OSQPend((OS_Q *)&SendQueue, (OS_TICK )0, (OS_OPT )OS_OPT_PEND_BLOCKING, (OS_MSG_SIZE *)&msg_size, (CPU_TS *)0, (OS_ERR *)&err); if (err == OS_ERR_NONE) { // 闪烁LED1表示正在处理 LED1_ON(); for(i = 0; i < 50000; i++); // 处理消息 process_message(received_msg); // 发送处理后的消息到接收队列 OSQPost((OS_Q *)&RecvQueue, (void *)received_msg, (OS_MSG_SIZE )sizeof(APP_MSG*), (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR *)&err); LED1_OFF(); } // 短暂延迟 OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_DLY, &err); } } // 消息处理函数 void process_message(APP_MSG *msg) { // 1. 验证校验和 CPU_INT32U calc_checksum = 0; for (int i = 0; i < msg->data_length; i++) { calc_checksum += msg->data[i]; } if (calc_checksum != msg->checksum) { // 校验和错误,标记消息 snprintf(msg->data + msg->data_length, sizeof(msg->data) - msg->data_length, " [CHECKSUM ERROR]"); msg->data_length += 16; } else { // 2. 处理消息数据 - 转换为大写 for (int i = 0; i < msg->data_length; i++) { if (msg->data[i] >= 'a' && msg->data[i] <= 'z') { msg->data[i] = msg->data[i] - 'a' + 'A'; } } // 3. 添加处理标记 snprintf(msg->data + msg->data_length, sizeof(msg->data) - msg->data_length, " [PROCESSED]"); msg->data_length += 12; // 4. 更新校验和 msg->checksum = calc_checksum; } } // 接收任务函数 void receiver_task(void *p_arg) { OS_ERR err; OS_MSG_SIZE msg_size; volatile CPU_INT32U i; // 用于简单延时 while(1) { // 从接收队列获取消息 APP_MSG *final_msg = (APP_MSG*)OSQPend((OS_Q *)&RecvQueue, (OS_TICK )0, (OS_OPT )OS_OPT_PEND_BLOCKING, (OS_MSG_SIZE *)&msg_size, (CPU_TS *)0, (OS_ERR *)&err); if (err == OS_ERR_NONE) { // 闪烁LED2表示接收成功 LED2_ON(); for(i = 0; i < 100000; i++); // 打印消息详情 print_message(final_msg); // 释放消息内存 OSMemPut(MsgPool, (void*)final_msg, &err); LED2_OFF(); } // 短暂延迟 OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_DLY, &err); } } // 消息打印函数 void print_message(APP_MSG *msg) { printf("\n[RECEIVER] Message %d Details:\n", msg->msg_id); printf(" Length: %d bytes\n", msg->data_length); printf(" Checksum: %u\n", msg->checksum); printf(" Content: %s\n", msg->data); } ``` ## 三任务消息处理系统说明 ### 1. 任务分工 - **发送任务 (Sender Task)**: - 优先级最低 (8) - 每2秒创建一条新消息 - 填充消息ID和内容 - 计算并存储校验和 - 发送消息到处理队列 - 使用LED0指示发送状态 - **处理任务 (Processor Task)**: - 中等优先级 (7) - 从发送队列接收消息 - 验证消息校验和 - 处理消息数据(转换为大写) - 添加处理标记 - 发送处理后的消息到接收队列 - 使用LED1指示处理状态 - **接收任务 (Receiver Task)**: - 最高优先级 (6) - 从接收队列获取消息 - 打印消息详细信息 - 释放消息内存 - 使用LED2指示接收状态 ### 2. 消息队列设计 - **SendQueue**: 发送任务 → 处理任务 - **RecvQueue**: 处理任务 → 接收任务 ### 3. 消息处理流程 ```mermaid graph LR A[发送任务] -->|发送消息| B[SendQueue] B --> C[处理任务] C -->|处理消息| D[RecvQueue] D --> E[接收任务] ``` ### 4. 消息结构体 ```c typedef struct { CPU_INT16U msg_id; // 消息唯一标识 CPU_INT16U data_length; // 数据长度 CPU_CHAR data[50]; // 消息内容 CPU_INT32U checksum; // 数据校验和 } APP_MSG; ``` ## 关键功能实现详解 ### 1. 内存管理 ```c // 初始化内存池 void init_memory_pool(void) { OS_ERR err; MsgPool = OSMemCreate((void*)&MsgMemory[0], MSG_POOL_SIZE, sizeof(APP_MSG), &err); } // 发送任务获取消息内存 APP_MSG *new_msg = (APP_MSG*)OSMemGet(MsgPool, &err); // 接收任务释放消息内存 OSMemPut(MsgPool, (void*)final_msg, &err); ``` ### 2. 消息校验和计算与验证 ```c // 发送任务计算校验和 new_msg->checksum = 0; for (int i = 0; i < new_msg->data_length; i++) { new_msg->checksum += new_msg->data[i]; } // 处理任务验证校验和 CPU_INT32U calc_checksum = 0; for (int i = 0; i < received_msg->data_length; i++) { calc_checksum += received_msg->data[i]; } if (calc_checksum != received_msg->checksum) { // 校验和错误处理 } ``` ### 3. 消息数据处理 ```c // 转换为大写 for (int i = 0; i < received_msg->data_length; i++) { if (received_msg->data[i] >= 'a' && received_msg->data[i] <= 'z') { received_msg->data[i] = received_msg->data[i] - 'a' + 'A'; } } // 添加处理标记 snprintf(received_msg->data + received_msg->data_length, sizeof(received_msg->data) - received_msg->data_length, " [PROCESSED]"); received_msg->data_length += 12; ``` ## 系统特点 1. **健壮的消息验证**: - 校验和验证确保数据完整性 - 错误消息特殊标记 - 内存池管理避免内存碎片 2. **可视化状态指示**: - LED0:发送任务状态指示 - LED1:处理任务状态指示 - LED2:接收任务状态指示 3. **优先级设计**: - 接收任务优先级最高 (6) - 处理任务中等优先级 (7) - 发送任务最低优先级 (8) - 确保消息及时处理 4. **错误处理**: - 校验和错误检测 - 内存分配失败处理 - 消息队列操作错误检查 ## 预期输出示例 ``` [RECEIVER] Message 0 Details: Length: 22 bytes Checksum: 313 Content: MESSAGE #0 [PROCESSED] [RECEIVER] Message 1 Details: Length: 22 bytes Checksum: 314 Content: MESSAGE #1 [PROCESSED] [RECEIVER] Message 2 Details: Length: 38 bytes Checksum: 315 Content: Message #2 [CHECKSUM ERROR] ``` 这个三任务消息传递系统完整实现了消息的创建、发送、处理和接收流程,包含了严格的消息验证和处理机制,并通过LED提供直观的状态反馈。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值