embedded linux application development

Developing applications on embeded Linux

  • 嵌入式 Linux 系统只是一个普通的 Linux 系统,通常组件选择较少
  • 在应用程序开发方面,在嵌入式 Linux 上进行开发与在桌面 Linux 系统上进行开发完全相同
  • 所有现有技能均可重复使用,无需进行任何特殊调整
  • 所有现有的库(无论是第三方的还是内部的)都可以集成到嵌入式 Linux 系统中
    • 当然,考虑到嵌入式系统在性能、存储和内存方面的限制
  • 甚至在硬件可用之前,应用程序开发就可以在 x86 上开始

Leverage existing libraries and languages

  • 许多刚开始使用嵌入式 Linux 的开发人员仅限于使用 C、有时是 C++ 和 C/C++ 标准库
  • 然而,有很多库和语言可以帮助你加速和简化你的应用程序开发
    • Rust 和 Go 等编译语言越来越受欢迎
    • 解释型语言,尤其是 Python
    • 更高级别的库:Qt、Glib、Boost 等等
  • 确保评估什么是适合您项目的正确选择,但要注意如下事项:
    • 低端平台上的占用空间和性能
    • 使用维护良好且知名的技术

Building your applications/libraries

  • 即使对于简单的应用程序或库,也要使用构建系统
    • CMake
    • Meson
  • 简化事项有如下:
    • 应用程序的构建过程
    • 加入项目的开发人员的开发周期
    • 将您的应用程序打包到嵌入式 Linux 构建系统中

CMake

Meson

GDB: GNU Project Dubugger

  • GNU/Linux 上的调试器,适用于大多数嵌入式架构。

  • 支持的语言:C、C++、Pascal、Objective-C、Fortran、Ada…

  • 命令行界面

  • 许多图形集成开发环境都集成了gdb

  • 也可用作:

    • 控制正在运行的程序的执行、设置断点或更改内部变量
    • 查看程序崩溃时正在做什么:事后分析
  • 新的替代方案:LLVM 项目的 lldb

gdb

Remote debugging

  • 在非嵌入式环境中,使用 gdb 或其前端之一进行调试。
  • gdb 可以直接访问使用调试符号编译的二进制文件和库
  • 然而,在嵌入式环境中,目标平台环境通常太有限,无法使用 gdb 直接调试(x86 上为 2.4 MB)。
  • 远程调试优势:
    • ARCH-linux-gdb 用于开发工作站,提供其所有功能。
    • 目标系统上使用 gdbserver(arm 上仅 400 KB)。

Remote debugging: architeture

image-20241020183318748

Remote debugging: target setup

  • 在目标上,通过 gdbserver 运行程序。

    程序不会立即执行

    gdbserver : <port> <executable> <args>

    gdbserver /dev/ttyS0 <executable> <args>

  • 否则,将 gdbserver 附加到已在运行的程序

gdbserver --attach :<port> <pid>

  • 您还可以启动 gdbserver,而无需传递任何要启动或附加的程序(并稍后在客户端设置目标程序):

    gdbserver --multi :<port>

Remote debugging: host setup

  • 然后,在主机上启动 ARCH-linux-gdb <executable>,并使用下面的gdb命令
    • 告诉gdb共享库的位置:gdb> set sysroot <library-path> ,(通常是没有 lib/ 的构建空间的路径)
    • 连接目标,gbd> target remote <ip-addr>:<port>gdb> target remote /dev/ttyUSB0 (如果存在多个远程目标,注意替换参数)
    • 如果您没有在 gdbserver 命令行上将程序设置为调试,gdb> set remote exec-file <path_to_program_on_target>

Coredumps for post mortem analysis

  • 当应用程序因分段错误而崩溃,且应用程序不在调试器的控制之下时,我们无法获得有关崩溃的信息
  • 幸运的是,Linux 可以生成一个核心文件,其中包含崩溃时应用程序内存的 ELF 格式映像。gdb 可以使用这个核心文件让我们分析崩溃应用程序的状态
  • 在目标上:
    • 在shell中执行:ulimit -c unlimited ,当程序崩溃发生时,创建core 文件
    • coredump文件的名字可以在该路径下修改:/proc/sys/kernel/core_pattern
    • 在使用systemd的系统上,core dump作为默认安全功能被取消,为了重新存储coredump缓存,运行:echo core > /proc/sys/kernel/core_pattern
  • 在主机上:
    • 程序崩溃发生后,将coredump文件从目标传输到主机上,然后运行:ARCH-linux-gdb -c core-file application-binary

minicoredumper

  • 对于复杂的应用程序来说,core dump可能非常大
  • minicoredumper 是一个基于标准core dump功能的用户空间工具,基于通过管道将核心转储输出重定向到用户空间程序的可能性
  • 基于JSON配置文件,它能做如下:
    • 仅保存相关部分(堆栈、堆、选定的 ELF 部分)
    • 压缩输出文件
    • 从 /proc 保存附加信息
  • “高效、实用的嵌入式系统碰撞数据采集“