STM32CubeMX移植RT-Thread nano 3.1.3 & 添加控制台与 FinSH
使用 串口1,配置为中断方式,不用DMA

效果
选 shell组件
程序代码
main.h
1 /* Define to prevent recursive inclusion -------------------------------------*/ 2 #ifndef __MAIN_H 3 #define __MAIN_H 4 5 #ifdef __cplusplus 6 extern "C" { 7 #endif 8 9 /* Includes ------------------------------------------------------------------*/ 10 #include "stm32g0xx_hal.h" 11 12 /* Private includes ----------------------------------------------------------*/ 13 /* USER CODE BEGIN Includes */ 14 15 /* USER CODE END Includes */ 16 17 /* Exported types ------------------------------------------------------------*/ 18 /* USER CODE BEGIN ET */ 19 20 /* USER CODE END ET */ 21 22 /* Exported constants --------------------------------------------------------*/ 23 /* USER CODE BEGIN EC */ 24 void SystemClock_Config(void); 25 /* USER CODE END EC */ 26 27 /* Exported macro ------------------------------------------------------------*/ 28 /* USER CODE BEGIN EM */ 29 30 /* USER CODE END EM */ 31 32 /* Exported functions prototypes ---------------------------------------------*/ 33 void Error_Handler(void); 34 35 /* USER CODE BEGIN EFP */ 36 37 /* USER CODE END EFP */ 38 39 /* Private defines -----------------------------------------------------------*/ 40 /* USER CODE BEGIN Private defines */ 41 42 /* USER CODE END Private defines */ 43 44 #ifdef __cplusplus 45 } 46 #endif 47 48 #endif /* __MAIN_H */
main.c
1 /* USER CODE BEGIN Header */ 2 /** 3 ****************************************************************************** 4 * @file : main.c 5 * @brief : Main program body 6 ****************************************************************************** 7 * @attention 8 * 9 * Copyright (c) 2023 STMicroelectronics. 10 * All rights reserved. 11 * 12 * This software is licensed under terms that can be found in the LICENSE file 13 * in the root directory of this software component. 14 * If no LICENSE file comes with this software, it is provided AS-IS. 15 * 16 ****************************************************************************** 17 */ 18 /* USER CODE END Header */ 19 /* Includes ------------------------------------------------------------------*/ 20 #include "main.h" 21 #include "usart.h" 22 #include "gpio.h" 23 24 /* Private includes ----------------------------------------------------------*/ 25 /* USER CODE BEGIN Includes */ 26 27 /* USER CODE END Includes */ 28 29 /* Private typedef -----------------------------------------------------------*/ 30 /* USER CODE BEGIN PTD */ 31 32 /* USER CODE END PTD */ 33 34 /* Private define ------------------------------------------------------------*/ 35 /* USER CODE BEGIN PD */ 36 /* USER CODE END PD */ 37 38 /* Private macro -------------------------------------------------------------*/ 39 /* USER CODE BEGIN PM */ 40 41 /* USER CODE END PM */ 42 43 /* Private variables ---------------------------------------------------------*/ 44 45 /* USER CODE BEGIN PV */ 46 47 /* USER CODE END PV */ 48 49 /* Private function prototypes -----------------------------------------------*/ 50 void SystemClock_Config(void); 51 /* USER CODE BEGIN PFP */ 52 53 /* USER CODE END PFP */ 54 55 /* Private user code ---------------------------------------------------------*/ 56 /* USER CODE BEGIN 0 */ 57 58 /* USER CODE END 0 */ 59 60 /** 61 * @brief The application entry point. 62 * @retval int 63 */ 64 int main(void) 65 { 66 /* USER CODE BEGIN 1 */ 67 68 /* USER CODE END 1 */ 69 70 /* MCU Configuration--------------------------------------------------------*/ 71 72 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 73 // HAL_Init(); 74 75 /* USER CODE BEGIN Init */ 76 77 /* USER CODE END Init */ 78 79 /* Configure the system clock */ 80 // SystemClock_Config(); 81 82 /* USER CODE BEGIN SysInit */ 83 84 /* USER CODE END SysInit */ 85 86 /* Initialize all configured peripherals */ 87 // MX_GPIO_Init(); 88 // MX_USART1_UART_Init(); 89 /* USER CODE BEGIN 2 */ 90 91 /* USER CODE END 2 */ 92 93 /* Infinite loop */ 94 /* USER CODE BEGIN WHILE */ 95 while (1) 96 { 97 /* USER CODE END WHILE */ 98 99 /* USER CODE BEGIN 3 */ 100 rt_thread_mdelay(1000); 101 // rt_kprintf("Hello RT-Thread\n"); 102 } 103 /* USER CODE END 3 */ 104 } 105 106 /** 107 * @brief System Clock Configuration 108 * @retval None 109 */ 110 void SystemClock_Config(void) 111 { 112 RCC_OscInitTypeDef RCC_OscInitStruct = {0}; 113 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; 114 115 /** Configure the main internal regulator output voltage 116 */ 117 HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); 118 119 /** Initializes the RCC Oscillators according to the specified parameters 120 * in the RCC_OscInitTypeDef structure. 121 */ 122 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 123 RCC_OscInitStruct.HSEState = RCC_HSE_ON; 124 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 125 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 126 RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; 127 RCC_OscInitStruct.PLL.PLLN = 16; 128 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 129 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; 130 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 131 { 132 Error_Handler(); 133 } 134 135 /** Initializes the CPU, AHB and APB buses clocks 136 */ 137 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK 138 |RCC_CLOCKTYPE_PCLK1; 139 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 140 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 141 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; 142 143 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) 144 { 145 Error_Handler(); 146 } 147 } 148 149 /* USER CODE BEGIN 4 */ 150 151 /* USER CODE END 4 */ 152 153 /** 154 * @brief This function is executed in case of error occurrence. 155 * @retval None 156 */ 157 void Error_Handler(void) 158 { 159 /* USER CODE BEGIN Error_Handler_Debug */ 160 /* User can add his own implementation to report the HAL error return state */ 161 __disable_irq(); 162 while (1) 163 { 164 } 165 /* USER CODE END Error_Handler_Debug */ 166 } 167 168 #ifdef USE_FULL_ASSERT 169 /** 170 * @brief Reports the name of the source file and the source line number 171 * where the assert_param error has occurred. 172 * @param file: pointer to the source file name 173 * @param line: assert_param error line source number 174 * @retval None 175 */ 176 void assert_failed(uint8_t *file, uint32_t line) 177 { 178 /* USER CODE BEGIN 6 */ 179 /* User can add his own implementation to report the file name and line number, 180 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 181 /* USER CODE END 6 */ 182 } 183 #endif /* USE_FULL_ASSERT */
rtconfig.h
1 /* RT-Thread config file */ 2 3 #ifndef __RTTHREAD_CFG_H__ 4 #define __RTTHREAD_CFG_H__ 5 6 // <<< Use Configuration Wizard in Context Menu >>> 7 8 // <h>Basic Configuration 9 // <o>Maximal level of thread priority <8-256> 10 // <i>Default: 32 11 #define RT_THREAD_PRIORITY_MAX 32 12 // <o>OS tick per second 13 // <i>Default: 1000 (1ms) 14 #define RT_TICK_PER_SECOND 1000 15 // <o>Alignment size for CPU architecture data access 16 // <i>Default: 4 17 #define RT_ALIGN_SIZE 4 18 // <o>the max length of object name<2-16> 19 // <i>Default: 8 20 #define RT_NAME_MAX 8 21 // <c1>Using RT-Thread components initialization 22 // <i>Using RT-Thread components initialization 23 #define RT_USING_COMPONENTS_INIT 24 // </c> 25 26 #define RT_USING_USER_MAIN 27 28 // <o>the stack size of main thread<1-4086> 29 // <i>Default: 512 30 #define RT_MAIN_THREAD_STACK_SIZE 256 31 32 // </h> 33 34 // <h>Debug Configuration 35 // <c1>enable kernel debug configuration 36 // <i>Default: enable kernel debug configuration 37 //#define RT_DEBUG 38 // </c> 39 // <o>enable components initialization debug configuration<0-1> 40 // <i>Default: 0 41 #define RT_DEBUG_INIT 0 42 // <c1>thread stack over flow detect 43 // <i> Diable Thread stack over flow detect 44 //#define RT_USING_OVERFLOW_CHECK 45 // </c> 46 // </h> 47 48 // <h>Hook Configuration 49 // <c1>using hook 50 // <i>using hook 51 //#define RT_USING_HOOK 52 // </c> 53 // <c1>using idle hook 54 // <i>using idle hook 55 //#define RT_USING_IDLE_HOOK 56 // </c> 57 // </h> 58 59 // <e>Software timers Configuration 60 // <i> Enables user timers 61 #define RT_USING_TIMER_SOFT 0 62 #if RT_USING_TIMER_SOFT == 0 63 #undef RT_USING_TIMER_SOFT 64 #endif 65 // <o>The priority level of timer thread <0-31> 66 // <i>Default: 4 67 #define RT_TIMER_THREAD_PRIO 4 68 // <o>The stack size of timer thread <0-8192> 69 // <i>Default: 512 70 #define RT_TIMER_THREAD_STACK_SIZE 512 71 // </e> 72 73 // <h>IPC(Inter-process communication) Configuration 74 // <c1>Using Semaphore 75 // <i>Using Semaphore 76 #define RT_USING_SEMAPHORE 77 // </c> 78 // <c1>Using Mutex 79 // <i>Using Mutex 80 //#define RT_USING_MUTEX 81 // </c> 82 // <c1>Using Event 83 // <i>Using Event 84 //#define RT_USING_EVENT 85 // </c> 86 // <c1>Using MailBox 87 // <i>Using MailBox 88 #define RT_USING_MAILBOX 89 // </c> 90 // <c1>Using Message Queue 91 // <i>Using Message Queue 92 //#define RT_USING_MESSAGEQUEUE 93 // </c> 94 // </h> 95 96 // <h>Memory Management Configuration 97 // <c1>Memory Pool Management 98 // <i>Memory Pool Management 99 //#define RT_USING_MEMPOOL 100 // </c> 101 // <c1>Dynamic Heap Management(Algorithm: small memory ) 102 // <i>Dynamic Heap Management 103 #define RT_USING_HEAP 104 #define RT_USING_SMALL_MEM 105 // </c> 106 // <c1>using tiny size of memory 107 // <i>using tiny size of memory 108 //#define RT_USING_TINY_SIZE 109 // </c> 110 // </h> 111 112 // <h>Console Configuration 113 // <c1>Using console 114 // <i>Using console 115 #define RT_USING_CONSOLE 116 // </c> 117 // <o>the buffer size of console <1-1024> 118 // <i>the buffer size of console 119 // <i>Default: 128 (128Byte) 120 #define RT_CONSOLEBUF_SIZE 256 121 // </h> 122 123 // <h>FinSH Configuration 124 // <c1>include finsh config 125 // <i>Select this choice if you using FinSH 126 #include "finsh_config.h" 127 // </c> 128 // </h> 129 130 // <h>Device Configuration 131 // <c1>using device framework 132 // <i>using device framework 133 //#define RT_USING_DEVICE 134 // </c> 135 // </h> 136 137 // <<< end of configuration section >>> 138 139 #endif
board.c
1 #include <rthw.h> 2 #include <rtthread.h> 3 4 #include "main.h" // 使用cubemx产生的SystemClock_Config() 5 #include "usart.h"// 使用cubemx产生的MX_USART1_UART_Init() 6 #include "gpio.h" // 使用cubemx产生的MX_GPIO_Init() 7 #include "string.h"// 使用memset() 8 extern void SystemClock_Config(void); 9 10 #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP) 11 /* 12 * Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP 13 * the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes 14 */ 15 #define RT_HEAP_SIZE (15*1024) 16 static rt_uint8_t rt_heap[RT_HEAP_SIZE]; 17 18 RT_WEAK void *rt_heap_begin_get(void) 19 { 20 return rt_heap; 21 } 22 23 RT_WEAK void *rt_heap_end_get(void) 24 { 25 return rt_heap + RT_HEAP_SIZE; 26 } 27 #endif 28 29 void rt_os_tick_callback(void) 30 { 31 rt_interrupt_enter(); 32 33 rt_tick_increase(); 34 35 rt_interrupt_leave(); 36 } 37 /* cortex-m 架构使用 SysTick_Handler() */ 38 void SysTick_Handler() 39 { 40 rt_os_tick_callback(); 41 } 42 /** 43 * This function will initial your board. 44 */ 45 void rt_hw_board_init(void) 46 { 47 //#error "TODO 1: OS Tick Configuration." 48 /* 49 * TODO 1: OS Tick Configuration 50 * Enable the hardware timer and call the rt_os_tick_callback function 51 * periodically with the frequency RT_TICK_PER_SECOND. 52 */ 53 54 /* 1、系统、时钟初始化 */ 55 HAL_Init(); // 初始化 HAL 库 56 SystemClock_Config(); // 配置系统时钟 57 SystemCoreClockUpdate(); // 对系统时钟进行更新 58 59 60 /* 2、OS Tick 频率配置,RT_TICK_PER_SECOND = 1000 表示 1ms 触发一次中断 */ 61 SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); 62 63 /* Call components board initial (use INIT_BOARD_EXPORT()) */ 64 65 MX_GPIO_Init(); 66 #ifdef RT_USING_COMPONENTS_INIT 67 rt_components_board_init(); 68 #endif 69 70 #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP) 71 rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get()); 72 #endif 73 } 74 75 #ifdef RT_USING_CONSOLE 76 77 #define UartHandle huart1 78 static int uart_init(void) 79 { 80 //#error "TODO 2: Enable the hardware uart and config baudrate." 81 MX_USART1_UART_Init();// 串口初始化,中断方式接收字节,查询方式发送字节 82 83 __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_IDLE);// 开空闲中断 84 __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);// 开接收非空中断 85 return 0; 86 } 87 INIT_BOARD_EXPORT(uart_init); 88 89 /* 90 向串口打印字节,输出信息 91 */ 92 void rt_hw_console_output(const char *str) 93 { 94 //#error "TODO 3: Output the string 'str' through the uart." 95 rt_size_t i = 0, size = 0; 96 char a = '\r'; 97 98 __HAL_UNLOCK(&UartHandle); 99 100 size = rt_strlen(str); 101 for (i = 0; i < size; i++) 102 { 103 if (*(str + i) == '\n') 104 { 105 HAL_UART_Transmit(&UartHandle, (uint8_t *)&a, 1, 1); 106 } 107 HAL_UART_Transmit(&UartHandle, (uint8_t *)(str + i), 1, 1); 108 } 109 } 110 /* 111 串口接收数据用结构体 112 */ 113 #define CONSOLE_UART_RX_BUF_SIZE 128 114 static struct 115 { 116 uint8_t buf[CONSOLE_UART_RX_BUF_SIZE]; /* 帧接收缓冲 */ 117 struct 118 { 119 uint16_t len : 15; /* 帧接收长度,sta[14:0] */ 120 uint16_t finsh : 1; /* 帧接收完成标志,sta[15] */ 121 } sta; /* 帧状态信息 */ 122 } g_uart_rx_frame = {0}; /* UART接收帧缓冲信息结构体 */ 123 124 /* 125 重载rt_hw_console_getchar(),逐一字节,取得串口数据 126 */ 127 char rt_hw_console_getchar(void) 128 { 129 static int nbytes=CONSOLE_UART_RX_BUF_SIZE; 130 int ch = -1; 131 132 if(g_uart_rx_frame.sta.finsh !=1) 133 { 134 rt_thread_mdelay(10); 135 return ch; 136 } 137 138 if(g_uart_rx_frame.sta.len<nbytes) 139 { 140 nbytes =0; 141 g_uart_rx_frame.buf[g_uart_rx_frame.sta.len]='\r';/*读取缓冲区一个字节*/ 142 g_uart_rx_frame.sta.len++; 143 } 144 if((nbytes>=0 )&&(nbytes<g_uart_rx_frame.sta.len)) 145 { 146 ch = g_uart_rx_frame.buf[nbytes];/*读取缓冲区一个字节*/ 147 nbytes++; 148 return ch; 149 } 150 else 151 { 152 g_uart_rx_frame.sta.finsh=0; 153 g_uart_rx_frame.sta.len=0; 154 memset(g_uart_rx_frame.buf,0,CONSOLE_UART_RX_BUF_SIZE); 155 __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_IDLE);// 开空闲中断 156 __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);// 开接收非空中断 157 } 158 nbytes=CONSOLE_UART_RX_BUF_SIZE; 159 return ch; 160 } 161 162 /* 163 串口通信中断: 164 165 RXNE中断接收字节 166 空闲中断结束接收。 167 168 必须开中断: 169 __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_IDLE);// 开空闲中断 170 __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);// 开接收非空中断 171 */ 172 173 #define CONSOLE_UART_IRQHandler USART1_IRQHandler 174 void CONSOLE_UART_IRQHandler(void) 175 { 176 uint8_t tmp; 177 178 if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_ORE) != RESET) /* UART接收过载错误中断 */ 179 { 180 __HAL_UART_CLEAR_OREFLAG(&UartHandle); /* 清除接收过载错误中断标志 */ 181 (void)UartHandle.Instance->ISR;//SR; /* 先读SR寄存器,再读DR寄存器 */ 182 (void)UartHandle.Instance->RDR;//DR; 183 } 184 185 if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) /* UART接收中断 */ 186 { 187 HAL_UART_Receive(&UartHandle, &tmp, 1, HAL_MAX_DELAY); /* UART接收数据 */ 188 189 if (g_uart_rx_frame.sta.len < (CONSOLE_UART_RX_BUF_SIZE - 1)) /* 判断UART接收缓冲是否溢出 190 * 留出一位给结束符'\0' 191 */ 192 { 193 g_uart_rx_frame.buf[g_uart_rx_frame.sta.len] = tmp; /* 将接收到的数据写入缓冲 */ 194 g_uart_rx_frame.sta.len++; /* 更新接收到的数据长度 */ 195 } 196 else /* UART接收缓冲溢出 */ 197 { 198 g_uart_rx_frame.sta.len = 0; /* 覆盖之前收到的数据 */ 199 g_uart_rx_frame.buf[g_uart_rx_frame.sta.len] = tmp; /* 将接收到的数据写入缓冲 */ 200 g_uart_rx_frame.sta.len++; /* 更新接收到的数据长度 */ 201 } 202 } 203 204 if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_IDLE) != RESET) /* UART总线空闲中断 */ 205 { 206 g_uart_rx_frame.sta.finsh = 1; /* 标记帧接收完成 */ 207 __HAL_UART_CLEAR_IDLEFLAG(&UartHandle); /* 清除UART总线空闲中断 */ 208 __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_IDLE);// 开空闲中断 209 __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE); /* 关接收非空中断 */ 210 } 211 } 212 #endif
参考连接:
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-nano/finsh-port/an0045-finsh-port
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)