Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题

这篇具有很好参考价值的文章主要介绍了Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


在直接将CANopenSTM32的示例工程直接移植到Keil环境下。
如果移植工程未实现printf函数重定向,则要注释掉log_printf下面的printf函数,使日志打印失效
/* Printf function of CanOpen app */
#define log_printf(macropar_message, ...) //printf(macropar_message, ##__VA_ARGS__)

在未在选项中勾选使用微库的时候,程序会卡死。调试会发现是卡死在了BKAP 0xAB处,网上搜索会有很多说明,是因为使用了printf函数而为实现重定向导致的。解决办法1:勾选上使用微库。办法2:禁用半主机模式。
选择办法1后进行编译,程序可以正常运行了。

问题描述

因为我在其它工程上使用arm clang编译器,因而不能选择勾选微库的方式。因而我尝试办法2,但这时就出现了比较奇怪的问题(两个编译器都会出现这个奇怪的问题,这里是在armcc编译器下的测试)

按照我之前文章中https://blog.csdn.net/xiaoyuanwuhui/article/details/110538555描述的如下方式便可以重定向。

/* ------------------通过重定向将printf函数映射到串口1上-------------------*/
#if !defined(__MICROLIB)

#pragma import(__use_no_semihosting)
void _sys_exit(int x) //避免使用半主机模式
{
  x = x;
}
//__use_no_semihosting was requested, but _ttywrch was 
void _ttywrch(int ch)
{
    ch = ch;
}
typedef struct __FILE
{
  int handle;
}FILE;

#endif

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif 
PUTCHAR_PROTOTYPE
{
  /* 实现串口发送一个字节数据的函数 */
  //serial_write(&serial1, (uint8_t)ch); //发送一个自己的数据到串口
	//HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
  return ch;
}

但是在添加了上述内容后,进行编译提示了如下报错:请求禁用半主机模式,但是_sys_open函数未定义
Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题,CANopenNode,STM32,stm32,CANopenNode
仿照之前定义_sys_exit()函数的方式定义_sys_open()函数,如下:

void _sys_open(int x)
{
  x = x;
}

然后进行编译程序又出现了如下报错:_sys_open函数重复定义
Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题,CANopenNode,STM32,stm32,CANopenNode
至此,一脸懵逼,到底什么情况:不定义提示缺少定义,定义了又提示重复定义,只能是无语了。期待有大佬可以详细描述下这是怎么回事 ,不胜感激!

问题结决

https://developer.arm.com/documentation/ka002219/latest文章中提供了一种半主机问题的解决方案:使用RTE(Run-Time-Environment)中的Compiler组件重新定位标准C运行时库的I/O函数。
Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题,CANopenNode,STM32,stm32,CANopenNode
这里我只针对于解决上面的问题,如上图所示,在STDOUT处选中,并将后面的值改为User。
将程序中之前重定向的代码全部移除掉,然后进行编译,这时仍会有一个报错提示,如下:
Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题,CANopenNode,STM32,stm32,CANopenNode
这是因为我们选择了重定向输出,还需要实现对应的stdout_putchar函数(用于打印一个字符到输出设备),一般而言这需要通过串口实现发送一个字符的功能,这里暂时先定义一个空函数:

int stdout_putchar (int ch) {

}

然后再进行编译,结果如下:
Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题,CANopenNode,STM32,stm32,CANopenNode
此时已经没有报错了,程序下载到单片机上也可以正常运行了。

思考:

为什么这种方式可以解决问题,之前的方式就不可以呢?
这里我们将RTE下的retarget_io.c文件中的内容复制一份到retarget.c文件,并添加到工程中,然后将之前勾选的RTE中的STDOUT的取消,在retarget.c文件的前面添加上如下宏定义并注释掉RTE组件头文件

//#include "RTE_Components.h"
#define RTE_Compiler_IO_STDOUT_User
#define RTE_Compiler_IO_STDOUT

直接进行编译,也没有出现报错,下载到单片机中也可以正常运行。

__attribute__((weak))
FILEHANDLE _sys_open (const char *name, int openmode) {};
__attribute__((weak))
int _sys_close (FILEHANDLE fh) {};
__attribute__((weak))
int _sys_write (FILEHANDLE fh, const uint8_t *buf, uint32_t len, int mode) {};
__attribute__((weak))
int _sys_istty (FILEHANDLE fh) {};
__attribute__((weak))
int _sys_seek (FILEHANDLE fh, long pos) {};
__attribute__((weak))
long _sys_flen (FILEHANDLE fh) {};

上面这6个函数注释掉哪一个都会出现如下报错:
Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题,CANopenNode,STM32,stm32,CANopenNode
好像是要将所有的这几个函数都实现了才不会调用C库中的函数。
进一步实验:
将上面的6个函数的空语句添加到main.c的空白位置,然后进行编译,发现不会报错,但程序下载到单片机内依然会卡死。
再在6个函数的前面添加上__stdin_name,__stdout_name,__stderr_name的定义

#include <rt_sys.h>
///* Standard IO device name defines. */
const char __stdin_name[]  = ":STDIN";
const char __stdout_name[] = ":STDOUT";
const char __stderr_name[] = ":STDERR";
__attribute__((weak))
FILEHANDLE _sys_open (const char *name, int openmode) {};
__attribute__((weak))
int _sys_close (FILEHANDLE fh) {};
__attribute__((weak))
int _sys_write (FILEHANDLE fh, const uint8_t *buf, uint32_t len, int mode) {};
__attribute__((weak))
int _sys_istty (FILEHANDLE fh) {};
__attribute__((weak))
int _sys_seek (FILEHANDLE fh, long pos) {};
__attribute__((weak))
long _sys_flen (FILEHANDLE fh) {};

