BetaFlight模块设计之三十七:SBUS

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.mzph.cn/news/173943.shtml

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

相关文章

Leetcode—266.回文排列【简单】Plus

2023每日刷题&#xff08;四十&#xff09; Leetcode—266.回文排列 C语言实现代码 char chara[26] {0};int calculate(char *arr) {int nums 0;for(int i 0; i < 26; i) {nums arr[i];}return nums; }bool canPermutePalindrome(char* s) {int len strlen(s);for(in…

零基础在ubuntu上搭建rtmp服务器-srs

搭建服务器 搭建 SRS&#xff08;Simple-RTMP-Server&#xff09;服务器需要一些步骤&#xff0c;以下是一个简单的步骤指南。请注意&#xff0c;SRS 的配置可能会有所不同&#xff0c;具体取决于你的需求和环境。在开始之前&#xff0c;请确保你的 Ubuntu 系统已经连接到互联…

高效记账,轻松管理,批量记账与柱形图分析助你掌控收支明细

你是否曾经因为繁琐的记账过程而感到烦恼&#xff1f;是否曾经因为无法全面掌握个人或企业的收支情况而感到困惑&#xff1f;现在&#xff0c;我们为你带来了一种全新的高效记账方式&#xff0c;让你从此告别繁琐&#xff0c;轻松掌控收支明细。 首先第一步我们要打开晨曦记账…

商城免费搭建之java商城 鸿鹄云商 B2B2C产品概述

【B2B2C平台】&#xff0c;以传统电商行业为基石&#xff0c;鸿鹄云商支持“商家入驻平台自营”多运营模式&#xff0c;积极打造“全新市场&#xff0c;全新 模式”企业级B2B2C电商平台&#xff0c;致力干助力各行/互联网创业腾飞并获取更多的收益。从消费者出发&#xff0c;助…

pytest系列——pytest-xdist插件之多进程运行测试用例|| pytest-parallel插件之多线程运行测试用例

pytest之多进程运行测试用例(pytest-xdist) 前言 平常我们功能测试用例非常多时&#xff0c;比如有1千条用例&#xff0c;假设每个用例执行需要1分钟&#xff0c;如果单个测试人员执行需要1000分钟才能跑完当项目非常紧急时&#xff0c;会需要协调多个测试资源来把任务分成两…

警惕!AI正在“吞食”你的数据

视觉中国供图 □ 科普时报记者 陈 杰 AI大模型的热度&#xff0c;已然开始从产业向日常生活渗透&#xff0c;并引起不小的舆论旋涡。近日&#xff0c;网友指出国内某智能办软件有拿用户数据“投喂”AI之嫌&#xff0c;引发口水的同时&#xff0c;再度把公众对AI的关注转移到数…

使用paddledetection的记录

首先在这里使用的是是paddle--detection2.7的版本。 成功进行训练 目录&#xff1a; 目录 数据集准备 配置文件的修改 使用的是BML的平台工具&#xff1a; !python -m pip install paddlepaddle-gpu2.5 -i https://mirror.baidu.com/pypi/simple --user %cd /home/aistudio…

Rust语言入门教程(七) - 所有权系统

所有权系统是Rust敢于声称自己为一门内存安全语言的底气来源&#xff0c;也是让Rust成为一门与众不同的语言的所在之处。也正是因为这个特别的所有权系统&#xff0c;才使得编译器能够提前暴露代码中的错误&#xff0c;并给出我们必要且精准的错误提示。 所有权系统的三个规则…

Anaconda安装教程(超详细版)

目录 一、Anaconda简介 二、运行环境 三、安装Anaconda 四、手动配置环境变量&#xff08;重点&#xff09; 五、测试Anaconda环境是否配置成功 一、Anaconda简介 Anaconda&#xff0c;一个开源的Python发行版本&#xff0c;可用于管理Python及其相关包&#xff0c;包含了…

慕尼黑电子展采访全程 | Samtec管理层对话电子发烧友:虎家卓越服务

