Remap serial port to rt_kprintf function (study notes)

This article refers to [Wildfire EmbedFire] "RT-Thread Kernel Implementation and Application Development - Based on STM32", which is only used as a personal study note. For more detailed content and steps, please check the original text (you can download it from the Wildfire Data Download Center)

In RT-Thread, there is a printing function rt_kprintf(), which can output various information to facilitate our debugging. If you want to use rt_kprintf(), you must remap the console to rt_kprintf(). This console can be output devices such as serial port, CAN, USB, Ethernet, etc. The most used one is serial port. The serial port is redirected to rt_kprintf().

hardware initialization

The hardware to be used here is the serial port. I directly copied the bottom-level code of the serial port of Wildfire.

insert image description here

Modify the board.cfile and add the serial port initialization function

void rt_hw_board_init(void)
{
    
    
#if 0
    /* TODO: OS Tick Configuration */
    _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
#endif
	
	/* 初始化 SysTick */
	SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);

	/* 硬件 BSP 初始化统统放在这里,比如 LED,串口,LCD 等 */
	
	// LED初始化
	LED_GPIO_Config();
	
	// 串口初始化
	USART_Config();

    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}

Custom rt_hw_console_output()

rt_kprintf()Two ways of output are supported, one is when the device driver is used, the device will be used as the console; the other is when the device driver is not used, the system processes the output device through rt_hw_console_output()functions .rt_kprintf()

rt_hw_console_output()In board.cthe implementation, the following code refers to "RT-Thread Kernel Implementation and Application Development - Based on STM32", using library functions.

#ifdef RT_USING_CONSOLE
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);
		}
		
		USART_SendData(DEBUG_USARTx, *str++);
	  	while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
	}
 		
	/* 退出临界段 */
	rt_exit_critical();
}

The first line above indicates that if you want to use the console, you also need to enable it. Method: Modify rtconfig.hand enable the corresponding macro definition.

insert image description here

write test code

Next we create threads to test rt_kprintf(), using dynamic threads (the code used in the previous article)

#include "board.h"
#include "rtthread.h"

// 定义线程控制块指针
static rt_thread_t led0_thread = RT_NULL;

/******************************************************************************
* @ 函数名  : led0_thread_entry
* @ 功  能  : LED0线程入口函数
* @ 参  数  : parameter 外部传入的参数
* @ 返回值  : 无
******************************************************************************/
static void led0_thread_entry(void *parameter)
{
    
    
	while(1)
	{
    
    
		LED0(ON);
		rt_thread_delay(500); // 500个tick(500ms)
		rt_kprintf("kprintf test, LED0_ON\r\n");
		LED0(OFF);
		rt_thread_delay(500);
		rt_kprintf("kprintf test, LED0_OFF\r\n");
	}
}

int main(void)
{
    
    
	// 硬件初始化和RTT的初始化已经在component.c中的rtthread_startup()完成

	// 创建一个动态线程
	led0_thread =                                 // 线程控制块指针
	rt_thread_create("led0",                      // 线程名字
	                led0_thread_entry,            // 线程入口函数
	                RT_NULL,                      // 入口函数参数
	                255,                          // 线程栈大小
				    5,                            // 线程优先级
					10);                          // 线程时间片
	
	// 开启线程调度
	if(led0_thread != RT_NULL)
		rt_thread_startup(led0_thread);
	else
		return -1;			
}


Simulation with Keil Debug

If there is no hardware at hand, we can use Keil's Debug function to test serial port printing,

  • First, modify the debugging to software simulation debugging:

insert image description here

  • Open the serial port debugging window (at this time, the serial port can only be read but not written, and the serial port transmission has not been implemented)

insert image description here

  • But when I run it for the first time, I get the following error:

insert image description here

  • I went to the Internet to find a solution, and found that software debugging needs to specify the chip model (this is indeed very reasonable)

insert image description here

  • Fill in the corresponding DLL and parameters into the corresponding edit box under the simulation,

insert image description here

  • Software simulation again, you can see that UART #1the serial port prints out the rt_kprintf()content of the thread, and the test is successful.

insert image description here

Experimental effect

The following is the real experimental effect:

insert image description here

Guess you like

Origin blog.csdn.net/weixin_43772810/article/details/123652008