BetaFlight模块设计之三十七:SBUS

news2024/11/24 0:22:38

BetaFlight模块设计之三十七:SBUS

  • 1. 源由
  • 2. sbus启动&动态任务
  • 3. 主要函数
    • 3.1 sbus初始化
    • 3.2 sbusFrameStatus更新
    • 3.3 rxFrameTimeUs
    • 3.4 sbusDataReceive接收数据
  • 4. 辅助函数
    • 4.1 sbusChannelsDecode
  • 5. 参考资料

1. 源由

接着BetaFlight模块设计之三十六:SoftSerial,就Betaflight关于STM32F405 SBUS协议兼容硬件电气特性问题的代码支持问题做一个研读,看看目前设计上这个框架代码是否支持SBUS。

2. sbus启动&动态任务

main
 └──> init
     └──> rxInit
         └──> serialRxInit
             └──> sbusInit
main
 └──> run
     └──> scheduler
         └──> rxFrameCheck
             └──> rcFrameStatusFn(sbusFrameStatus)

[TASK_RX] = DEFINE_TASK("RX", NULL, rxUpdateCheck, taskUpdateRxMain, TASK_PERIOD_HZ(33), TASK_PRIORITY_HIGH), // If event-based scheduling doesn't work, fallback to periodic scheduling
 └──> taskUpdateRxMain
     └──> processRx
         └──> updateRcRefreshRate
             └──> rxGetFrameDelta
                 └──> rcFrameTimeUsFn(rxFrameTimeUs)

3. 主要函数

3.1 sbus初始化

sbusInit
 │   //支持SBUS_MAX_CHANNEL(18)个通道
 ├──> static uint16_t sbusChannelData[SBUS_MAX_CHANNEL];
 ├──> static sbusFrameData_t sbusFrameData;
 ├──> static uint32_t sbusBaudRate;
 │
 ├──> rxRuntimeState->channelData = sbusChannelData;
 ├──> rxRuntimeState->frameData = &sbusFrameData;
 │
 │   //初始化通道数据
 ├──> sbusChannelsInit(rxConfig, rxRuntimeState);
 │
 ├──> rxRuntimeState->channelCount = SBUS_MAX_CHANNEL;
 │
 │   //配置波特率SBUS_FAST_BAUDRATE(200000)/SBUS_BAUDRATE(6000)
 ├──> <rxConfig->sbus_baud_fast>
 │   └──> sbusBaudRate  = SBUS_FAST_BAUDRATE;
 ├──> < else >
 │   └──> sbusBaudRate  = SBUS_BAUDRATE;
 │
 │   //挂两个钩子函数:sbusFrameStatus/rxFrameTimeUs
 ├──> rxRuntimeState->rcFrameStatusFn = sbusFrameStatus;
 ├──> rxRuntimeState->rcFrameTimeUsFn = rxFrameTimeUs;
 │
 ├──> const serialPortConfig_t *portConfig = findSerialPortConfig(FUNCTION_RX_SERIAL);
 ├──> <!portConfig>
 │   └──> return false;
 │
 ├──> <USE_TELEMETRY>
 │   └──> bool portShared = telemetryCheckRxPortShared(portConfig, rxRuntimeState->serialrxProvider);
 ├──> <#else>
 │   └──> bool portShared = false;
 │
 │   //端口初始化,回调函数sbusDataReceive
 ├──> serialPort_t *sBusPort = openSerialPort(portConfig->identifier,
 │      FUNCTION_RX_SERIAL,
 │      sbusDataReceive,
 │      &sbusFrameData,
 │      sbusBaudRate,
 │      portShared ? MODE_RXTX : MODE_RX,
 │      SBUS_PORT_OPTIONS | (rxConfig->serialrx_inverted ? 0 : SERIAL_INVERTED) | (rxConfig->halfDuplex ? SERIAL_BIDIR : 0))
 ├──> <rxConfig->rssi_src_frame_errors>
 │   └──> rssiSource = RSSI_SOURCE_FRAME_ERRORS;
 │
 ├──> <USE_TELEMETRY><portShared>
 │   └──> telemetrySharedPort = sBusPort;
 └──> return sBusPort != NULL;

3.2 sbusFrameStatus更新

sbusFrameStatus
 │   //检查帧状态
 ├──> sbusFrameData_t *sbusFrameData = rxRuntimeState->frameData;
 ├──> <!sbusFrameData->done>
 │   └──> return RX_FRAME_PENDING;
 │
 ├──> sbusFrameData->done = false;
 │
 ├──> DEBUG_SET(DEBUG_SBUS, DEBUG_SBUS_FRAME_FLAGS, sbusFrameData->frame.frame.channels.flags);
 │   //帧数据解码
 ├──> const uint8_t frameStatus = sbusChannelsDecode(rxRuntimeState, &sbusFrameData->frame.frame.channels);
 │
 │   //更新最近一次有效帧时间戳
 ├──> <!(frameStatus & (RX_FRAME_FAILSAFE | RX_FRAME_DROPPED))>
 │   └──> rxRuntimeState->lastRcFrameTimeUs = sbusFrameData->startAtUs;
 │
 └──> return frameStatus;
 
