当前位置: 首页 > news >正文

基于LiteOS与SLE的多任务无线控制器项目实战

前言

在《LiteOS与SLE透传实战案例》中,介绍了SLE通信协议与LiteOS实时操作系统的基础知识与开发方法。本文将以实际项目为例,讲解如何将SLE与LiteOS应用于多任务无线控制器的完整开发流程,包括架构设计、关键代码、软硬件协同、调试方法等,帮助理解相关技术。

文章目录

    • 前言
    • 一、项目简介
    • 二、项目架构与功能特性
      • 1. 系统架构概览
      • 2. 主要功能特性
    • 三、作者与开源信息
    • 四、硬件要求
    • 五、接口定义
      • ADC 接口
      • I2C 接口
    • 六、项目结构
    • 七、软件依赖
    • 八、使用方法
    • 九、开发方式
    • 十、软件架构与主要模块
      • 1. LiteOS 多任务架构
        • 任务创建与优先级
      • 2. 队列与互斥锁
      • 3. 主要流程
      • 4. 其他细节
      • 5. 关键代码说明
        • 5.1 系统初始化与任务创建
        • 5.2 按键中断与校准流程
        • 5.3 摇杆输入与数据采集
        • 5.4 OLED 显示与内容切换
        • 5.5 SLE 通信与数据上报
        • 5.6 队列与互斥锁操作示例
    • 十一. LiteOS 相关说明
    • 十二. 按键说明
    • 十三. 运行与调试
    • 十四. 参考资料



一、项目简介

SLEController 是基于 Hispark ws63 核心板的多任务低延迟无线控制器项目,采用 C 语言开发,使用 LiteOS 实时操作系统。

项目支持多通道摇杆输入采集、OLED 实时数据显示、SLE 协议无线通信,适用于远程设备、无人机等场景。

二、项目架构与功能特性

1. 系统架构概览

项目采用多任务并发架构,任务间通过队列和互斥锁通信,确保数据采集、显示与传输的高效协同。

2. 主要功能特性

  • 摇杆数据采集与显示:支持4通道摇杆数据实时采集,OLED屏幕显示控制数据和状态,支持校准和内容切换。
  • SLE低延迟通信:支持Server模式,断开自动重连,实时上报数据,支持自定义设备名。
  • 多任务系统架构:并行处理采集、显示、传输、协议等多种功能,任务间高效通信与同步。
  • 异常处理与容错:外设初始化失败检测、队列读写失败提示、通信异常日志输出。
  • OLED显示优化:提升显示实时性和准确性,支持内容切换。
  • 测试模式切换:支持通过按键切换无人机测试模式,OLED显示当前模式编号。

三、作者与开源信息

  • Lamonce(flashier) - 嵌入式软件开发
  • 软件开源地址:SLEController - gitee/HiSpark/fbb_ws63
  • silenirt - 硬件设计
  • 硬件开源地址:星闪遥控器 - 立创开源硬件平台

四、硬件要求

  • Hispark ws63 开发板
  • SSD1306 OLED 显示屏(I2C 接口)
  • 硬件平台

五、接口定义

ADC 接口

  • ADC 通道 0-3:连接摇杆 X1、Y1、X2、Y2 轴
  • ADC 通道 5:连接电池电压采集

I2C 接口

  • 连接 SSD1306 OLED 显示屏

六、项目结构

SLEController/
├── sle_uart_server/                # SLE Server 相关驱动与头文件
│   ├── sle_uart_server_adv.c       # Server 端广播驱动实现
│   ├── sle_uart_server_adv.h       # Server 端广播头文件
│   ├── sle_uart_server.c           # Server 端驱动实现
│   └── sle_uart_server.h           # Server 端头文件
├── CMakeLists.txt                  # CMake 构建脚本
├── README.md                       # 项目说明文档
├── SLEController.c                 # 主程序入口
├── SSD1306_OLED.c                  # OLED 驱动实现
└── SSD1306_OLED.h                  # OLED 驱动头文件

七、软件依赖

  • Hispark Studio
  • 串口助手

