FreeRTOS 上报任务设计---UplinkTask 上行数据上报任务详解

🎬 渡水无言个人主页渡水无言

专栏传送门 : 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》

专栏传送门 : 《freertos专栏》 《STM32 HAL库专栏》《linux裸机开发专栏

专栏传送门《产品测评专栏》《Ai智能体专栏

⭐️流水不争先,争的是滔滔不绝

📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生

| 省级优秀毕业生获得者 | csdn新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生

在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连

目录

前言

[一、UplinkTask 任务定位](#一、UplinkTask 任务定位)

二、全局时序交互图

[三、UplinkTask 完整代码](#三、UplinkTask 完整代码)

总结


前言

在前面的系列文章中,我们已经搭建起机器人下位机的三大核心任务:

CommTask 实现上位机指令解析。

ControlTask 完成底盘运动控制闭环。

SensorTask 构建整机状态感知体系。

SensorTask 通过系统状态快照机制,统一采集并缓存了电池电压、轮速、IMU 姿态等关键数据,但这些数据只有上传到上位机,才能实现可视化监控、远程调试、状态诊断等功能。

因此本篇我们实现 UplinkTask 上行数据上报任务 ,它专门负责:定时读取状态快照 → 协议组帧 → DMA 串口发送 → 上传至上位机


一、UplinkTask 任务定位

UplinkTask 是纯数据输出任务,不操作任何硬件传感器,只做三件事:

固定周期从 系统状态快照 安全读取系统状态。

按通信协议打包状态帧。

通过 USART1 + DMA 异步发送到上位机。

二、全局时序交互图

下面是整个系统 采集 → 快照 → 上报 → 发送 的完整时序流程,是整篇文章的核心图:

SensorTask 周期采集传感器数据,并原子写入全局快照。

UplinkTask 周期读取快照,不影响采集任务。

协议层组帧后,通过 DMA 异步发送。

发送完成 / 失败由 HAL 回调通知,释放发送标志。

发送繁忙时自动丢弃,不阻塞、不堆积。

全程无任务阻塞,架构干净、稳定、高效。

三、UplinkTask 完整代码

总体流程:

代码如下:

cpp 复制代码
/**
 ****************************************************************************************************
 * @file        uplink_task.c
 * @brief       上行状态上报任务(Uplink Task)
 * 本任务用于周期性向上位机发送系统状态信息,典型流程为:
 *
 *   SensorTask / ControlTask
 *           ↓
 *   SensorSnap_Get()(获取一次完整快照)
 *           ↓
 *   UplinkProto_SendStatus()
 *           ↓
 *   UART 发送(协议帧)
 *
****************************************************************************************************
 */

#include "uplink_task.h"
#include "FreeRTOS.h"
#include "task.h"
#include <stdint.h>
#include "log_task.h"
#include "control_task.h"
#include "uplink_proto.h"
#include "sensor_task.h"
#include "usart.h"
#include "protocol.h"
#include "monitor_task.h"

/* 上行周期(ms):1s 上报一次状态 */
#define UPLINK_PERIOD_MS      (1000u)

/**
 * @brief   上行状态上报任务入口
 * @details 周期性读取快照 → 协议组帧 → 串口DMA发送
 */
void KaoYaApp_UplinkTask(void *argument)
{
    (void)argument;

    /* 帧序号(用于上位机检测丢包/乱序) */
    uint8_t seq = 0;

    /* 初始化上行协议模块 */
    UplinkProto_Init();

    /* 上行协议帧缓存 */
    proto_uplink_t tx;

    /* 系统状态快照 */
    proto_status_t st;

    /* 周期调度基准 */
    TickType_t last_wake = xTaskGetTickCount();

    for (;;)
    {
        /* 1. 任务心跳:监控任务是否正常运行 */
        MON_HB_UPLINK();

        /* 2. 线程安全读取全局状态快照 */
        SensorSnap_Get(&st);

        /* 3. 协议打包并发送状态帧 */
        UplinkProto_SendStatus(&tx, seq++,
                               st.battery_mv, st.temp,
                               st.vx, st.vy, st.vz,
                               st.gx, st.gy, st.gz,
                               st.ax, st.ay, st.az);

#if UPLINK_KAOYATEACH_ENABLE
        /* 调试打印:上报内容输出 */
        uint32_t seq_sent = (uint32_t)(seq - 1u);
        LOGKAOYA_T("UPLINK", "==================UPLINK==================");
        LOGKAOYA_T("UPLINK", "【上报】STATUS 已发送:seq=%lu", (unsigned long)seq_sent);
        LOGKAOYA_T("UPLINK", "【电池】BAT=%u mV", (unsigned int)st.battery_mv);
        LOGKAOYA_T("UPLINK", "【温度】TEMP=%d C", (int)st.temp);
        LOGKAOYA_T("UPLINK", "【速度】v(mm/s)=(%d,%d,%d)", (int)st.vx, (int)st.vy, (int)st.vz);
        LOGKAOYA_T("UPLINK", "【角速度】g(0.01deg/s)=(%d,%d,%d)", (int)st.gx, (int)st.gy, (int)st.gz);
        LOGKAOYA_T("UPLINK", "【加速度】a(mg)=(%d,%d,%d)", (int)st.ax, (int)st.ay, (int)st.az);
#endif

        /* 4. 固定周期延时:1秒上报一次 */
        vTaskDelayUntil(&last_wake, pdMS_TO_TICKS(UPLINK_PERIOD_MS));
    }
}

总结

本篇实现的 UplinkTask 上行上报任务,与前面的 SensorTask 完美配合,实现数据上报功能。

相关推荐
星夜夏空992 小时前
STM32单片机学习(32) —— ADC
stm32·单片机·学习
少年、潜行6 小时前
【开源】基于STM32的无线姿态检测仪设计
stm32·嵌入式硬件·开源·姿态检测仪
三品吉他手会点灯8 小时前
STM32F103 学习笔记-22-DMA(第1节)-DMA功能框图讲解和DMA初始化结构体讲解
笔记·stm32·单片机·嵌入式硬件·学习
篮子里的玫瑰10 小时前
STM32/MCU【IAP在线升级】全流程深度解析与实战指南
stm32·单片机·嵌入式硬件
Plankton_Li11 小时前
嵌入式国密加密:STM32L4 + MIRACL 库实现 SM2 加解密
stm32·单片机·嵌入式软件
项目題供诗13 小时前
STM32-TIM输出比较(十二)
stm32·单片机·嵌入式硬件
星夜夏空9916 小时前
STM32单片机学习(28) —— STM32的SPI外设
stm32·单片机·学习
超级小星星16 小时前
west flash指令无法烧录STM32
linux·python·stm32
我叫张土豆16 小时前
STM32CubeProgrammer 用户手册
stm32·单片机·嵌入式硬件
嵌入式小站17 小时前
STM32 零基础可移植教程 08:串口接收一个字节,先把 RX 中断跑通
stm32·单片机·嵌入式硬件