typedef enum {
    RX_FRAME_PENDING = 0,
    RX_FRAME_COMPLETE = (1 << 0),
    RX_FRAME_FAILSAFE = (1 << 1),
    RX_FRAME_PROCESSING_REQUIRED = (1 << 2),
    RX_FRAME_DROPPED = (1 << 3)
} rxFrameState_e;

3.3 rxFrameTimeUs

获取最近一帧有效数据的时间。

timeUs_t rxFrameTimeUs(void)
{
    return rxRuntimeState.lastRcFrameTimeUs;
}

3.4 sbusDataReceive接收数据

在这里插入图片描述

sbusDataReceive
 ├──> sbusFrameData_t *sbusFrameData = data;
 ├──> const timeUs_t nowUs = microsISR();
 ├──> const timeDelta_t sbusFrameTime = cmpTimeUs(nowUs, sbusFrameData->startAtUs);
 │
 │   //超时500,从新SBUS数据帧开始算(数据中断异常)
 ├──> <sbusFrameTime > (long)(SBUS_TIME_NEEDED_PER_FRAME + 500)>
 │   └──> sbusFrameData->position = 0;
 │
 │   //确保帧起始位置
 ├──> <sbusFrameData->position == 0>
 │   ├──> <c != SBUS_FRAME_BEGIN_BYTE>
 │   │   └──> return;
 │   └──> sbusFrameData->startAtUs = nowUs;
 │
 │   //读取一帧数据
 └──> <sbusFrameData->position < SBUS_FRAME_SIZE>
     ├──> sbusFrameData->frame.bytes[sbusFrameData->position++] = (uint8_t)c;
     ├──> <sbusFrameData->position < SBUS_FRAME_SIZE>
     │   └──> sbusFrameData->done = false;
     └──> < else >
         ├──> sbusFrameData->done = true;
         └──> DEBUG_SET(DEBUG_SBUS, DEBUG_SBUS_FRAME_TIME, sbusFrameTime);

typedef struct sbusChannels_s {
    // 176 bits of data (11 bits per channel * 16 channels) = 22 bytes.
    unsigned int chan0 : 11;
    unsigned int chan1 : 11;
    unsigned int chan2 : 11;
    unsigned int chan3 : 11;
    unsigned int chan4 : 11;
    unsigned int chan5 : 11;
    unsigned int chan6 : 11;
    unsigned int chan7 : 11;
    unsigned int chan8 : 11;
    unsigned int chan9 : 11;
    unsigned int chan10 : 11;
    unsigned int chan11 : 11;
    unsigned int chan12 : 11;
    unsigned int chan13 : 11;
    unsigned int chan14 : 11;
    unsigned int chan15 : 11;
    uint8_t flags;
} __attribute__((__packed__)) sbusChannels_t;
#define SBUS_CHANNEL_DATA_LENGTH sizeof(sbusChannels_t)
#define SBUS_FRAME_SIZE (SBUS_CHANNEL_DATA_LENGTH + 2)

4. 辅助函数

4.1 sbusChannelsDecode

对通道数据进行译码,并根据接收机内部信息判别FAILSAFESIGNAL_LOSS事件。

