RT-Thread—重映射串口到rt_kprintf

重映射

在初学C语言时,用的最多的怕是printf()函数了,其作用就是将传入的参数打印到屏幕上,可以实现人机交互或方便用户对程序的调试等等。
在RT-Thread中,也有一个打印函数rt_kprintf(),其作用和printf()类似,可以在调试时输出各种信息。但是如果想要使用rt_kprintf()函数,就必须将控制台重映射到rt_kprintf(),这个控制台可以是串口、CAN、USB、以太网等输出设备,这里主要介绍一下将串口重定向到rt_kprintf()

rt_kprintf()函数定义

rt_kprintf()函数是在kservice.c文件中实现的,属于内核服务类函数,源代码如下:

/**
 * 简介:这个函数是用来向控制台打印特定格式的字符串
 * 参数:fmt指定的格式
 */
void rt_kprintf(const char *fmt, ...)
{
    va_list args;
    rt_size_t length;
    /* 定义一个字符缓冲区,用于储存将要发生的字符串,默认大小为128 */
    static char rt_log_buf[RT_CONSOLEBUF_SIZE];

    va_start(args, fmt);
    /* 调用rt_vsnprintf()函数,将要输出的字符串按照fmt指定的格式传到rt_log_buf[]
       缓冲区,然后我们将缓冲区的内容输出到控制台就可以了 */
    length = rt_vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args);
    /* 判断字符串是否超过大小范围,超过的话要裁剪 */
    if (length > RT_CONSOLEBUF_SIZE - 1)
        length = RT_CONSOLEBUF_SIZE - 1;
 /* 如果使用设备驱动,通过设备驱动函数将缓冲区的内容输出到控制台 */
#ifdef RT_USING_DEVICE
    if (_console_device == RT_NULL)
    {
        rt_hw_console_output(rt_log_buf);
    }
    else
    {
        rt_uint16_t old_flag = _console_device->open_flag;

        _console_device->open_flag |= RT_DEVICE_FLAG_STREAM;
        rt_device_write(_console_device, 0, rt_log_buf, length);
        _console_device->open_flag = old_flag;
    }
/* 如果不使用设备驱动函数,使用rt_hw_console_output()函数将缓冲区的内容输出到控制台 */
#else
    rt_hw_console_output(rt_log_buf);
#endif
    va_end(args);
}
RTM_EXPORT(rt_kprintf);
#endif

总的来说:使用rt_kprintf()实现重映射就是先将要显示的字符串传入rt_kprintf()的形参中,字符串会被放在rt_kprintf()中申请好的一段缓冲区中,然后将缓冲区中的内容输出到指定的控制台(通过rt_hw_console_output()函数),这样就实现了重映射,这里我们要重映射到串口,所以要对rt_hw_console_output()函数进行定义!

自定义rt_hw_console_output()

rt_hw_console_output()函数可以将缓冲区中的字符串输出到指定的控制台,这里我们将字符串输出到串口,也就是将串口控制台重映射到rt_kprintf()函数,rt_hw_console_output()的代码如下:

void rt_hw_console_output( const char *str )
{
    /* 进入临界段 */
	rt_enter_critical();
	while(*str != '\0')
	{
		if( *str=='\n' )
		{
		   /* 选择串口发送字符串 */
			USART_SendData( DEBUG_USARTx, '\r' );
			while(USART_GetFlagStatus( DEBUG_USARTx, USART_FLAG_TXE )==RESET)
				;
		}
	}
	/* 退出临界段 */
	rt_exit_critical();
}

注意:重映射串口到rt_kprintf,要对相应的串口进行初始化。

发布了62 篇原创文章 · 获赞 188 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43743762/article/details/103108983