然后再进行编译也不会报错,下载到单片机内也可以正常运行。
初步结论:只有6个函数和3个变量都定义了才能完成完整的重定向功能。
实际应用时还是建议直接使用RTE的组件,这里拆分出来是为了进一步分析。

相关文章

std::mt19937 with ARM Compiler 6 uses sys_open and breaks retarget.c
I/O Retargeting文章来源地址https://www.toymoban.com/news/detail-534783.html

到了这里,关于Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【STM32】Keil V5联合VSCode配置代码编写与下载环境,解决报错问题

    最近重新捡起了STM32的开发工作,由于之前一年多的时间一直在从事PC端与Linux下的开发,习惯了VSCode的开发界面以及各种方便的插件,再次打开keil的界面时倍感丑陋。于是花了不少心思配置了VSCode中的代码编写环境,再次特做记录。 VSCode的插件商店中其实包含了支持Keil的插

    2024年02月06日
    浏览(79)
  • MPU6050(读取原数据、移植DMP、stm32f4、HAL库、KEIL5)

    记录一下自己遇到的问题及解决方法,希望能帮助到一些人。 第一步,读取芯片的原始数据。需要注意两点:1、对HAL库提供的IIC读取写入函数进行再包装。(千万不要觉的这步多此一举,后面移植DMP时用得到) 2、芯片的地址(这里面有俩坑)第一就是,芯片的 I2C 设备地址

    2023年04月08日
    浏览(54)
  • STM32F7xx Keil5 RTX RL-TCPnet DP83822移植

    暂时全部默认配置,DHCP已打开 修改RTE_Device.h ETH配置 修改DP83822驱动 去掉文件只读属性,之后需要修改,添加到工程 修改DP83822 ID RTE创建tcp server例程,参考该例程,进行修改 修改后的TCP_Socket_server.c ping Tcp client 可以PING通,但client无法连接,后来发现是netInitialize以及server相关

    2024年02月08日
    浏览(50)
  • STM32使用串口printf乱码问题解决方法

    使用stm32系列单片机串口打印问题,在使用HAL库重新定义printf为串口输出后,输出的内容全都是乱码,试了网上的方法后还是乱码。  像这样的    最后发现是串口调试助手和keil的文字编码方式不同, keil中是GB 2312,串口调试助手是UFT_8,所以打印出来才会乱码  将串口调试助

    2024年02月11日
    浏览(38)
  • STM32H5移植zbar记录

    ZBar是一种流行的二维码扫描和解码工具,它在嵌入式系统中拥有广泛的应用。在嵌入式系统中,我们面临着有限的资源和更严格的性能要求,因此,选择适当的库来完成特定的任务非常重要。 ZBar适用于各种嵌入式平台,包括ARM、x86和MIPS等处理器架构。它可以轻松地整合到各

    2024年02月06日
    浏览(42)
  • 关于STM32F4系列中printf重定向问题详解

    前言 关于 printf函数 和 fputc函数 联系和区别 联系: 1.共同目标: printf 函数和 fputc 函数都用于将字符 输出到指定的输出流中 。 2.字符输出: 两个函数都可以用于输出一个字符,但在实际使用时, printf 函数 通常用于输出 格式化的数据 ,而 fputc 函数 更常用于 单个字符的直

    2024年02月03日
    浏览(47)
  • Keil5编译环境搭建流程----STM32和GD32

    以下蓝色字体是对应文章的链接,单击便可以查看详细信息! 文章链接: Keil5-MDK下载和安装教程 资源链接: Keil5_MDK安装包链接----点击下载 文章链接: stm32芯片包下载和安装教程 GD32芯片包下载和安装教程 资源链接: Keil5-STM32芯片包链接----点击下载 Keil5-GD32芯片包链接---

    2024年02月05日
    浏览(61)
  • 【正点原子STM32探索者】CubeMX+Keil开发环境搭建

    本文主要分为三部分,第一部分介绍正点原子STM32探索者开发板外观和配套资料如何下载,第二部分介绍如何搭建CubeMX+Keil开发环境,第三部分介绍如何使用CubeMX和Keil一步步创建出一个点亮LED灯的项目。搭建开发环境部分,包括安装Keil MDK、安装STM32 CubeMX、安装STM32F4系列MCU的

    2024年03月16日
    浏览(82)
  • 【32】STM32F103在Keil4软件下开发环境的建立

    目录 一、下载STM32F10x 固件库下载 二、对所需的库文件分类存放 三、配置Keil4开发环境 STM32 固件库 STM32 Standard Peripheral Libraries,适用于STM32F1系列 STM32 的固件库是芯片官方给出的用于新建STM32工程与相关的库文件,示例程序的文件包。 STM32F103的固件库可以去STM官网下载 https

    2024年02月04日
    浏览(65)
  • Keil MDK编程环境下的 STM32 IAP下载(学习笔记)

    ICP ICP(In Circuit Programing)。在电路编程,可通过 CPU 的 Debug Access Port 烧录代码,比如 ARM Cortex 的 Debug Interface 主要是 SWD(Serial Wire Debug) 或 JTAG(Joint Test Action Group); ISP ISP(In System Programing)。在系统编程,可借助 MCU 厂商预置的 Bootloader 实现通过板载 UART 或 USB 接口烧录代码,比如

    2024年02月06日
    浏览(41)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包