sbusChannelsDecode
 │   //16通道赋值
 ├──> uint16_t *sbusChannelData = rxRuntimeState->channelData;
 ├──> sbusChannelData[0] = channels->chan0;
 ├──> sbusChannelData[1] = channels->chan1;
 ├──> sbusChannelData[2] = channels->chan2;
 ├──> sbusChannelData[3] = channels->chan3;
 ├──> sbusChannelData[4] = channels->chan4;
 ├──> sbusChannelData[5] = channels->chan5;
 ├──> sbusChannelData[6] = channels->chan6;
 ├──> sbusChannelData[7] = channels->chan7;
 ├──> sbusChannelData[8] = channels->chan8;
 ├──> sbusChannelData[9] = channels->chan9;
 ├──> sbusChannelData[10] = channels->chan10;
 ├──> sbusChannelData[11] = channels->chan11;
 ├──> sbusChannelData[12] = channels->chan12;
 ├──> sbusChannelData[13] = channels->chan13;
 ├──> sbusChannelData[14] = channels->chan14;
 ├──> sbusChannelData[15] = channels->chan15;
 │
 │   //根据Flag标识赋值MAX/MIN
 ├──> <channels->flags & SBUS_FLAG_CHANNEL_17>
 │   └──> sbusChannelData[16] = SBUS_DIGITAL_CHANNEL_MAX;
 ├──> < else >
 │   └──> sbusChannelData[16] = SBUS_DIGITAL_CHANNEL_MIN;
 │
 │   //根据Flag标识赋值MAX/MIN
 ├──> <channels->flags & SBUS_FLAG_CHANNEL_18>
 │   └──> sbusChannelData[17] = SBUS_DIGITAL_CHANNEL_MAX;
 ├──> < else >
 │   └──> sbusChannelData[17] = SBUS_DIGITAL_CHANNEL_MIN;
 │
 │   //接收机标识FAILSAFE
 ├──> <channels->flags & SBUS_FLAG_FAILSAFE_ACTIVE>
 │   │  // internal failsafe enabled and rx failsafe flag set
 │   │  // RX *should* still be sending valid channel data (repeated), so use it.
 │   └──> return RX_FRAME_COMPLETE | RX_FRAME_FAILSAFE;
 │
 │   //接收机标识SIGNAL_LOSS
 ├──> <channels->flags & SBUS_FLAG_SIGNAL_LOSS>
 │   │  // The received data is a repeat of the last valid data so can be considered complete.
 │   └──> return RX_FRAME_COMPLETE | RX_FRAME_DROPPED;
 │
 └──> return RX_FRAME_COMPLETE;

5. 参考资料

【1】BetaFlight开源代码框架简介
【2】BetaFlight模块设计之三十六:SoftSerial
【3】Betaflight关于STM32F405 SBUS协议兼容硬件电气特性问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1258855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

西北大学计算机844考研-23年计网计算题详细解析

西北大学计算机844考研-23年计网计算题详细解析 1.计算无传输差错状态下停止—等待ARQ协议效率,电磁波传播速率为2*10^8m/s&#xff0c;链路长为2000m&#xff0c;帧长度为1000比特&#xff0c;计算传输速率10kbps及10Mbps时的协议效率&#xff08;即信道利用率&#xff09; …

医院绩效考核管理系统项目源码

医院绩效考核体系该如何完善 一、合理制定绩效指标 绩效指标是医院绩效考核体系的重要部分&#xff0c; 而医院各科室的工作方法和目的各不相同、职责也不同。因此&#xff0c;医院要重视绩效指标的制定&#xff0c;并且从实际出发&#xff0c;根据各科室情况合理制定个性化的…

Pytorch 基于 deeplabv3_resnet50 迁移训练自己的图像语义分割模型

一、图像语义分割 图像语义分割是计算机视觉领域的一项重要任务&#xff0c;旨在将图像中的每个像素分配到其所属的语义类别&#xff0c;从而实现对图像内容的细粒度理解。与目标检测不同&#xff0c;图像语义分割要求对图像中的每个像素进行分类&#xff0c;而不仅仅是确定物…

华夏ERP信息泄露漏漏洞复现 [附POC]

文章目录 华夏ERP信息泄露漏漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 华夏ERP信息泄露漏漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#x…

深思:C与C++相互调用问题

背景 上周&#xff0c;偶然看到同事愁眉苦脸的样子&#xff0c;便善意咨询了下发生了什么。简单沟通下&#xff0c;才知道他遇到了一个工程编译的问题&#xff0c;一直无法编译通过&#xff0c;困扰了他快一天时间。出于个人的求知欲和知识的渴望&#xff0c;我便主动与他一同分…

动态规划学习——等差子序列问题

目录 一&#xff0c;最长等差子序列 1.题目 2.题目接口 3.解题思路及其代码 二&#xff0c;等差序列的划分——子序列 1.题目 2.题目接口 3.解题思路及其代码 一&#xff0c;最长等差子序列 1.题目 给你一个整数数组 nums&#xff0c;返回 nums 中最长等差子序列的长度…

M3u8视频文件怎么转换成MP4?一分钟解决!

大部分网课平台或者视频平台&#xff0c;都是基于m3u8格式的&#xff0c;这是因为m3u8格式本身的特点&#xff0c;既支持直播又支持点播。但是往往在其他平台或者设备上不兼容&#xff0c;就需要转成MP4格式&#xff0c;那么就像大家介绍3种好用的方法~ 方法一&#xff1a;使用…

详解HTTP协议(介绍--版本--工作过程--Fiddler 抓包显示--请求响应讲解)

目录 一.HTTP协议的介绍 1.1HTTP是什么&#xff1f; 1.2HTTP版本的演变 二.HTTP的工作过程 三.使用Fiddler抓包工具 3.1简单讲解Fiddler 3.2Fiddler工作的原理 3.3抓包结果分析 四.HTTP请求 4.1认识URL 4.2关于URL encode 4.3认识方法 4.3.1认识get和post 4.3.…

