stm32中printf重定向

2023-05-16

先上代码

//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
	int handle;
};

FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
	x = x;
}
//重定义fp
utc函数
int fputc(int ch, FILE *f)
{
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
	USART1->DR = (u8) ch;
	return ch;
}
#endif
//加入以下代码,支持printf函数,而不需要选择use MicroLIB

为什么要用标准库我也不清楚,下文是他们的解释:

实际上,我们大部分工程用到的标准C库函数很少,而且keil中的microLIB默认已将printf重定向到UART1,我们可以直接使用printf通过串口1输出数据,所以勾选使用microLIB是一种非常好的方法,如果不勾选microLIB,则keil变压器会自动链接标准库函数。

一旦没勾选可不就是要自己重定义么

#if 1
#endif

#if 1, 看起来是很鸡肋的东西,之所以要这样搞,假设#if 0,就可以不执行里面的代码,编译的时候会被优化掉,正常情况下那个数字应该变成一个宏定义,估计写这个的人一开始只是随意写的。

问题来了,为什么要一会执行,一会不执行,这得从长说起。

重新定义printf,是用来串口调试的,(调试有很多种方法,有硬件调试,软件调试,串口调试)在写代码逻辑的过程中,很可能会很混乱,出现一些bug,printf可以查看代码,相较于debug选项,他们各有各自的优缺点,

#pragma import(__use_no_semihosting)

在keil中编程时常会遇到use_no_semihosting_swi的警告,这时你就是进入了半主机模式。**在嵌入式的编程中你是避免不了使用printf、fopen、fclose等函数的但是因为嵌入式的程序中并没有对这些函数的底层实现,使得设备运行时会进入软件中断BAEB处,这时就需要use_no_semihosting_swi这 个声明,使程序遇到这些文件操作函数时不停在此中断处,具体操作如下,将下列程序加入你的工程中:**

pragma import(__use_no_semihosting_swi)

这条语句可以关闭半主机模式,只需要在任意一个C文件中加入即可。

什么是半主机模式?

半主机是用于 ARM 目标的一种机制,可将来自应用程序代码的输入/输出请求传送至运行调试器的主机。 例如,使用此机制可以启用 C 库中的函数,如 printf() 和 scanf(),来使用主机的屏幕和键盘,而不是在目标系统上配备屏幕和键盘。

这种机制很有用,因为开发时使用的硬件通常没有最终系统的所有输入和输出设备。 半主机可让主机来提供这些设备。

半主机是通过一组定义好的软件指令(如 SVC)来实现的,这些指令通过程序控制生成异常。 应用程序调用相应的半主机调用,然后调试代理处理该异常。 调试代理提供与主机之间的必需通信。

半主机接口对 ARM 公司提供的所有调试代理都是通用的。 在无需移植的情况下使用 RealView ARMulator® ISS、指令集系统模型 (ISSM)、实时系统模型 (RTSM)、RealView ICE 或 RealMonitor 时,会执行半主机操作。

标准库使用半主机模式,半主机是通过一组定义好的软件指令 (如 SVC)SVC 指令 (以前称为 SWI 指令)来实现的,这些指令通过程序控制生成异常。 应用程序调用相应的半主机调用,然后调试代理处理该异常。调试代理(这里的调试代理是仿真器)提供与主机之间的必需通信。也就是说使用半主机模式必须使用仿真器调试。

ARMv7 之前的 ARM 处理器使用 SVC 指令 (以前称为 SWI 指令)进行半主机调

用。 但是,如果要为 ARMv6-M 或 ARMv7-M (如 Cortex™-M1 或 Cortex-M3 处

理器)进行编译,请使用 BKPT 指令来实现半主机。

简单的来说,半主机模式就是通过仿真器实现开发板在电脑上的输入和输出。和半主机模式功能相同的是ITM调试机制。有关ITM调试机制可以参考这里http://www.douban.com/note/248637026/

问题来了,为什么要关闭半主机模式?