八、使用方法

  1. 硬件连接

    • 焊接元器件
    • 将摇杆模块连接到 ADC 接口
    • 将 OLED 显示屏连接到 I2C 接口
  2. 烧录文件

    flash ws63-liteos-app_all.fwpkg / ws63-liteos-app_load_only.fwpkg
    
  3. 操作说明

    • 开机后系统自动初始化并进入摇杆校准状态,同时启动 SLE Server
    • SLE Server 端会自动广播设备信息,等待客户端连接
    • Server 端和 Client 端通过 Local Name 进行连接,默认名称为 NearLink(代码参考sle_uart - gitee/bearpi/bearpi-pico_h3863)
    • 将摇杆向四个方向移动,系统会自动校准并显示当前摇杆状态,找到摇杆最大值(最小值默认为 0)
    • 完成校准后按下 KEY3 以退出校准状态
    • OLED 显示当前摇杆数据和状态信息,按 KEY3 切换显示内容
    • 摇杆操作将直接反映在 OLED 屏幕上
    • 控制数据会通过 SLE 框架实时传输
    • 按下 KEY6 可切换测试模式(模式相应操作由用户自定义),OLED 显示当前模式编号

九、开发方式

本项目采用 C 语言开发,基于 Hispark Studio 、HUAWEI LiteOS 和 SLE 通信框架。

十、软件架构与主要模块

1. LiteOS 多任务架构

本项目基于 LiteOS,采用多任务并发设计。

主要任务如下:

  • JoystickInputTask

    • 初始化 ADC,采集 4 路摇杆原始数据和电池电压
    • 校准阶段自动记录最大值,按下 KEY3 结束校准
    • 数据写入 joystick_data_queueID(摇杆数据队列)和 battery_voltage_queueID(电池电压队列)
    • 校准完成后,计算百分比数据写入 SLE_Transfer_QueueID,并对中值做抖动校准
  • OLEDDisplayTask

    • 初始化 OLED 屏幕,显示内容包括摇杆原始数据、百分比、电池电压、SLE 连接状态、测试模式等
    • 支持按下 KEY3 切换显示内容(摇杆/状态/测试模式)
    • 通过互斥锁 g_mux_id 保证 OLED 与 ADC 初始化顺序,防止资源冲突
  • SELSendTask

    • 负责将摇杆百分比数据通过 SLE 框架实时发送给客户端
    • SLE_Transfer_QueueID 读取数据,判断连接状态后进行数据上报
  • sle_uart_server_task

    • 负责 SLE Server 端的消息队列管理、广播和连接状态维护
    • 通过设备名 sle_local_name 进行连接,断开时自动重启广播
任务创建与优先级

系统初始化时,依次创建上述任务,并设置合理的优先级,确保数据采集、显示与传输的高效协同。

2. 队列与互斥锁

  • joystick_data_queueID:摇杆原始数据队列,供 JoystickInputTask 写入,OLEDDisplayTask 读取
  • battery_voltage_queueID:电池电压数据队列,供 JoystickInputTask 写入,OLEDDisplayTask 读取
  • SLE_Transfer_QueueID:摇杆百分比数据队列,供 JoystickInputTask 写入,SELSendTask 读取
  • g_sle_uart_server_msgqueue_id:SLE Server 端内部消息队列
  • g_mux_id:互斥锁,保证 OLED 与 ADC 初始化顺序

3. 主要流程

  1. 系统启动:初始化 GPIO、队列、互斥锁,依次创建各任务
  2. 摇杆校准:上电后进入校准,移动摇杆采集最大值,按 KEY3 结束校准
  3. 数据采集与显示:ADC 任务持续采集数据,OLED 任务实时显示,支持内容切换
  4. 数据传输:SELSendTask 任务将百分比数据通过 SLE 实时上报,Server 端断开自动重连广播
  5. 异常处理:各任务均有错误检测与日志输出

4. 其他细节

  • 支持通过修改 sle_local_name 更改 SLE 设备名。
  • 电池电压采集采用分压方式,已在代码中做换算。
  • 按键 KEY3 既用于校准结束,也用于显示切换。
  • 按键 KEY6 用于切换无人机测试模式,OLED 显示当前模式编号。
  • 所有任务均有详细日志输出,便于调试。

