Pixhawk---基于NSH的Firmware开发与调试

2023-05-16



版权声明:本文为博主[原创]文章,未经博主允许可以转载,注明博客出处:[http://blog.csdn.net/FreeApe]

目录(?)[+]

  1. 相关知识了解
    1. 1 Nuttx系统
    2. 2 NSH
  2. 编译固件和刷固件
  3. 调试方式
    1. 1 测试小功能程序
    2. 2 固件测试
  4. 调试实例演示

1 相关知识了解

1.1 Nuttx系统

  嵌入式实时操作系统(RTOS)。强调标准兼容和小型封装,具有从8位到32位微控制器环境的高度可扩展性。NuttX 主要遵循 Posix 和 ANSI 标准,对于在这些标准下不支持的功能,或者不适用于深度嵌入环境的功能(如 fork()),采用来自 Unix 和常见 RTOS (如 VxWorks)的额外的标准 API。
  支持文件系统、设备驱动、网络、USB支持、Flash支持、图形支持等。

1.2 NSH

  NuttShell和Unix终端命令类似。NSH通过串口或者USB转串口来与PX4FMU交互,因此可以使用类似超级终端的串口软件来与FMU交互,在Pixhawk开发中,建立好了开发环境后(安装了工具链等),PX4 Toolchain 已经附带了一个串口工具:TeraTerm。如果版本低了,可以单独去下载这个软件并安装。
  在PX4FMU中,NSH默认是通过USB转串口和串口5(波特率为57600)来交互。可以更改默认设置。
  将Pixhawk通过USB转串口连接上电脑上后,再打开TeraTerm软件。通过输入『?』或『help』指令可以查看当前NSH支持的指令已经编译好的应用。其他的一些指令跟Unix终端中用法差不多,不过一些指令的参数都没有了。
这里写图片描述
  通过串口5的交互能打印PX4FMU启动时的一些信息。这个可以用来查看系统启动方面的信息。当然启动完后,还可以输入一些指令来与PX4FMU来交互。
这里写图片描述
这里写图片描述
这里写图片描述

2 编译固件和刷固件

  刷固件的方式很多,可以通过地面站软件QGC或者MP都可以刷固件,可以刷稳定版的固件或者自己编译出来的自定义固件。这里通过PX4 Console来编译固件和刷固件。打开控制台,进入到固件目录:

cd /d/px4/firmware

  删除所有编译的文件,包括编译的操作系统,即删除Archives文件夹和Build文件夹里面的内容一般不使用:

make distclean

  编译操作系统:

make archives

  一般只有当Nuttx配置改变了或者submodule(在GIT中链接外部库,比如MAVLINK或者Nuttx OS)发生了改变才会去编译操作系统,平时编译一次就好了,而且这个编译一次是需要很长的时间的,一个小时左右吧。尽管并行编译会加快速度,但是配置不好,并行编译很容易在系统运行的过程中出问题。如果你使用苹果系统或者Linux系统,这个时间也会大大降低。
  删除编译的固件相关文件,即删除Build文件夹里面的内容:

make clean

  编译固件,以px4fmu-v2_default版本为例:

make px4fmu-v2_defaul

  编译并刷固件,编译完后紧接着刷固件:

make upload px4fmu-v2_default

  在控制台上用到上面的指令就差不多了。

3 调试方式

3.1 测试小功能程序

  因为在windows系统上编译一次固件需要3分钟左右吧,对于一般的功能测试程序可以通过在本机安装上VC6.0或VS或者MinGW(gcc,g++,推荐),编写测试程序编译调试。

3.2 固件测试

  通过printf打印相关信息,断点标识等。这个需要编译固件,并刷固件。Pixhawk通过USB转串口线连接电脑,用TeraTerm输入指令来调试。

4 调试实例演示

  前面已经说了通过串口5(波特率57600)可以查看系统启动打印的信息。通过USB转串口在NSH终端(TeraTerm)输入指令控制Nuttx中的应用或者一些命令。
  可以先阅读sdlog2日志记录自动清理功能分析与实现,了解sdlog2应用是怎么运行的。sdlog2应用随着系统启动时默认启动了的,当我们修改了固件中sdlog2应用的代码时,比如简单的,我们知道sdlog2_main这个函数是在后台运行的,它是检测sdlog2应用的参数输入,比如stop,start,on,off。我们也可以自己再加一条参数检测到这个函数中:


<code class="language-c++ hljs scss has-numbering">    <span class="hljs-comment">/*添加测试代码start...*/</span>
    <span class="hljs-function">if(!<span class="hljs-function">strcmp(argv[<span class="hljs-number">1</span>],<span class="hljs-string">"hello"</span>)</span>)</span>{
        <span class="hljs-function">printf(<span class="hljs-string">"[YCM]hello world!\n"</span>)</span>;
    }
    <span class="hljs-comment">/*添加测试代码end...*/</span></code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>  

<code class="language-c++ hljs cpp has-numbering"><span class="hljs-keyword">int</span> sdlog2_main(<span class="hljs-keyword">int</span> argc, <span class="hljs-keyword">char</span> *argv[])
{
    <span class="hljs-keyword">if</span> (argc < <span class="hljs-number">2</span>) {
        sdlog2_usage(<span class="hljs-string">"missing command"</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    }

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">strcmp</span>(argv[<span class="hljs-number">1</span>], <span class="hljs-string">"start"</span>)) {

        <span class="hljs-keyword">if</span> (thread_running) {
            warnx(<span class="hljs-string">"already running"</span>);
            <span class="hljs-comment">/* this is not an error */</span>
            <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
        }

        main_thread_should_exit = <span class="hljs-keyword">false</span>;
        deamon_task = px4_task_spawn_cmd(<span class="hljs-string">"sdlog2"</span>,
                         SCHED_DEFAULT,
                         SCHED_PRIORITY_DEFAULT - <span class="hljs-number">30</span>,
                         <span class="hljs-number">3000</span>,
                         sdlog2_thread_main,
                         (<span class="hljs-keyword">char</span> * <span class="hljs-keyword">const</span> *)argv);
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">strcmp</span>(argv[<span class="hljs-number">1</span>], <span class="hljs-string">"stop"</span>)) {
        <span class="hljs-keyword">if</span> (!thread_running) {
            warnx(<span class="hljs-string">"not started"</span>);
        }

        main_thread_should_exit = <span class="hljs-keyword">true</span>;
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }

    <span class="hljs-comment">/*添加测试代码start...*/</span>
    <span class="hljs-keyword">if</span>(!<span class="hljs-built_in">strcmp</span>(argv[<span class="hljs-number">1</span>],<span class="hljs-string">"hello"</span>)){
        <span class="hljs-built_in">printf</span>(<span class="hljs-string">"[YCM]hello world!\n"</span>);
    }
    <span class="hljs-comment">/*添加测试代码end...*/</span>

    <span class="hljs-keyword">if</span> (!thread_running) {
        warnx(<span class="hljs-string">"not started\n"</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    }

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">strcmp</span>(argv[<span class="hljs-number">1</span>], <span class="hljs-string">"status"</span>)) {
        sdlog2_status();
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">strcmp</span>(argv[<span class="hljs-number">1</span>], <span class="hljs-string">"on"</span>)) {
        <span class="hljs-keyword">struct</span> vehicle_command_s cmd;
        cmd.command = VEHICLE_CMD_PREFLIGHT_STORAGE;
        cmd.param1 = -<span class="hljs-number">1</span>;
        cmd.param2 = -<span class="hljs-number">1</span>;
        cmd.param3 = <span class="hljs-number">1</span>;
        orb_advertise(ORB_ID(vehicle_command), &cmd);
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">strcmp</span>(argv[<span class="hljs-number">1</span>], <span class="hljs-string">"off"</span>)) {
        <span class="hljs-keyword">struct</span> vehicle_command_s cmd;
        cmd.command = VEHICLE_CMD_PREFLIGHT_STORAGE;
        cmd.param1 = -<span class="hljs-number">1</span>;
        cmd.param2 = -<span class="hljs-number">1</span>;
        cmd.param3 = <span class="hljs-number">2</span>;
        orb_advertise(ORB_ID(vehicle_command), &cmd);
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }

    sdlog2_usage(<span class="hljs-string">"unrecognized command"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
}
</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li></ul>  

  编译固件并刷固件,如果你的代码有问题,那么会报错,终止编译,会有错误提示:

make upload px4fmu-v2_default

这里写图片描述

  从编译过程中打印信息,我们也可以知道这个submodule中什么改变了,就需要重新编译操作系统了。编译完,刷好了固件:

这里写图片描述
  再次连接TeraTerm,输入指令:

sdlog2 hello

这里写图片描述

  输出hello world!了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pixhawk---基于NSH的Firmware开发与调试 的相关文章

  • sockaddr_in详解

    struct sockaddr in short sin family Address family一般来说AF INET xff08 地址族 xff09 PF INET xff08 协议族 xff09 unsigned short sin
  • ubuntu下好用的TCP/UDP调试工具

    github官方链接 GitHub s kyo mNetAssist mNetAssist A UDP TCP Assistant 编译好的安装包 ubuntu下好用的TCP UDP调试工具 网络设备文档类资源 CSDN下载 1 解压dpk
  • Linux网络编程之connect函数分析

    在一个 CLIENT SERVER模型的网络应用中 xff0c 客户端的调用序列大致如下 xff1a socket gt connect gt recv send gt close 其中socket没有什么可疑问的 xff0c 主要是创建一
  • linux route 命令

    显示现在所有路由 route n root 64 Ubuntu route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 10
  • 大量LAST_ACK 分析过程

    记录一下自己的思想过程 现象 在netstat的时候发现大量处于LAST ACK状态的TCP连接 xff0c 达到在ESTABLISHED状态的90 以上 root 64 ccsafe netstat ant fgrep 34 34 cut
  • const 与重载

    const到底是不是一个重载的参考对象 xff0c 请看下面的例子 class A public void f int i std cout lt lt 34 1 34 函数1 void f int i const std cout lt
  • 指向成员函数的指针

    指向成员函数的指针 取一个非静态成员函数的地址 xff0c 如果该函数是nonvirtual xff0c 则得到的结果是它在内存中真正的地址 然而这个值也不是完全的 xff0c 它也需要被绑定于某个class object的地址上 xff0
  • rviz 远程显示及控制移动机器人的导航

    环境 xff1a xff08 1 xff09 虚拟机本地端IP 192 168 10 30 xff08 虚拟机需要通过桥接的形式与PC本地机连接 xff0c PC 机IP 192 168 10 21 xff09 xff08 2 xff09
  • iptables - administration tools for packet filtering and NAT

    2 iptables administration tools for packet filtering and NAT Linux Iptables Manual Incoming Traffic V 43 43 PREROUTING 4
  • C++ 内部类、嵌套类

    1 嵌套类 nested class 一个类可以定义在另一个类的内部 xff0c 前者称为嵌套类 xff0c 嵌套类时一个独立的类 xff0c 和外层类基本没什么关系 它通过提供新的类型类作用域来避免名称混乱 嵌套类必须声明在类的内部 xf
  • SONY VAIO P VPCP118KJ索尼酷袋本 鸡肋上网本初体验

    随着消费者市场需求的不断多样化和个性化 xff0c 个人电脑厂家开始不断突破创新 xff0c 在产品线拼装出各种各样的个人电脑 xff0c 主打性能的游戏本 xff0c 主打便携轻薄本 xff0c 2009年的CES上索大法推出了一款与众不
  • 第2课【CMSIS和标准库开发】标准库 CMSIS 分层

    目录 基本知识框架课堂笔记CMSISCMSIS的分层关系和作用CMSIS层文件结构内核函数层文件外设函数访问层文件 标准库开发标准库开发 LED GPIO标准库开发 KEY GPIO标准库开发 位带操作位带位带位带别名区位带区和位带别名区的
  • 第4课【STM32的时钟】时钟 时钟源 内外部时钟 高低速时钟

    目录 基本知识框架课堂笔记时钟什么是时钟 xff1f 时钟有什么作用 时钟源HSE 外部高速时钟HSI 内部高速时钟LSE 外部低速时钟LSI 内部低速时钟PLL锁相环 主要时钟和其他时钟主要时钟其他时钟 配置系统时钟实验 基本知识框架Xm
  • 第7课【SysTick定时器】中断 系统定时器 寄存器

    目录 基本知识框架课堂笔记SysTick定时器简介什么是SysTick定时器SysTick定时器的作用 SysTick寄存器CTRL控制及状态寄存器LOAD重装载数值寄存器VALUE当前数值寄存器CALIB校准数值寄存器 SysTick实战
  • 第8课【通讯的基本概念】串行并行 单工半双工全双工 同步异步 比特率波特率

    目录 基本知识框架课堂笔记通讯传送方式串行通讯并行通讯串行通讯与并行通讯的特性 通讯方向单工通讯半双工通讯全双工通讯 同步方式同步通讯异步通讯同步通讯与异步通讯的区别 传输单位比特率波特率比特率和波特率的联系 通讯简介通讯标准 基本知识框架
  • 嵌入式宏定义中do...while(0)的意义

    目录 背景do while 0 形式宏定义使得宏定义拥有一些函数的特点 分析1 封装 xff1a 使得宏定义可以包含复杂的内容而不容易出错 xff0c 提高代码健壮性2 生命周期 xff1a 宏定义内 外部定义的同名变量不会冲突3 返回 x
  • 第9课【USB协议】USB总线 接口 端点 管道 数据包 枚举 STM32_USB-FS-Device_Lib V4.1.0

    目录 简介背景特点版本 数据流模型总线拓扑结构主 从设备通信流端点管道 物理层接口类型USB Type AUSB Type BUSB Type C 引脚定义4PIN9PIN5PIN24PIN16PIN6PIN 电平标准 协议层 通讯方式通讯
  • 第10课【STM32 USB通讯协议实战】HID键盘+CDC虚拟串口组合设备

    目录 前言USB设备类别未定义设备设备描述符 配置描述符分析配置从机类型配置设备专用的描述符配置从机端点实现设备类特定请求 HID设备特点HID键盘描述符实例HID报文描述符短条目报文生成HID键盘报文描述符实例总结 CDC设备特点CDC
  • 创建 std_srvs::Empty 型 Service (参数为空的服务)

    参考 xff1a ros NodeHandle advertiseService API docs 1 包含头文件 include lt std srvs Empty h gt 2 创建服务 xff0c 并绑定服务的回调函数 restart
  • stm32串口+DMA环形缓冲收发保姆级

    基于HAL库的STM32串口DMA环形缓冲收发实例 首先在此感谢开源项目 xff0c 以及大佬们的无私奉献 xff0c 让每一个逐梦人能够免费学习 xff0c 再次感谢 xff01 发布只为记录 xff0c 记性不够 xff0c 笔记来凑

随机推荐

  • NX串口通讯windows

    我用windows与NX进行通讯 xff0c 用的线是CH340下载线 USB端连接windows xff0c 绿色的TXD连接NX的10号 RXD xff0c 白色的RXD连接NX的8号 TXD 目录 1 windows端 2 NX端 2
  • 串口接收 DMA FIFO 双缓冲区配置 + 单色OLED屏幕灰度图像显示的抖动算法

    适用于单色OLED屏幕图像显示的抖动算法 Visual studio c 43 43 STM32F4070 96寸单色IIC通信OLED5级灰度串口DMA 双缓冲github 抖动算法原理 DITHER抖动算法是指灰度可以用一定比例的黑白点
  • HTTP请求报文与响应报文

    一 HTTP的请求报文格式 xff1a HTTP的请求报文内容包括 xff1a 请求行 request line 请求头部 header 空行 和 请求数据 request data 四个部分组成 请求行主要包括 xff1a 请求方法 UR
  • c++中char转换为string类型

    写程序遇到一个Bug如下 xff1a char x 61 39 a 39 string str x 这里报错了 当时就有点蒙了 xff0c 查了下string的构造函数 xff1a string string const string am
  • C语言——内存管理问题

    常见的内存错误及解决方法 一 结构体成员指针未初始化 eg span class token macro property span class token directive hash span span class token dire
  • 大端存储和小端存储

    一 大端存储 高字节数据存储在低地址 二 小端存储 低字节数据存储在低地址 注意 xff1a 无论是大端存储还是小端存储 xff0c 读取到的数据为0x0102030405 三 大端存储或小端存储都是由系统设定的 xff0c 其二者区别在于
  • 多播的概念

    一 多播概述 多播 xff1a 数据的收发仅仅在同一组中进行 xff08 相当于我往一个群里发 xff0c 只有加入这个群的人才能收到 xff09 多播的特点 xff1a 多播地址标示一组接口 多播可以用于广域网使用 在IPv4 xff0c
  • 利用C语言编写一个网络分析器

    一 链路层数据格式 mac报文 xff1a 14个字节 二 IP数据报文格式 三 TCP数据报文格式 四 UDP数据报文格式 五 demo xff08 网络分析器 xff09 recvfrom接收链路层帧数据 xff0c 不经过网络层 传输
  • ARP攻击代码(ARP欺骗)

    一 ARP攻击 ARP欺骗攻击原理 xff1a ARP欺骗攻击建立在局域网主机间相互信任的基础上的 比如 xff1a 假设A B C在同一个局域网中 xff0c 网关为192 168 43 1 xff0c IP地址和MAC地址分别假设如下
  • 使用wireshark抓包并分析TCP三次握手

    一 实验过程 1 TCP包抓取及分析过程 确认使用的协议 xff0c 使用HTTP服务 选择https www baidu com 作为目标地址 启动Wireshark软件 xff0c 点击开始抓包后 在浏览器地址输入https www b
  • 使用wireshark抓包并分析TCP四次挥手

    一 四次挥手 第一次挥手 xff1a xff08 FIN 43 ACK xff09 客户端发送FIN 43 ACK包给服务端 xff0c 用来关闭客户端到服务器的数据传送 此时客户端进入FIN WAIT 1状态 第二次挥手 xff1a AC
  • TR-069协议介绍

    一 概念 关于TR 069 协议命名 TR 069 全称 Technical Report 069 是由DSL Forum xff08 一个非盈利性的全球行业联盟 致力于发展宽带网络范 xff09 其成员包括通讯 设备 计算机 网络和服务提
  • FFMPEG关键结构体——AVCodecContext

    一 AVCodecContext结构体 这是一个描述编码器上下文的数据结构 xff0c 包含了众多编码器需要的参数信息 该结构体在libavcodec avcode h中定义 二 常见变量
  • FFMPEG关键结构体——AVIOContext

    一 AVIOContext结构体 这个结构体 xff0c 是FFmpeg中有关io操作的顶层结构体 xff0c 是avio的核心 FFmpeg支持打开本地文件路径和流媒体协议的URL 该结构体在libavformat avio h中定义 二
  • 指针数组和数组指针

    一 什么是指针数组 一个数组 xff0c 若其元素均为指针类型数据 xff0c 称为指针数组 xff0c 也就是说 xff0c 指针数组中的每一个元素都存放一个地址 xff0c 相当于一个指针变量 span class token keyw
  • Symfony学习笔记之翻译组件-----translation总结

    过际化 xff08 internationalization xff0c 常被简写为i18n xff09 xff0c 是指将字符串和其他一些具有区域特征的片段 xff0c 从你的程序中提取 xff08 abstract xff09 出来 x
  • 为什么要配环境变量?path用来干什么?

    提出问题 xff1a 为什么要配环境变量 xff1f 配环境变量解决了什么 xff1f xff08 阿菜进来看哈嘛 xff09 注 xff1a 环境变量具体概念自行百度百科 概念理解 xff1a 环境变量相关概念 path路径 xff1a
  • Ubuntu18.04无wifi图标安装Realtek RTL8111/8168/8411网卡驱动详解

    这是本人第一次写博客 xff0c Ubuntu系统网卡驱动问题也已经遇到过两次了 xff0c 本次写下博客作为记录 xff0c 希望对遇到同样问题的同学有所帮助 电脑 xff1a 联想E14 系统 xff1a Ubuntu18 04 使用网
  • ROS echo 命令出现报错Cannot load message class for .... Are your messages built?解决办法

    1 把别人录制的bag包拿到自己的系统环境中echo某个topic想查看内容 xff0c 键入echo命令后弹出Are your messages built 错误 xff0c 原因 xff1a 没有在自己的工作空间下的devel incl
  • Pixhawk---基于NSH的Firmware开发与调试

    xfeff xfeff 版权声明 xff1a 本文为博主 原创 文章 xff0c 未经博主允许可以转载 xff0c 注明博客出处 xff1a http blog csdn net FreeApe 目录 43 相关知识了解 1 Nuttx系统