嵌入式_GD32使用宏开关进行Debug串口打印调试

这篇具有很好参考价值的文章主要介绍了嵌入式_GD32使用宏开关进行Debug串口打印调试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

嵌入式_GD32使用宏开关进行Debug串口打印调试

串口Debug是一种将数据通过串口发送的方法。通过使用printf函数,我们可以将需要发送的数据格式化为字符串,并通过串口发送出去。在C语言中,通常使用串口发送数据的函数为printf函数,但是需要将标准输出重定向到串口。



前言

本文详细的介绍了如何重定向printf输出到串口输出的多种方法,包括调用MDK微库(MicroLib)的方法,调用标准库的方法,以及适用于 GNUC 系列编译器的方法。
注:本项目基于GD32F103CBT6硬件平台, 使用标准库GD32F10x_Firmware_Library_V2.2.4


一、什么是printf/fputc重定向?

printf 函数可以输出各种类型的数据,使用格式控制输出各种长度的字符,甚至输出各种各样的图案。因此在程序出错的时候,懒得调试,直接简单粗暴的加个 printf 找bug,有时候也不失为一种有效的方法。

printf 作为变参函数,参数由右向左以此进入函数
定义在 <stdio.h> 头文件中,如下:

int printf(const char *format, ...);

printf 函数根据 format 字符串给出的格式打印输出到 stdout(标准输出)中,当然,printf 函数是不会一个字符一个字符去输出,它会调用更底层的 I/O 函数:fputc去逐个字符打印。

fputc 也定义于头文件 <stdio.h>中,如下:

int fputc(int ch, FILE *stream);

我们要做的实际是对fputc进行定向,将它重定义到为串口输出,这样使用printf时就相当于直接通过串口输出了。

二、配置步骤

1.串口配置

1.首先需要对输出串口进行配置,使用有效的串口外设是第一步,保证硬件连接没有问题;
2.串口外设软件驱动配置,包括GPIO、串口时钟,串口波特率,时钟等
3.MDK需要勾选使用MicroLIB库
4.fputc函数重定向的串口,没发送一个字符都会调用此函数。

int fputc(int ch, FILE *f)
{
    /* Loop until transmit data register is empty */
     while(usart_flag_get(USART0,USART_FLAG_TBE) == RESET)
    {
      
    }
    /* Place your implementation of fputc here */
     usart_data_transmit(USART0,(uint8_t)ch );
    //SEGGER_RTT_PutChar(0, ch);
    return ch;
}

串口打印需要耗费不少时间,为了增加效率可直接使用寄存器操作

至此可以直接使用Printf(“hello world\n”);串口会直接输出

2.宏开关

使用宏开关的好处就是在不需要串口打印或者软件调试完成需要交付的时,可以直接通过定义SYSTEM_SUPPORT_DEBUG宏作为开关来确定串口打印与否,直接使用Debug输输出:Debug(“hello world!\n”)

#ifdef SYSTEM_SUPPORT_DEBUG
  #define	Debug		printf
#else
  #define	Debug(...)	do{ }while(0)
#endif

三、注意事项

1.关闭半主机模式

printf 函数使用了半主机模式,所以直接使用标准库会导致程序无法运行,因此必须提前告知编译器不使用半主机模式:
这条语句可以关闭半主机模式,只需要在任意一个C文件中加入即可。

/* 告知连接器不从C库链接使用半主机的函数 */
#pragma import(__use_no_semihosting)
 
/* 定义 _sys_exit() 以避免使用半主机模式 */
void _sys_exit(int x)
{
    x = x;
}
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
/*  */
int fputc(int ch, FILE *f)
{
    /* Loop until transmit data register is empty */
     while(usart_flag_get(USART0,USART_FLAG_TBE) == RESET)
    {
      
    }
    /* Place your implementation of fputc here */
     usart_data_transmit(USART0,(uint8_t)ch );
    //SEGGER_RTT_PutChar(0, ch);
    return ch;
}
 
#endif

在嵌入式的编程中你是避免不了使用printf、fopen、fclose等函数的但是因为嵌入式的程序中并没有对这些函数的底层实现,使得设备运行时会进入软件中断BAEB,这时就需要__use_no_semihosting_swi这 个声明,使程序遇到这些文件操作函数时不停在此中断处。MDK上开启半主机模式-需要SWO线(换言之,需要使用JTAG接线),而我们程序模式开启的半主机模式,所以,我们需要禁止半主机模式。当目标板脱离仿真器(jlink/ulink)单独运行时,不能使用半主机模式。否则进入软件中断BAEB处,无法再执行下去。

2.输出十六进制数据

