OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13283|回复: 19

GCC编译STM32代码如何重定向printf函数

[复制链接]

23

主题

114

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2014-3-9
在线时间
103 小时
发表于 2017-11-2 14:30:57 | 显示全部楼层 |阅读模式
10金钱
屏幕快照 2017-11-02 14.26.01 (2).png 如图 在usart.c里面已经重定向了fputc函数,
但调用printf函数则会出现库报错,用gcc编译的朋友能告诉我是怎么回事吗,
附源码一份

stm32_lcd.zip (1.13 MB, 下载次数: 197)

最佳答案

查看完整内容[请看2#楼]

搞清楚了,gnu对printf的底层实现跟keil是不同的,所以不能直接用原子的那套方式来重定向接口, gnu99可以在编译参数里面加入 --specs=nano.specs [/backcolor] --specs=nosys.specs[/backcolor] 两个选项 重定向部分需要改写一下 gnu下是_write函数实现的,需要改写这个函数 而fputc函数就不用管了 //加入以下代码,支持printf函数,而不需要选择use MicroLIB [/backcolor] #if 0[/backcolor] #pragma import(__use_n ...
魔法王子
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

23

主题

114

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2014-3-9
在线时间
103 小时
 楼主| 发表于 2017-11-2 14:30:58 | 显示全部楼层
本帖最后由 huang_liquan 于 2017-11-6 18:18 编辑

搞清楚了,gnu对printf的底层实现跟keil是不同的,所以不能直接用原子的那套方式来重定向接口,
gnu99可以在编译参数里面加入
--specs=nano.specs
--specs=nosys.specs

两个选项
重定向部分需要改写一下
gnu下是_write函数实现的,需要改写这个函数 而fputc函数就不用管了
//加入以下代码,支持printf函数,而不需要选择use MicroLIB   
#if 0
#pragma import(__use_no_semihosting)            
//标准库需要的支持函数                 
struct __FILE
{
    int handle;
    /* Whatever you require here. If the only file you are using is */
    /* standard output using printf() for debugging, no file handling */
    /* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
void _sys_exit(int x)
{
    x = x;
}
//重定向fputc函数
//printf的输出,指向fputc,由fputc输出到串口
//这里使用串口1(USART1)输出printf信息
int fputc(int ch, FILE *f)
{      
    while((USART1->SR&0X40)==0);//等待上一次串口数据发送完成  
    USART1->DR = (u8) ch;       //写DR,串口1将发送数据
    return ch;
}
#endif //重定向代码如下
int _write (int fd, char *pBuffer, int size)  
{  
    for (int i = 0; i < size; i++)  
    {  
        while((USART1->SR&0X40)==0);//等待上一次串口数据发送完成  
        USART1->DR = (u8) pBuffer;       //写DR,串口1将发送数据
    }  
    return size;  
}





更新一下源码
用linux或mac OS开发的小伙伴们可以浪起来了
stm32_lcd.zip (1.02 MB, 下载次数: 478)
魔法王子
回复

使用道具 举报

5

主题

69

帖子

0

精华

高级会员

Rank: 4

积分
567
金钱
567
注册时间
2017-5-30
在线时间
70 小时
发表于 2017-11-2 16:46:59 | 显示全部楼层
膜拜大神。
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2017-11-3 08:53:20 | 显示全部楼层
yklstudent 发表于 2017-11-2 22:39
GCC感觉用的人不是很多

IAR用的多
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

23

主题

114

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2014-3-9
在线时间
103 小时
 楼主| 发表于 2017-11-3 09:02:38 | 显示全部楼层
yklstudent 发表于 2017-11-2 22:39
GCC感觉用的人不是很多

MAC OS的系统装不了keil
魔法王子
回复

使用道具 举报

2

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2017-10-13
在线时间
39 小时
发表于 2017-11-3 10:30:11 | 显示全部楼层
huang_liquan 发表于 2017-11-2 14:30
搞清楚了,gnu对printf的底层实现跟keil是不同的,所以不能直接用原子的那套方式来重定向接口,
gnu99可以 ...

真·大神啊,解决了困扰我半年的问题.实在搞不定我甚至写了一个简陋的printf用....
现在一句话搞定了......
int _write(int fd, char *pBuffer, int size)
{
        HAL_UART_Transmit(&huart1, pBuffer, size, 0xff);
        return size;
}
回复

使用道具 举报

6

主题

69

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
219
金钱
219
注册时间
2017-8-31
在线时间
45 小时
发表于 2018-5-3 13:54:25 | 显示全部楼层
必须浪,搞我好久。
回复

使用道具 举报

23

主题

114

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2014-3-9
在线时间
103 小时
 楼主| 发表于 2018-5-3 14:57:08 | 显示全部楼层
YST 发表于 2018-5-3 13:54
必须浪,搞我好久。

同道中人 STM32跑不跑C++
魔法王子
回复

使用道具 举报

6

主题

69

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
219
金钱
219
注册时间
2017-8-31
在线时间
45 小时
发表于 2018-5-3 16:17:36 | 显示全部楼层
huang_liquan 发表于 2018-5-3 14:57
同道中人 STM32跑不跑C++

目前还没有C++这方面的代码,都是C搞定,后续研究研究。
回复

使用道具 举报

23

主题

114

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
408
金钱
408
注册时间
2014-3-9
在线时间
103 小时
 楼主| 发表于 2018-5-3 18:40:30 | 显示全部楼层
YST 发表于 2018-5-3 16:17
目前还没有C++这方面的代码,都是C搞定,后续研究研究。

参考我的博客 不搞C++感觉不够浪

https://blog.csdn.net/u013908686/article/details/80045796
魔法王子
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2019-8-4
在线时间
4 小时
发表于 2019-8-9 00:40:27 | 显示全部楼层
krguang 发表于 2017-11-3 10:30
真·大神啊,解决了困扰我半年的问题.实在搞不定我甚至写了一个简陋的printf用....
现在一句话搞定了.... ...

牛人啊。。。。。
回复

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2019-5-28
在线时间
27 小时
发表于 2020-6-29 08:47:22 | 显示全部楼层
楼主太棒了,不过有个地方好像错了
一开始我直接把楼主的代码复制过去发现打印出来的是乱码
后来改成这样子就可以了
int _write (int fd, char *pBuffer, int size)  
{  
    for (int i = 0; i < size; i++)  
    {  
        while((USART1->SR&0X40)==0);//等待上一次串口数据发送完成  
        USART1->DR = (u8) *(pBuffer+i);       //写DR,串口1将发送数据
    }  
    return size;  
}
回复

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2018-5-27
在线时间
31 小时
发表于 2020-7-8 12:28:14 | 显示全部楼层
无法printf浮点数怎么办?加了-u _printf_float也不行
回复

使用道具 举报

0

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2020-5-3
在线时间
20 小时
发表于 2020-9-25 14:48:15 | 显示全部楼层
我想问一下,在macOS下是怎么进行串口调试的呢?
回复

使用道具 举报

2

主题

459

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4512
金钱
4512
注册时间
2018-5-14
在线时间
964 小时
发表于 2020-9-25 15:57:41 | 显示全部楼层
huang_liquan 发表于 2017-11-3 09:02
MAC OS的系统装不了keil

一样。不过我是用eclipse中添加 GNU ARM ECLIPSE插件开发的,它能生成一些初始化工程。我直接拷贝里面的_write.c和Trace.c重定向的(默认重定向到调试器)。它可以直接通过Jlink打印到控制台。不会额外占用串口,比较方便
回复

使用道具 举报

2

主题

459

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4512
金钱
4512
注册时间
2018-5-14
在线时间
964 小时
发表于 2020-9-25 15:58:29 | 显示全部楼层
gqx 发表于 2020-9-25 14:48
我想问一下,在macOS下是怎么进行串口调试的呢?

jlink可以直接用 gdb调试服务。stlink需要用openocd启动gdb服务
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2020-9-28 16:10:39 | 显示全部楼层
姚先起 发表于 2020-9-25 15:57
一样。不过我是用eclipse中添加 GNU ARM ECLIPSE插件开发的,它能生成一些初始化工程。我直接拷贝里面的_ ...

Mac或Linux系统可以用ST官方的STM32CubeIDE
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2020-9-28 16:19:12 | 显示全部楼层
本帖最后由 ufbycd 于 2020-9-28 16:24 编辑
远空w 发表于 2020-7-8 12:28
无法printf浮点数怎么办?加了-u _printf_float也不行

楼主添加编译参数“--specs=nano.specs ”有点误解,该参数是叫编译器链接nano C库,这个库不支持printf float,所以不用打印浮点数时才应该加这个参数,目的是减小目标文件体积。
另外,printf可以自己去实现,参考我以前的帖子: http://www.openedv.com/forum.php ... d=278292&extra=

回复

使用道具 举报

22

主题

2251

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4480
金钱
4480
注册时间
2013-4-22
在线时间
337 小时
发表于 2020-9-28 16:46:36 | 显示全部楼层
printf都是需要修改fputs和fgets那两个函数
回复

使用道具 举报

1

主题

8

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
452
金钱
452
注册时间
2019-8-3
在线时间
76 小时
发表于 2020-10-16 20:44:08 | 显示全部楼层
he798447699 发表于 2020-6-29 08:47
楼主太棒了,不过有个地方好像错了
一开始我直接把楼主的代码复制过去发现打印出来的是乱码
后来改成这样 ...

你好!请问下我在stm32cubeide里面编译的标志库程序,改成这样了,打印出来还是不对?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 10:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表