使用的keil版本为:5.21a IAR for 8051 version 为 10.10.1
(f4)串口2:
下面这个是TI 的cc2530(就先跑着寄存器版本的吧,协议栈里头配置差不太多!):
为啥要移植呢!相信学过实时操作系统的都有所了解,有个叫互斥信号量的东西!就是为了防止同一时间内有两个寄存器(那十来个寄存器,不是指外设!)在访问同一块内存!这个很严重的,可能会导致程序死机,或者卡在了某个死循环里面!
我们所使用的 printf 就是首先通过 vsprinf 对我们传进来的参数进行格式化,我们传进去多少数据,他按照我们传进来的格式,格式化后统统存放在一个buf里,如果我们定义了重定向,它就会把这个buf发送至你要发送的地方!
想象一下,如果在某个系统中有一个线程在vsprintf里面运行,突然有一个任务级别比他高的任务把它运行的时间抢了过去!而任务优先级高的任务也在printf里面使用了那个buf,那就会产生上述的问题!
那就意味着我们所使用的 printf 存在不安全问题!当然我们在系统中可以通过临界保护区来处理,也可以通过信号量等等处理!
但是目前有一个线程安全
的函数,摆在你面前,就问你用不用?
那我们的上边 printf_u1 它是怎么处理的呢?毫无疑问,看代码就能知道,它是直接发送的,也就是说你传进来的每一个参数它都会顺手就发送出去(当然要看你配置),它的数据将不会存放在一个 buf 里边,在发送。这就是他给力的地方了!
keil移植printf
首先,我们到文章的末尾获取到源代码后,打开 keil 软件,
点击 project > Options for…
就能打开一下页面:
下面来配置代码部分,打开头文件为printf.h:
来到这里之后我们可以看到_vsprintf 这个代码里面最复杂的就是这一串函数了!
//我们只需要关心第一个参数即可!它是一个函数指针
static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
//指向了一个参数为下图的函数,返回值为void
typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen);
static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)buffer; (void)idx; (void)maxlen;
if (character)
{
_putchar(character,1);
}
}
上图是串口1的。再来看看串口2的:
int printf_u2(const char* format, ...)
{
va_list va;
va_start(va, format);
char buffer[1];
const int ret = _vsnprintf(u2_out_char, buffer, (size_t)-1, format, va);
va_end(va);
return ret;
}
//注意vsprintf第一参数
static inline void u2_out_char(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)buffer; (void)idx; (void)maxlen;
if (character) {
_putchar(character,2);
}
}
而_putchar 就是我们数据最终流向的地方了!我是这样写的。
void _putchar(char character,char sw)
{
// send char to console etc.
if(sw == 1)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) character;
}
if(sw == 2)
{
while((USART2->SR&0X40)==0);//循环发送,直到发送完毕
USART2->DR = (u8) character;
}
if(sw == 3)
{
while((USART3->SR&0X40)==0);//循环发送,直到发送完毕
USART3->DR = (u8) character;
}
}
这个 USART3->DR 为stm32串口的寄存器!读者可参照自己的芯片来配置!
简单就完了!
IAR 配置方法
首先添加文件:
我在这里起名字为 C_Library。然后在添加文件:
在选择第一个大框框右边的那个:
程序编译通过!printf_u0 和stm32 配置类型,无非就是修改一下数据的流向!读者自己研究一下吧!!
原文:https://blog.csdn.net/dasuanweideyagao/article/details/115155026?spm=1001.2014.3001.5501
文章来源于网络,版权归原作者所有,如有侵权,请联系删除。