STM32CUBEMX_日志系统_RTT和串口(重映射浮点数打印)

STM32CUBEMX_日志系统_RTT和串口(重映射浮点数打印)

前言:
嵌入式系统开发过程中日志的打印至关重要,他在系统架构搭建和开发过程中包括后期调试定位问题都非常重要,所以在此记录两种日志打印的方式。第一种是移植J-link中自带的RTT(SWD或GADG接口打印日志),这种方式优点非常明显,不用额外占用一个串口资源(优先推荐使用),第二种就是使用一个串口当做日志的打印,优点是常见,不用依托于J-ink使用。

注意:移植RTT过程我已经写了一片文章,详见https://blog.csdn.net/weixin_50183638/article/details/124633472
①在裸机系统中使用没有什么注意的,直接调用SEGGER_RTT_printf(0,“SEGGER RTT Terminal\r\n”);
②需要打印不同的颜色,直接调用SEGGER_RTT_printf(0,RTT_CTRL_TEXT_GREEN"SEGGER RTT Terminal\r\n");
③需要打印到RTT_Viewer的不同的串口,先设置一下输出接口就好了,SEGGER_RTT_SetTerminal(0);
④在FREERTOS系统中,两个任务中不能同时调用SEGGER_RTT_printf(0,“SEGGER RTT Terminal\r\n”);会使系统卡死
⑤使用printf重映射后,不管是串口方式还是RTT方式都可以在不同的线程中打印日志
⑥注意包含头文件,使用printf时注意包含头文件#include “stdio.h”

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */     
#include "SEGGER_RTT.h"
#include "stdio.h"
#include "usart.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/**********************************************自定义的日志打印函数*********************************************************/
#define USER_MAIN_DEBUG 1  //日志打印功能使能开关
 
#ifdef USER_MAIN_DEBUG
#define user_main_printf(format, ...) 	printf(RTT_CTRL_TEXT_WHITE format "\r\n", ##__VA_ARGS__)
#define user_main_info(format, ...)   	printf(RTT_CTRL_TEXT_GREEN"[main]info:" format "\r\n", ##__VA_ARGS__)
#define user_main_debug(format, ...)  	printf(RTT_CTRL_TEXT_WHITE"[main]debug:" format "\r\n", ##__VA_ARGS__)
#define user_main_warning(format, ...)  printf(RTT_CTRL_TEXT_YELLOW"[main]debug:" format "\r\n", ##__VA_ARGS__)
#define user_main_error(format, ...)  	printf(RTT_CTRL_TEXT_RED"[tmain]error:" format "\r\n",##__VA_ARGS__)
#else
#define user_main_printf(format, ...)
#define user_main_info(format, ...)
#define user_main_debug(format, ...)
#define user_main_error(format, ...)
#endif

/**********************************************自定义的日志打印函数*********************************************************/

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId_t defaultTaskHandle;
osThreadId_t myTask02Handle;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);
void StartTask02(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */
       
  /* USER CODE END Init */
osKernelInitialize();

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  const osThreadAttr_t defaultTask_attributes = {
    .name = "defaultTask",
    .priority = (osPriority_t) osPriorityNormal,
    .stack_size = 512
  };
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* definition and creation of myTask02 */
  const osThreadAttr_t myTask02_attributes = {
    .name = "myTask02",
    .priority = (osPriority_t) osPriorityLow,
    .stack_size = 512
  };
  myTask02Handle = osThreadNew(StartTask02, NULL, &myTask02_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used 
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
	char GetKey;
  /* Infinite loop */
  for(;;)
  {
		/*********************************************接收RTT_Virwer发送字符*********************************************************/
		if (SEGGER_RTT_HasKey())            /*判断接受缓冲区中是否有数据*/
		{
				GetKey = SEGGER_RTT_GetKey();   /*从接收缓冲区中取出一个字符*/
				SEGGER_RTT_SetTerminal(0);
				SEGGER_RTT_printf(0, "GetKey = %c\r\n", GetKey);
		}
		/*********************************************接收RTT_Virwer发送字符*********************************************************/
		
		HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_RESET);
		osDelay(500);
		HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET);
		osDelay(500);
		printf(RTT_CTRL_TEXT_GREEN"StartDefaultTask:%f,%f,%f\r\n",234.153,564.1386,2.1350);  //重映射RTT打印浮点数
		
//		printf("StartTask02:%.1f,%.1f,%.1f\r\n",45.45,46.46,47.789);  //重映射串口打印浮点数
		
		/**********************************************测试自定义的日志打印函数*********************************************************/
		SEGGER_RTT_SetTerminal(0);
		user_main_printf("StartDefaultTask:%f",1.153);  	//打印在窗口0,颜色显示:白色
		user_main_info("StartDefaultTask:%f",2.153);  		//打印在窗口0,颜色显示:绿色
		user_main_debug("StartDefaultTask:%f",3.153);  		//打印在窗口0,颜色显示:白色
		user_main_warning("StartDefaultTask:%f",4.153);  	//打印在窗口0,颜色显示:黄色
		user_main_error("StartDefaultTask:%f",5.153);  		//打印在窗口0,颜色显示:红色
		/**********************************************测试自定义的日志打印函数*********************************************************/
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_StartTask02 */
/**
* @brief Function implementing the myTask02 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask02 */
void StartTask02(void *argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1000);
		
		/**********************************************测试自定义的日志打印函数*********************************************************/
		SEGGER_RTT_SetTerminal(1);  //打印在串口1
		user_main_printf("StartDefaultTask:%f",1.153);
		user_main_info("StartDefaultTask:%f",2.153);
		user_main_debug("StartDefaultTask:%f",3.153);
		user_main_warning("StartDefaultTask:%f",4.153);
		user_main_error("StartDefaultTask:%f",5.153);
		/**********************************************测试自定义的日志打印函数*********************************************************/
		
		printf(RTT_CTRL_TEXT_YELLOW"StartTask02:%d,%d,%d\r\n",45,46,47);  //打印黄色日志
//		printf("StartTask02:%d,%d\r\n",156,586641);  //重映射串口打印整数
  }
  /* USER CODE END StartTask02 */
}

/* Private application code --------------------------------------------------*/

/********************************************重映射函数*********************************************************/
/* USER CODE BEGIN Application */
//int __io_putchar(int ch)
//{
//  HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
//  return ch;
//}

//int fputc(int ch, FILE *f){
//	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
//	return ch;
//}

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
//	HAL_UART_Transmit(&huart1, (uint8_t*) &ch, 1, 0xffff);  //重映射串口1
//	return ch;
		SEGGER_RTT_PutChar(0, ch);  //重映射RTT
		return ch;
}
/********************************************重映射函数*********************************************************/
/* USER CODE END Application */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值