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,要對相應的串口進行初始化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章