欢迎光临散文网 会员登陆 & 注册

教程示例:嵌入式软件移植 printf

2023-06-15 16:59 作者:补给站Linux内核  | 我要投稿

在嵌入式中printf 这种功能强大的函数可谓是c语言库函数的中的一股清流!也就是太好用了吧!今天分享的例程有 stm32f4ZG 和 cc2530f256,这个两款芯片的移植例程和移植教程!相信你看完后也可以移植到别的芯片去!

  • 使用的keil版本为:5.21a

  • IAR for 8051 version 为 10.10.1

可能会因为有些版本不同配置就略有所不同!(f4)串口1:

(f4)串口2:

下面这个是TI 的cc2530(就先跑着寄存器版本的吧,协议栈里头配置差不太多!):

为啥要移植呢!相信学过实时操作系统的都有所了解,有个叫互斥信号量的东西!就是为了防止同一时间内有两个寄存器(那十来个寄存器,不是指外设!)在访问同一块内存!这个很严重的,可能会导致程序死机,或者卡在了某个死循环里面!

我们所使用的 printf 就是首先通过 vsprinf 对我们传进来的参数进行格式化,我们传进去多少数据,他按照我们传进来的格式,格式化后统统存放在一个buf里,如果我们定义了重定向,它就会把这个buf发送至你要发送的地方!

想象一下,如果在某个系统中有一个线程在vsprintf里面运行,突然有一个任务级别比他高的任务把它运行的时间抢了过去!而任务优先级高的任务也在printf里面使用了那个buf,那就会产生上述的问题!

那就意味着我们所使用的 printf 存在不安全问题!当然我们在系统中可以通过临界保护区来处理,也可以通过信号量等等处理!

但是目前有一个线程安全的函数,摆在你面前,就问你用不用?

那我们的上边 printf_u1 它是怎么处理的呢?毫无疑问,看代码就能知道,它是直接发送的,也就是说你传进来的每一个参数它都会顺手就发送出去(当然要看你配置),它的数据将不会存放在一个 buf 里边,在发送。这就是他给力的地方了!


【文章福利】小编推荐自己的Linux内核技术交流群:【749907784】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)    



keil移植printf

首先,我们到文章的末尾获取到源代码后,打开 keil 软件, 点击 project > Options for… 就能打开一下页面:

点击 C/C++,选择c99标准。到此为止编译器配置完毕!

下面来配置代码部分,打开头文件为printf.h:

1,添加这个两个文件的路径还有头文件,如果不懂可以搜搜!2,点击图片上面的printf_ 去它定义的地方,我们要做出一定的修改。

来到这里之后我们可以看到_vsprintf 这个代码里面最复杂的就是这一串函数了!

我们只要修改这_putchar 里面的内容即可。参数二是我加上去的为了区分不同的串口类型,有多少个串口就的写多少个_out_char 这样的函数(这个是我的方法):

上图是串口1的。再来看看串口2的:

而_putchar 就是我们数据最终流向的地方了!我是这样写的。

这个 USART3->DR 为stm32串口的寄存器!读者可参照自己的芯片来配置!

简单就完了!

IAR 配置方法

首先添加文件:

我在这里起名字为 C_Library。然后在添加文件:

选择 printf.c (反正就是添加这个文件,放到哪里看你自己):

接着就是添加编译器头文件路径:

在选择第一个大框框右边的那个:

点击Click to add。选择头文件路径所在的文件夹后 select,接着就会回到这里:

上面是配置头文件路径的,第一个是绝对路径,也就是说你工程文件移动了,就回到不到了,第二个是相对路径!选第二个吧!接着编译就会发现报错了!!!不要慌!我们首先选择Options > General Options:

此时在编译一次,就会发现也还是错了!说什么没定义。经研究,哦,原来是stdint.h这个头文件在for 8051 这款工具上,没有定义64为的无符号整形,那个怎么办啊!经发现,哦 ,原来注释这个宏就行!

程序编译通过!printf_u0 和stm32 配置类型,无非就是修改一下数据的流向!读者自己研究一下吧!!

原文作者:【一起学嵌入式 】


教程示例:嵌入式软件移植 printf的评论 (共 条)

分享到微博请遵守国家法律