半主机是这么一种机制,它使得在ARM目标上跑的代码,如果主机电脑运行了调试器,那么该代码可以使用该主机电脑的输入输出设备。 这点非常重要,因为开发初期,可能开发者根本不知道该 ARM 器件上有什么输入输出设备,而半主基机制使得你不用知道ARM器件的外设,利用主机电脑的外设就可以实现输入输出调试。 所以要利用目标 ARM器件的输入输出设备,首先要关掉半主机机制。然后再将输入输出重定向到 ARM 器件上,如 printf 和 scanf,你需要重写 fputc和 fgetc 函数。

//标准库需要的支持函数
struct __FILE
{
	int handle;
};

FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
	x = x;
} //标准库需要的支持函数
struct __FILE
{
	int handle;
};

FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
	x = x;
}

上面的这一份代码看的很头晕,没怎么看明白,希望有大神能指点

//重定义fputc函数
int fputc(int ch, FILE *f)
{
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
	USART1->DR = (u8) ch;
	return ch;
}//重定义fputc函数
int fputc(int ch, FILE *f)
{
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
	USART1->DR = (u8) ch;
	return ch;
}

fpuct函数,重定义了stdio.h文件里的函数

fputc()默认是把字符输出到调试器控制窗口,要把数据通过USART输出到串口助手,需对基于fputc()的printf()系列函数的输出都重定向到USART端口上去,要想使用USART功能,需重定向fputc()函数,

fpuct函数,重定义了stdio.h文件里的函数

fputc()默认是把字符输出到调试器控制窗口,要把数据通过USART输出到串口助手,需对基于fputc()的printf()系列函数的输出都重定向到USART端口上去,要想使用USART功能,需重定向fputc()函数,

除了半主机模式还有ITM机制调试

semihost/ITM机制浅析以及使用JLINK通过ITM调试stm32单片机

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

stm32中printf重定向 的相关文章

