Emacs 调试单片机

Emacs 使用的人少, Emacs 开发单片机的人就更少了, Debuff 叠满了属于是 :rofl:

本人开始接触的都是从 IAR, Keil 等 IDE 软件开发单片机的, 对于外部使用 gdb 进行调试单片机经验相对较少, 想在 Emacs 调试单片机历程就相当艰辛了..

自从 Emacs 后, 渐渐的开始用 Emacs 编写代码了, 这时候就有着 Emacs 替代 IDE 软件的想法了, 毕竟 Emacs 真的太酷, 好用 , 便开始了寻找在 Emacs 调试单片机的方法了

PS: Keil, IAR 等 IDE 软件的调试功能真的是相当好了, 可惜不是免费的.

过程当中看到使用 Vscode 调试单片机功能如此完善, 有 EIDE, Cortex-M Debug 等优秀的插件助攻 VSCode 调试单片机, 而且竟然还看到了 Neovim 竟然有类似 Vsocd 的 Cotex-M Debug 的支持, 反观 Emacs…

真是令人唏嘘啊 :smiling_face_with_tear:

重要的是接触到了 vscode 调试方面貌似类似 LSP 那样开放? 为后续留下线索

好在在某个 vim 帖子看到有人居然直接可以用 cpptools 调试硬件了, 直接开干(最后面才发现有这路子)

Emacs 调试单片机历程:

  1. eshell 运行 arm-none-eabi-gdb

    对比 IDE 软件真的是相当难用了(因为我基本没用过 gdb 调试过), 对新手来说简直是噩梦了, 无法根据源码文件 breakpoints, 也无法 breakpoints 自动跳转到源码行 , 无法从 GUI 方式 Watch

  2. gud-gdb 运行 arm-none-eabi-gdb

    有了根据源码文件 breakpoints, 可以 breakpoints 自动跳转到源码行, 就是有点问题, 跳转问题有是好有时坏, 失效了一次就没办发继续跳转了, 无法观察 watch 很不方便

  3. dape.el + arm-none-eabi-gdb + cpptools (最终方案)

    终于找到了一个相当满意的方案了, 基本满足了基本需求, 现在就缺失了 mcu register 的支持(只要不是太大问题, 这个功能基本没有用到, 根本不看 mcu reg), 哈哈

这个历程相当艰辛了, 陆陆续续, 断断续续, 已经接近2年了, 走了各种弯路, 查了各种各样的资料, 最后真的用上 Emacs 调试单片机了…

单片机网上的资料资源 对比 软件方面真的少了好几个档次, 不知道是不是因为单片机的人不爱分享还是为啥.

希望此论坛有单片机相关工作的人员, 也多多分享你是怎么使用 Emacs 的.

附上教程: Emacs 调试单片机 dape.el + arm-none-eabi-gdb + cpptools

20 个赞

真好啊,你们用的mcu竟然能用调试器,我们用的国内几家mcu,没有给资料说怎么调试的,也不是arm架构…平时全靠printf😂

不过习惯了也还好,暂时没有觉得必须要上调试器的情况,可能我们只是业务逻辑多,没开发啥算法

我选择 emacs+vscode, vscode 擅长的事就让 vscode 做吧。

printf is enough :smiley:

printf 怎么用啊? 看见很多人都是使用 uart printf 到电脑, 这很浪费资源
类似终端printf的方法很难奏效, 不同 MCU 总是很难实现, 基本不可用
不知道你的 printf 是怎么用的?
能否指点一下? 想实现 终端(控制台) printf 的方法

不是吧……国内我们用过几家不同的蓝牙芯片,哪家都支持printf重定向到uart输出呀,再说UART也能通过DMA直接输出,CPU占用不多,如果你是指字符串字面量需要占用空间的话,那确实算是浪费,不过我们基本都用2Mbyte以上的内置flash,这一点点还是浪费得起的。

不知道你用的是哪一类的MCU,我上面用的这些厂家都有实现了printf重定向到uart,不需要我们自己去实现。

哦, 可能是我表达不清楚, 我的意思是: printf 重定向到 Console (控制台/终端)输出显示, 而不是使用 uart 等串口打印到 PC 电脑端, 因为这会浪费一组 uart 以及 MCU 引脚

printf到控制台?你mcu跑的是linux系统咩?我们有用过国内两家linux系统的,也是要通过串口输出控制台的内容才能让电脑那边接收显示

我们用的一般都有3组uart,qfn52封装,管脚还是够的,真要用足3组来通讯的话,那只能开发阶段打印一下咯,调试完就用回做正常ic间通讯

printf 到 Console 是不需要 mcu uart 的吧?
类似刚学C的时候, 直接一个 printf(“Hello World”)
然后电脑系统运行这个编译出来的程序, 终端会有 Hello Wolrd 显示
但是到单片机这些就不行了, 需要重定向 printf, 重定向有:

在 Keil 中实现 printf 的输出效果,有两种方法:

方法 1:重定向 printf 到串口

 1. 初始化串口(例如,USART2)。
 2. 重定向 printf:重写 fputc 或 _write 函数,将 printf 输出发送到串口。

int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return ch;
}


 3. 调用 UART_Init 初始化串口,然后可以直接使用 printf。

方法 2:使用半主机模式

 1. 启用半主机模式:在 Keil 中开启「Semihosting」。
 2. 初始化半主机模式:

extern void initialise_monitor_handles(void);
initialise_monitor_handles();


 3. 使用 printf 输出,调试时在「Console」窗口查看。

哦,你说跑在pc系统呀,我还以为你说嵌入式那种几百kb ram的环境

噢, 哈哈, 原来你说的是 MCU 跑一个系统? 类似 RTOS 那种吗?
对:

使用 printf 输出,调试时在「Console」窗口查看。

有什么指点吗?

没有指点…我想表达的是mcu的东西要在pc显示的话,必然要和pc通讯咯,uart应该就是最廉价的通讯了,只要一个pin就够了(gnd不算啦)

想不用串口可以试一下RTT

如果你的console这边已经有稳定的传输了那你给printf套个壳,在打印之前往console发同样的内容不就行了。

如果你有linux,往console的tty写即可。

看起来不错, 有空弄一弄先

听你说起来的样子满容易的?
知识盲区了, 我看看是个啥情况, 但又不知道找啥相关的知识学习

弄明白linux tty怎么回事就行了。

Linux tty?
先记着了, 毕竟现在不是用linux