rt-thread中基于开启设备驱动和未开启设备驱动下的rt_kprintf()函数的分析

/*** rtconfig.h ***/

/* Kernel Device Object */

#define RT_USING_DEVICE  //开启设备驱动的定义
#define RT_USING_CONSOLE //开启shell命令输出功能
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart1" //默认输出设备名称
#define RT_VER_NUM 0x40001
#define ARCH_ARM
#define ARCH_ARM_CORTEX_M
#define ARCH_ARM_CORTEX_M4

rt_kprintf()函数

/*** kservice.c **/
/**
 * This function will print a formatted string on system console
 *
 * @param fmt the format
 */
void rt_kprintf(const char *fmt, ...)
{
    va_list args;
    rt_size_t length;
    static char rt_log_buf[RT_CONSOLEBUF_SIZE];

    va_start(args, fmt);
    /* the return value of vsnprintf is the number of bytes that would be
     * written to buffer had if the size of the buffer been sufficiently
     * large excluding the terminating null byte. If the output string
     * would be larger than the rt_log_buf, we have to adjust the output
     * length. */
    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;
    }
#else
//不使用 RT-Thread 的设备驱动,则使用以下函数作为console输出
    rt_hw_console_output(rt_log_buf);
#endif
    va_end(args);
}
RTM_EXPORT(rt_kprintf);
#endif

如果使用 RT-Thread 的设备驱动,则打印输出功能由设备驱动完成,默认的输出设备在drv.common.c中定义

/** drv.common.c ***/

    /* Set the shell console output device */
#ifdef RT_USING_CONSOLE
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif

如果不使用 RT-Thread 的设备驱动 ,那通过 rt_kprintf 输出的内容则由rt_hw_console_output 函数处理, 这个函数需要用户单独实现

参考:

  • [野火®]《RT-Thread+内核实现与应用开发实战—基于STM32》.pdf

/*** main.c **/
/**
 * @brief 重映射串口1 到rt_kprintf
 * @param str:要输出到串口的字符串
 * @retval 无
 *
 * @attention 在标准固件库下的定义
 *
 */
void rt_hw_console_output(const char *str)
{	
    /* 进入临界区 */
	rt_enter_critical();

    /* 直到字符串结束 */
	while (*str!='\0')
	{
		if (*str=='\n')
		{
			USART_SendData(USART1, '\r'); 
			while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
		}

		USART_SendData(USART1, *str++); 				
		while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	
	}	
    /* 退出临界区 */
	rt_exit_critical();
}

注册uart设备

参考:

  • https://www.rt-thread.org/download/manual/rtthread_manual.zh.pdf

rt-thread中基于开启设备驱动和未开启设备驱动下的rt_kprintf()函数的分析_第1张图片

rt-thread中基于开启设备驱动和未开启设备驱动下的rt_kprintf()函数的分析_第2张图片

你可能感兴趣的:(STM32,物联网)