随机推荐

  • 了解串口协议,及完成STM32的USART串口通讯程序,并用keil观察波形

    文章目录 前言一 串口协议1 RS 2322 485标准 二 RS 232 485和TTL电平1 RS 232电平2 4853 TTL电平4 区别 三 USB TTL转2321 CH3402 发送接收3 USB转RS 232 四 完成一个S
  • UART RS232 RS485协议原理及应用

    一 URAT UART Universal Asynchronous Receiver Transmitter 通用异步收发传输器 xff0c 简称串口 xff0c 是设备间进行异步通信的模块 UART负责处理数据总线和串行口之间的串 并
  • 2022年电赛E题声源定位跟踪系统

    我们组本来是奔着视觉题去的 xff0c 可是到比赛的时候突然发现好像就无人机比较合适 xff0c 但是我们都没玩过无人机 xff0c 本想转战小车 xff0c 可是材料突然发现要两辆小车 xff0c 材料也不够来不及买 xff0c 于是我们
  • Python中requests库使用方法详解

    python中requests库使用方法详解 前言 xff1a 一 什么是Requests二 安装Requests库三 各种请求方式1 基本的GET请求2 带参数的GET请求3 解析json4 获取二进制数据5 添加headers6 基本P
  • File Browser的安装(适用于Kali/Ubuntu/Debian)

    filebrowser是一个基于Go开发的开源轻量级免费的文件浏览器 xff0c 可以把电脑上的文件快速传到其他设备上 1 下载 下载地址 xff1a https github com filebrowser filebrowser rel
  • Ubuntu 挂载硬盘到 /home 目录下扩容

    实验室提供的 NVIDIA Jetson NX 内存容量太小 xff0c 只有16G xff0c 刷完机装上系统和 CUDA 等安装包后 xff0c 系统只剩下一点多个G xff0c 后面完全是不够用的 xff0c 因此需要加硬盘并挂载才能
  • vue-element-admin 二次开发 报错修改

    安装 GitHub git clone https github com PanJiaChen vue element admin git Gitee https gitee com panjiachen vue element admin
  • 常用字符串函数

    1 strlen 函数 strlen 函数用来计算字符串长度 用法 xff1a 结果 xff1a 2 strcpy 函数 用来将一个数组的内容拷贝到另一个数组 用法 xff1a 结果 xff1a 注意 xff1a 如果a1中的比a2中的长
  • C++ 学习日志——STL中的容器 Vector

    本文简单的介绍下STL下的容器 vector的简单的存放和遍历方法 目录 一 vector存放和访问方式 二 三种遍历方式 三 vector存放对象 四 vector存放指针 难点 一 vector存放和访问方式 迭代器 xff1a vec
  • ARM汇编程序入门实践

    一 stm32程序 1 新建工程 1 xff09 双击打开keil xff0c 点击菜单栏Project gt New Vision Project xff0c 新建项目 xff0c 在弹窗中设置工程项目的名称和路径 xff0c 在这里 x
  • 【STM32学习笔记】(5)—— STM32工程添加源文件和头文件

    向工程目录里创建头文件和源文件 STM32的工程文件构成较为复杂 xff0c 同时为STM32工程文件添加源文件和头文件也是较为复杂的 xff0c 下面就由此文章来介绍怎么给STM32工程添加源文件 xff08 c xff09 与头文件 x
  • 在STM32中使用printf函数

    一 目的 利用printf函数使得输出打印到串口中 二 工作原理 我们在C语言中为什么能够调用printf函数打印数据到控制台中 xff0c 那是因为printf函数又调用了fputc 函数 那么我们我们可不可以说printf函数之所以能够
  • 电赛备赛日记(一):K210与STM32串口通信

    拖更了n久的备赛日记终于来啦 xff0c 最近实现了关于K210图像识别并将所需数据 xff08 即目标类别 xff0c 目标在图像中的加权坐标 xff09 其中 xff0c 加权坐标指K210识别到的目标并框出的框的宽和高与框左上顶点的坐
  • 实验作业2(数组)

    64 TOC实验题目2 xff1a 某公司生产5种产品 xff0c 每周记录生产的每种产品数量和销售数量 每个月月末 xff0c 公司将对其生产规划进行评估 该评估需要以下一个或多个信息 每周生成和销售的数量 xff1b 所有生产产品的总量
  • 函数作业

    仅供交流 xff0c 禁止抄袭 实验一 求序列的和 问题描述 求Y 61 1 1 2 43 1 3 1 4 43 1 2 n 的前n项之和 输入形式 从键盘输入n 输出形式 输出n项和 按四舍五入的方式精确到小数点后第二位 样例输入 30
  • Windows下MySQL安装及配置

    目录 1 MySQL下载2 MySQL配置 mysql版本 xff1a 5 7 注 xff1a 1 现在最新的mysql版本是8 0 xff0c 但是一般安装软件都不推荐安装最新版本的 xff0c 因为可能会有一些错误无法预见 xff0c
  • SLAM遇到的问题及技巧

    文章目录 1 rosbag太大了 xff0c 打不开2 机器人的三维变换roslaunch的node强制关闭了 xff0c exit code 11 1 rosbag太大了 xff0c 打不开 以LZ4格式压缩 rosbag compres
  • 关于螺旋数组的讨论

    下面收集了几种可能的螺旋数组形式以及相应的主代码 供大家学习参考 给定N的值 xff0c 从矩阵的左上角输出顺时针螺旋矩阵 例如N 61 4时 xff0c 输出 xff1a 1 2 3 4 12 13 14 5 11 16 15 6 10
  • 动态链接库dll详解

    动态链接库概述 DLL就是整个Windows操作系统的基础 动态链接库不能直接运行 xff0c 也不能接收消息他们是一些独立的文件 Windows API中的所有函数都包含在DLL中 其中有三个最重要的DLL kernel32 dll xf
  • stm32中printf重定向

    先上代码 加入以下代码 支持printf函数 而不需要选择use MicroLIB if 1 pragma import use no semihosting 标准库需要的支持函数 struct FILE int handle FILE s