当需要打印输出多个十六进制数据和字符数字据时,串口调试助手窗口的数据会非常难分辨,(要么全是字符要么全是十六进制),所以多个十六进制数据需要单独打印输出。
代码如下(示例:

void Print_Hex(uint8_t len,uint8_t *HexArray)
{
  uint8_t i=0;
  
  Debug(" \r\n");
  for(i = 0;i < len;i++)
  {
    Debug("%02x ",HexArray[i]);
  }
  Debug(" \r\n");
}

总结

这就是嵌入式中使用Debug串口调试的方法,有些语句是直接引用其他博主,在此谢过,欢迎指正文章来源地址https://www.toymoban.com/news/detail-629869.html

到了这里,关于嵌入式_GD32使用宏开关进行Debug串口打印调试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一文带你了解 嵌入式Typec 接口切换开关

         现在手机、电脑中大多是 typec 接口,该接口可以充电、 OTG 功能(typec数字耳机)、typec 模拟耳机等,可你知道是谁在切换不同功能的线路吗?是切换 IC,比如:FSA4480、ET7480 等。 插入后,根据上面两个 cc pin 的检测,来识别有东西插入,并且根据两个 pin 脚的高低电平,

    2024年02月10日
    浏览(58)
  • 使用Yocto进行嵌入式Linux开发3 Toaster

    我们已经知道了如何在Poky中使用BitBake构建图像image,那么我们将学习如何使用Toaster完成同样的操作。 Toaster是一个用于配置和运行构建的Web接口。它与BitBake和Poky构建系统通信,以管理和收集有关构建、软件包和镜像的信息。 使用Toaster的两种方法: 本地 可以将Toaster作为本

    2024年02月08日
    浏览(42)
  • 使用Yocto进行嵌入式Linux开发1 Yocto简介

    Yocto项目是Linux基金会的一个工作组,它是一个开源协作项目,帮助开发人员创建基于Linux的定制系统,这些系统专为嵌入式产品而设计,与产品的硬件架构无关。Yocto项目提供了一个灵活的工具集和开发环境,使世界各地的嵌入式设备开发人员能够通过共享技术、软件栈、配

    2024年02月09日
    浏览(50)
  • faac内存开销较大,为方便嵌入式设备使用进行优化(valgrind使用)

    faac内存开销较大,为方便嵌入式设备使用进行优化,在github上提了issues但是没人理我,所以就搞一份代码自己玩吧。 基于faac_1_30版本,原工程https://github.com/knik0/faac faac内存优化: faac内存开销较大,为方便嵌入式设备使用进行优化,在github上提了issues但是没人理我,所以就搞

    2024年02月14日
    浏览(47)
  • 【嵌入式Qt开发入门】如何使用Qt进行绘图——QPainter 绘图

            绘图与图表在嵌入式里有的比较多,尤其是图表,我们常在股票里看到的“图表折线/曲线 图/饼状图等”都可以用 Qt 的图表来实现。绘图和图表的内容本章主要介绍绘图和图表的基本操作,以简单的例子呈现绘图与图表的用法,目的就是快速入门绘图与图表,关

    2024年02月12日
    浏览(47)
  • 使用VSCode clangd插件进行linux内核代码阅读和嵌入式开发

    在进行 Linux 内核代码阅读和嵌入式开发时,选择合适的开发工具至关重要。VSCode 是一个流行的跨平台编辑器,并且它的扩展生态系统非常强大。在这篇博客中,我们将介绍如何使用 VSCode Clangd 插件来提高 Linux 内核代码的阅读和嵌入式开发效率。 Clangd 是一个基于 Clang 的语言

    2024年02月09日
    浏览(51)
  • 【嵌入式】STM32计时器编码器接口模式使用

    使用STM32调试电机或传感器时经常会使用到计数器的编码器接口模式,本文主要记录该模式的固件库配置方法,并给出使用该模式获取光栅测距值的实例。 硬件: STM32F103C8T6 光栅测距传感器 编码器接口模式为STM32计时器的一种特殊使用模式,该模式下可对编码器输出的脉冲信

    2024年02月20日
    浏览(49)
  • 使用Yocto进行嵌入式Linux开发2 第一个基于Poky的系统

    Ubuntu: Fedora 在我们的开发主机系统上安装了所需的软件包后,我们可以使用 Git 下载当前 LTS 版本的 Poky 源代码,命令如下: 下载完成后,poky 目录中的内容如下: 在poky目录中存在oe-init-build-env脚本,用于设置构建环境。 这里,[build-directory] 是一可选参数,用于指定配置环境

    2024年02月08日
    浏览(48)
  • 【嵌入式Qt开发入门】如何使用Qt进行绘制实时图表——QChart 图表

            要想使用 Qt Charts,我们的 Qt 版本得使用 Qt 5.7 之后的版本。其实 Qt Charts 并不是 Qt 5.7 才有的,是在 Qt 5.7 以前只有商业版本的 Qt 才有 Qt Charts。我们能免费下载的 Qt 版本都是社区(开源)版本。         Qt Charts 很方便的绘制我们常见的曲线图、折线图、柱状

    2024年02月12日
    浏览(65)
  • 【嵌入式Qt开发入门】如何使用Qt进行文本读写——QFile读写文本

            在很多时候我们需要读写文本文件进行读写,比如写个 Mp3 音乐播放器需要读 Mp3 歌词里的文本,比如修改了一个 txt 文件后保存,就需要对这个文件进行读写操作。本文介绍简单的文本文件读写,内容精简,让大家了解文本读写的基本操作。         QFile 类提

    2024年02月12日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包