重映射串口到 rt_kprintf 函数(学习笔记)

本文参考自[野火EmbedFire]《RT-Thread内核实现与应用开发实战——基于STM32》,仅作为个人学习笔记。更详细的内容和步骤请查看原文(可到野火资料下载中心下载)

在 RT-Thread 中,有一个打印函数 rt_kprintf(),它可以输出各种信息,方便我们的调试。如果要想使用 rt_kprintf(),必须将控制台重映射到 rt_kprintf(),这个控制台可以是串口、CAN、USB、以太网等输出设备,用的最多的就是串口,接下来我们讲解下如何将串口重定向到 rt_kprintf()。

硬件初始化

这里要用到的硬件是串口,我直接拷贝了野火的串口底层代码,

在这里插入图片描述

修改board.c文件,添加串口初始化函数

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
}

自定义 rt_hw_console_output()

rt_kprintf()支持两种方式的输出,一种是当使用设备驱动时,将设备将作为控制台;另外一种是当没有使用设备驱动时,系统通过rt_hw_console_output()函数处理rt_kprintf()输出的设备。

rt_hw_console_output()board.c中实现,下面的代码参考《RT-Thread内核实现与应用开发实战——基于STM32》,使用的是库函数。

#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();
}

上面第一行表示要想使用控制台,还需要对其进行使能,方法:修改rtconfig.h,开启对应宏定义。

在这里插入图片描述

编写测试代码

接下来我们创建线程来测试rt_kprintf(),用的是动态线程(上一篇文章所用的代码)

#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;			
}


使用Keil Debug仿真

如果手头上没有硬件,我们可以使用Keil的Debug功能来测试串口打印,

  • 首先将调试修改成软件模拟调试:

在这里插入图片描述

  • 打开串口调试窗口(此时串口只能读不能写,还没有实现串口发送)

在这里插入图片描述

  • 但是我第一次运行时出现了如下报错:

在这里插入图片描述

  • 到网上找了一下解决方法,发现软件调试是需要指定芯片型号的(这的确很合理)

在这里插入图片描述

  • 将对应的DLL和参数填写到模拟仿真下面的对应编辑框中,

在这里插入图片描述

  • 再次软件仿真,可以看到UART #1串口打印出了线程里rt_kprintf()的内容,测试成功。

在这里插入图片描述

实验效果

下面是真实的实验效果:

在这里插入图片描述

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
感谢您提出的问题!根据您的描述,您想要使用depthimage_to_laserscan节点将订阅的depth话题重映射为oak-d发布的/stereo/depth,并将订阅的depth_camera_info话题重映射为oak-d发布的/stereo/camera_info。然后,您希望将发布的scan重映射为/oak_scan。此外,您还需要运行静态tf变换,将camera_depth_optical_frame变换到oak-d_frame。 要实现这个功能,您可以按照以下步骤进行操作: 1. 在launch文件或终端中,使用remap命令来重映射订阅的depth话题和depth_camera_info话题。例如: ``` <node name="depthimage_to_laserscan" pkg="depthimage_to_laserscan" type="depthimage_to_laserscan" output="screen"> <remap from="depth" to="/oak-d/stereo/depth"/> <remap from="depth_camera_info" to="/oak-d/stereo/camera_info"/> </node> ``` 2. 在同一个launch文件或终端中,使用remap命令将发布的scan话题重映射为/oak_scan。例如: ``` <node name="scan_publisher" pkg="depthimage_to_laserscan" type="scan_publisher"> <remap from="scan" to="/oak_scan"/> </node> ``` 3. 运行静态tf变换,将camera_depth_optical_frame变换到oak-d_frame。您可以使用tf_static发布器来完成此操作。具体实现方式取决于您所使用的ROS版本。 请注意,这些步骤是一种可能的实现方法,具体的实现方式可能因您的代码结构和需求而有所不同。请根据您的实际情况进行调整。 希望这可以帮助到您!如果您还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小辉_Super

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值