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 完美配合,实现数据上报功能。

相关推荐
Deitymoon17 小时前
STM32F103——超声波模块
stm32·单片机·嵌入式硬件
風清掦21 小时前
【STM32学习笔记-12】Unix 时间戳、BKP 备份寄存器与 RTC 实时时钟
笔记·stm32·单片机·嵌入式硬件·学习·实时音视频·unix
hoiii18721 小时前
基于STM32的扫地机器人源码工程
stm32·单片机·机器人
济6171 天前
ARM Linux 驱动开发篇---Linux字符设备驱动代码阅读指南---附设备树LED驱动实战案例
linux·嵌入式·嵌入式linux驱动开发
担水老头1 天前
蓝桥杯嵌入式赛道解决LCD和LED引脚冲突的问题
嵌入式
振南的单片机世界1 天前
EXTI边沿检测:上升沿、下降沿、双边沿,硬件自动捕捉
stm32·单片机·嵌入式硬件
莎士比亚的文学花园2 天前
stm32——平衡小车
stm32·单片机·嵌入式硬件
Hello_Embed2 天前
STM32CubeIDE 创建第1个工程
stm32·单片机·嵌入式·ai编程
炸膛坦客2 天前
嵌入式 - 数据结构与算法:(1-1)数据结构 - 顺序表(Sequential List)
数据结构·算法·嵌入式