【FreeRTOS】第七课(4):任务间的通信——一个设备的数据写入多个队列
目录
一、程序框架
二、代码示例
1.游戏层
数据获取层
一、程序框架
红外遥控框架
二、代码示例
1.游戏层
/**************************************变量创建**************************************/
struct car {int x;int y;int control_key;
};struct car g_cars[3] = {{0, 0, IR_KEY_1},{0, 17, IR_KEY_2},{0, 34, IR_KEY_3},
};/**************************************任务函数**************************************/
static void CarTask(void *params)
{struct car *pcar = params;struct ir_data idata;/* 创建获取红外遥控器解析数据的队列 */QueueHandle_t xQueueIR = xQueueCreate(10, sizeof(struct ir_data));/* 注册队列 */RegisterQueueHandle(xQueueIR);/* 显示汽车 */ShowCar(pcar);while (1){/* 读取按键值:读队列 */xQueueReceive(xQueueIR, &idata, portMAX_DELAY);if (idata.val == pcar->control_key){/* 如果没有到最右边,控制汽车往右移动 */if (pcar->x < g_xres - CAR_LENGTH){/* 隐藏汽车 */HideCar(pcar);/* 调整位置 */pcar->x += 20;if (pcar->x > g_xres - CAR_LENGTH){pcar->x = g_xres - CAR_LENGTH;}/* 重新显示汽车 */ShowCar(pcar);}}}
}/**************************************游戏函数**************************************/
void car_game(void)
{/* 其他代码 */.../* 创建了三个汽车任务,每个汽车任务中都有创建获取红外遥控器解析数据的队列并将自己的队列句柄写入注册数组的操作 */xTaskCreate(CarTask, "car1", 128, &g_cars[0], osPriorityNormal, NULL);xTaskCreate(CarTask, "car2", 128, &g_cars[1], osPriorityNormal, NULL);xTaskCreate(CarTask, "car3", 128, &g_cars[2], osPriorityNormal, NULL);
}
数据获取层
static QueueHandle_t g_xQueueIR; /* 红外队列 *//* 用于保存注册的队列的句柄 */
static QueueHandle_t g_xQueues[10];
static int g_queue_cnt = 0;/* 注册队列 */
/* 每一个创建有自己队列的任务,如果想要获得红外遥控器的解析数据,就把自己的句柄保存在数组中 */
void RegisterQueueHandle(QueueHandle_t queueHandle)
{if (g_queue_cnt < 10){g_xQueues[g_queue_cnt] = queueHandle;g_queue_cnt++;}
}/* 此函数就是将IRReceiver_IRQTimes_Parse(void)中的xQueueSendFromISR()扩展为写入多个队列 */
static void DispatchKey(struct ir_data *pidata)
{
#if 0 extern QueueHandle_t g_xQueueCar1;extern QueueHandle_t g_xQueueCar2;extern QueueHandle_t g_xQueueCar3;xQueueSendFromISR(g_xQueueCar1, pidata, NULL);xQueueSendFromISR(g_xQueueCar2, pidata, NULL);xQueueSendFromISR(g_xQueueCar3, pidata, NULL);
#else/* 优化上面的代码,使用数组来保存队列 *//* 如果保存注册队列的数组未满 */int i;for (i = 0; i < g_queue_cnt; i++){/* 将数据写入数组中的每个队列*/xQueueSendFromISR(g_xQueues[i], pidata, NULL); }/* 之前挡球板游戏中创建的保存红外遥控器解析数据的队列也可以将自己的句柄传入数组,来获得红外遥控器解析数据,从而保证挡球板游戏也能玩 */
#endif
}/**********************采集并解析红外遥控数据保存进入红外队列**********************/
/* 处理原始数据 */
static int IRReceiver_IRQTimes_Parse(void)
{/* 写红外遥控原始数据队列 */struct ir_data data;data.dev = dev;data.val = val;/* 将数据分发给多个队列 */DispatchKey(&idata);return 0;
}/* 采集原始数据,回调数据处理函数 */
void IRReceiver_IRQ_Callback(void)
{/* 前置代码 */...IRReceiver_IRQTimes_Parse();
}