【摘要/前言】 今年的慕尼黑上海电子展上&#xff0c;Samtec大放异彩&#xff0c;特装展台一亮相就获得了大家的广泛关注&#xff0c;展台观众络绎不绝。 作为深耕连接器行业数十年的知名厂商以及Electronica的常客&#xff0c;Samtec毫无疑问地获得了大量媒体朋友的关注和报…

【数据结构】二叉树之链式结构

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、前置说明二、二叉树的遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历2.4 层序遍历 三、…

如何在本地安装部署WinSCP,并实现公网远程本地服务器

可视化文件编辑与SSH传输神器WinSCP如何公网远程本地服务器 文章目录 可视化文件编辑与SSH传输神器WinSCP如何公网远程本地服务器1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 …

送PDF书 | 豆瓣9.2分,超250万Python新手的选择!蟒蛇书入门到实践

在此疾速成长的科技元年&#xff0c;编程就像是许多人通往无限可能世界的门票。而在编程语言的明星阵容中&#xff0c;Python就像是那位独领风 骚的超级巨星&#xff0c; 以其简洁易懂的语法和强大的功能&#xff0c;脱颖而出&#xff0c;成为全球最炙手可热的编程语言之一。 …

Gitea和Jenkins安装

Gitea Gitea&#xff1a;https://dl.gitea.com/gitea/1.21.0/ Jenkins&#xff1a;https://www.jenkins.io/download/ 数据库配置 可以参考官方文档-https://docs.gitea.cn/1.20/installation/database-prep&#xff0c;这里以MySQL作为讲解 MySQL 在数据库实例上&#xf…

智能物流时代:快递物流信息订阅与推送API自动推送物流变更信息

引言 在当今数字化和智能化的时代&#xff0c;物流行业也在迅速演变&#xff0c;通过技术创新提高效率、提升服务质量。其中&#xff0c;快递物流信息订阅与推送API的自动推送功能成为推动物流领域发展的重要驱动力。本文将深入探讨这一趋势&#xff0c;并分析快递物流信息订阅…

完美解决:vue.js:6 TypeError: Cannot read properties of undefined (reading ‘0‘)

Vue项目出现以下报错&#xff1a; 原因&#xff1a; 在渲染的时候&#xff0c;不满足某个条件而报错&#xff0c;或者某个属性丢失或后台没传过来导致 我这里出现的原因是后台给我传递过来的数组中&#xff0c;其中有一条少传了一个我在渲染时需要用的属性&#xff0c;没让后台…

如何使用Java支付宝沙箱环境并公网调用sdk创建支付单服

Java支付宝沙箱环境支付&#xff0c;SDK接口远程调试【内网穿透】 1.测试环境 MavenSpring bootJdk 1.8 2.本地配置 获取支付宝支付Java SDK,maven项目可以选择maven版本,普通java项目可以在GitHub下载,这里以maven为例 SDK下载地址&#xff1a;https://doc.open.alipay.com…

阻塞队列及简单实现,生产者消费者模型

文章目录 阻塞队列阻塞队列是什么生产者消费者模型阻塞队列的实现 阻塞队列 阻塞队列是什么 阻塞队列是一种特殊的队列. 也遵守 “先进先出” 的原则. 当队列满的时候, 继续入队列就会阻塞, 直到有其他线程从队列中取走元素当队列空的时候, 继续出队列也会阻塞, 直到有其他线…

有效实施的五条教学策略

作为老师&#xff0c;是否曾为如何提高教学质量而苦恼&#xff1f;也为如何引导学生而思考&#xff1f;如果你正面临这些困扰&#xff0c;那么这篇文章将对你有帮助。为你介绍五条教学策略&#xff0c;帮你实施教学&#xff0c;提高效果。 明确教学目标 你是否知道你的教学目标…

针对操作系统漏洞的反馈方法

一、针对操作系统漏洞的反馈方法 漏洞扫描指基于漏洞数据库&#xff0c;通过扫描等手段对指定的远程或者本地计算机系统的安全脆弱性进行检测&#xff0c;发现可利用漏洞的一种安全检测&#xff08;渗透攻击&#xff09;行为。在进行漏洞扫描后&#xff0c;需先确定哪些是业务…