5. 关键代码说明

5.1 系统初始化与任务创建

系统初始化主要负责硬件引脚、消息队列、互斥锁的创建,并依次启动各功能任务。通过合理的任务划分与优先级设置,实现数据采集、显示、通信等功能的高效并发。

static void sysInit(void)
{pin_init(); // 初始化 GPIO 引脚osal_msg_queue_create("Joystick_Data_Queue", ...); // 创建摇杆数据队列osal_msg_queue_create("SLE_Transmit_Queue", ...); // 创建 SLE 传输队列osal_msg_queue_create("Battery_Voltage_Queue", ...); // 创建电池电压队列osal_mutex_init(&g_mux_id); // 初始化互斥锁// 创建各任务osal_kthread_create((osal_kthread_handler)JoystickInputTask, ...);osal_kthread_create((osal_kthread_handler)OLEDDisplayTask, ...);osal_kthread_create((osal_kthread_handler)SELSendTask, ...);osal_kthread_create((osal_kthread_handler)sle_uart_server_task, ...);
}
5.2 按键中断与校准流程
static void ButtonISR_KEY3(void)
{if (joystick_ready_index == false) // 校准阶段joystick_ready_index = true;else // 切换 OLED 显示内容OLED_display_index = (OLED_display_index + 1) % 3;
}static void ButtonISR_KEY6(void)
{test_flag = (test_flag + 1) % 3; // 切换测试模式
}
5.3 摇杆输入与数据采集
static void *JoystickInputTask(void)
{uapi_adc_init(ADC_CLOCK_NONE); // 初始化ADC// ...省略部分初始化...while (true) {adc_port_read(...); // 读取各通道ADC// 写入队列osal_msg_queue_write_copy(joystick_data_queueID, &joystick_data, sizeof(joystick_data), 0xff);// 校准后计算百分比if (joystick_ready_index == true) {sle_send_data.adc_ch0_percent = (joystick_data.adc_ch0 * 100) / joystick_adc_default_value0;// ...同理处理其它通道...sle_send_data.is_test_mode = test_flag;osal_msg_queue_write_copy(SLE_Transfer_QueueID, &sle_send_data, sizeof(sle_send_data), 0xff);}// 电池电压采集osal_msg_queue_write_copy(battery_voltage_queueID, &BAT_Vol, sizeof(BAT_Vol), 0xff);osal_msleep(ADC_DELAY_TIME);}
}
5.4 OLED 显示与内容切换
static void *OLEDDisplayTask(void)
{// ...初始化I2C和OLED...while (true) {// 读取队列数据osal_msg_queue_read_copy(joystick_data_queueID, &joystick_rcv_data, ...);osal_msg_queue_read_copy(battery_voltage_queueID, &battery_voltage, ...);if (OLED_display_index == 0) {// 显示摇杆百分比} else if (OLED_display_index == 1) {// 显示SLE连接状态、电池电压} else if (OLED_display_index == 2) {// 显示测试模式编号}}
}
5.5 SLE 通信与数据上报
static void *SELSendTask(void)
{while (true) {osal_msg_queue_read_copy(SLE_Transfer_QueueID, &sle_send_data, ...);if (sle_uart_client_is_connected()) {sle_uart_server_send_report_by_handle((uint8_t *)data_string, strlen(data_string));}}
}static void *sle_uart_server_task(const char *arg)
{sle_uart_server_create_msgqueue();sle_uart_server_register_msg(sle_uart_server_write_msgqueue);sle_uart_server_init(...);while (1) {sle_uart_server_receive_msgqueue(rx_buf, &rx_length);// 未连接则自动广播if (未连接) sle_start_announce(...);}
}
5.6 队列与互斥锁操作示例
// 创建队列
osal_msg_queue_create("QueueName", QUEUE_SIZE, &queueID, 0, NODE_SIZE);
// 写入队列
osal_msg_queue_write_copy(queueID, &data, sizeof(data), 0xff);
// 读取队列
osal_msg_queue_read_copy(queueID, &data, &msgSize, OSAL_WAIT_FOREVER);
// 互斥锁
osal_mutex_init(&g_mux_id);
osal_mutex_lock(&g_mux_id);
osal_mutex_unlock(&g_mux_id);

十一. LiteOS 相关说明

本项目基于 LiteOS,任务、队列、互斥锁等均采用 LiteOS API 实现。详细用法可参考:

  • LiteOS与SLE透传实战案例

主要用到的 LiteOS API 包括:

  • osal_kthread_create:创建任务
  • osal_msg_queue_create:创建消息队列
  • osal_mutex_init / osal_mutex_lock / osal_mutex_unlock:互斥锁操作
  • osal_msg_queue_write_copy / osal_msg_queue_read_copy:队列读写
  • osal_printk:日志输出

十二. 按键说明

  • KEY3:用于摇杆校准及切换 OLED 显示内容
  • KEY6:切换无人机测试模式,OLED 显示当前模式编号
  • 各按键功能可自定义

十三. 运行与调试

  1. 硬件连接:
    • 摇杆模块连接 ADC 接口
    • OLED 显示屏连接 I2C 接口
  2. 烧录固件:
    flash ws63-liteos-app_all.fwpkg / ws63-liteos-app_load_only.fwpkg
    
  3. 上电后自动进入校准,按 KEY3 结束校准,OLED 实时显示数据
  4. 通过 SLE 框架无线传输数据,可用 QCOM 串口助手等工具调试

十四. 参考资料

  • SLE 代码参考:https://gitee.com/bearpi/bearpi-pico_h3863/tree/master/application/samples/products/sle_uart
  • ws63 开发板资料:https://gitee.com/HiSpark/fbb_ws63/tree/master
  • SSD1306 OLED 驱动资料:https://item.szlcsc.com/datasheet/HS96L03W2C03/5960631.html?spm=sc.it.xds.a___sc.cidn.xh1.zy.n&lcsc_vid=FVlXAlZWFlUIX11XR1JXV11QTlNcUAFfFgdeU1EDRlgxVlNTRlhZX1JSQFlaUztW

如需进一步定制或移植,请参考源码注释与 LiteOS 官方文档。

http://www.dtcms.com/a/270286.html

相关文章:

  • 深圳凭物联网软件开发构建智慧‘城市大脑‘
  • 什么是 3D 文件?
  • UE material advance 学习笔记
  • 【时时三省】(C语言基础)怎样引用指针变量
  • 免安装图片修改软件,一键批量处理
  • 16018.UE4+Airsim仿真环境搭建
  • 详细页智能解析算法:洞悉海量页面数据的核心技术
  • 软件系统测试的基本流程
  • 【PyTorch项目实战】VisRAG:基于视觉的多模态文档检索增强生成(文本+图像)
  • Android 事件分发机制深度解析
  • Android 中的多线程编程全面解析
  • YOLO融合[ICLR2025]PolaFormer中的极性感知线性注意力
  • docker proxy
  • C 解压文件
  • Day55 序列预测任务介绍
  • Subject vs Flowable vs Observable 对比
  • 【零基础学AI】第31讲:目标检测 - YOLO算法
  • 每日算法刷题Day44 7.8:leetcode前缀和4道题,用时1h40min
  • JVM 为什么使用元空间(Metaspace)替换了永久代(PermGen)?——深入理解 Java 方法区与类元数据存储的演进
  • 视频能转成gif动图吗?怎么弄?
  • [NOIP][C++]洛谷P1376 [USACO05MAR] Yogurt factory 机器工厂
  • 没合适的组合wheel包,就自行编译flash_attn吧
  • 行业实践案例:金融行业数据治理体系全景解析
  • Java 关键字详解:掌握所有保留关键字的用途与最佳实践
  • Apache Atlas编译打包,可运行包下载地址
  • DMA技术与音频数据的存储和播放
  • C++STL-vector
  • 【c++学习记录】状态模式,实现一个登陆功能
  • 笔试——Day1
  • numpy数据分析知识总结