Fiddler弱网测试究竟该怎么做?

前言 使用Fiddler对手机App应用进行抓包&#xff0c;可以对App接口进行测试&#xff0c;也可以了解App传输中流量使用及请求响应情况&#xff0c;从而测试数据传输过程中流量使用的是否合理。 抓包过程&#xff1a; 1、Fiddler设置 1&#xff09;启动Fiddler->Tools->…

易点天下携AIGC创新成果KreadoAI亮相数贸会,解锁电商文化出海新可能

11月27日&#xff0c;第二届全球数字贸易博览会&#xff08;以下简称“数贸会”&#xff09;在浙江杭州完美落幕。作为出海营销领域最早一批布局AIGC战略的营销科技公司&#xff0c;易点天下受邀与来自全球800余家境内外数字贸易企业同台参展&#xff0c;并分享了旗下AIGC数字营…

拦截器使用详解

什么是拦截器? 拦截器是 Spring 框架提供的核⼼功能之⼀,主要⽤来拦截⽤户的请求, 在指定⽅法前后,根据业务需要执行预先设定的代码. 也就是说,允许开发⼈员提前预定义⼀些逻辑,在请求访问接口前/后执行.也可以在⽤户请求前阻止其进入接口执行 在拦截器当中&#xff0c;开发⼈…

广西铁塔发布ZETag定位服务,快递物流可视化将成趋势

在万亿的快递、物流红海市场中&#xff0c;可视化或将成为凸显差异化优势的一枚棋子。 11月17日&#xff0c;中国铁塔股份有限公司广西壮族自治区分公司&#xff08;以下简称“广西铁塔”&#xff09;在广西南宁召开“万物智联&#xff0c;贴‘芯’服务”物联网产品发布会&…

UE5富文本框学习(用途:A(名字)用刀(图片)击杀B(名字))

UE5-UMG教程-通用控件&#xff1a;多格式文本块&#xff08;RichTextBlock&#xff09;_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Pu4y1k7Z2/?p54&spm_id_frompageDriver 结果示例&#xff1a; 1.添加富文本框 2.添加文字样式库 点添加&#xff0c;更改每行行…

又又又重新刷题的第一天第一天第一天,这次目标是top100一定要刷完整至少一次两次吧:1/150:两数之和 2/150两数相加 3/150无重复字符的最长字串

题目1/150&#xff1a;两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重…

智慧工厂人员定位系统源码,融合位置物联网、GIS可视化等技术,实现对人员、物资精确定位管理

智慧工厂人员定位系统源码&#xff0c;UWB高精度定位系统源码 随着中国经济发展进入新常态&#xff0c;在资源和环境约束不断强化的背景下&#xff0c;创新驱动传统制造向智能制造转型升级&#xff0c;越发成为企业生存发展的关键。智能工厂作为实现智能制造的重要载体&#xf…

电商平台为什么要使用CDN加速?

随着电商零售市场的成熟&#xff0c;消费者越来越关注购物体验。电商零售平台的响应速度、稳定性和安全性&#xff0c;均可能直接影响用户购买欲和用户转化率。如何进一步提升用户体验成为电商零售企业在市场决胜的关键。 阿里云全站加速DCDN全球覆盖3200节点&#xff0c;在提…

【知网稳定检索】2024年应用经济学,管理科学与社会发展国际学术会议(AEMSS 2024)

2024年应用经济学&#xff0c;管理科学与社会发展国际学术会议&#xff08;AEMSS 2024&#xff09; 2024 International Conference on Applied Economics, Management Science and Social Development 2024年应用经济学&#xff0c;管理科学与社会发展国际学术会议&#xff…

无公网IP下,如何实现公网远程访问MongoDB文件数据库

文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射2.3 测试随机公网地址远程连接 3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问 前言 MongoDB是一个基于分布式文件存储的数…

即时电商需求快速爆发,商城系统平台的安全性如何保障?

双11的狂欢刚刚落下帷幕&#xff0c;留下的不仅是消费者的购物满足和品牌商家的销售增长&#xff0c;更让我们看到了一个行业变革的微妙暗示。 回溯这场全民购物的盛大节日&#xff0c;我们不难发现&#xff0c;线下零售品牌在电商巨浪的冲击下&#xff0c;非但没有萎靡&#x…

2023年最值得推荐的数据分析平台,可能是它!

在知乎上&#xff0c;商业数据分析和可视化是热门话题&#xff0c;其中Tableau和PowerBI是讨论最多的两个工具。随着数据分析行业的快速发展&#xff0c;利用这两个工具生成可视化dashboard并进行数据探索分析确实高效便捷。 作为一名数据分析爱好者&#xff0c;我也经常尝试各…