代码改变世界

rt_thread&finsh控制台移植STM32

2021-06-07 14:53  hdlBuf  阅读(682)  评论(0编辑  收藏  举报

      先说一下感受吧,第一次有想搞应用系统的想法,初步看了很多嵌入式系统,俗称RTOS,包括UC/OS/,freeRTOS,liteOS,rt_thread。虽然都不是很懂,但是有必要学习一下,最终还是选择了rt_thread,说是国产的,也说是学习比较容易的,硬件要求低的。反正一大推理由,我也不知道。选了就选吧。

      正题:

   A.  先来说一下我的硬件:STM32F103RCXX, 开发板随意,只要你有可以串口通信,还连接控制一颗灯即可)

                                 软件:WIN10, 这个应该不是很重要了吧。

  第一随文就节点是,我已经移植了,rt_thread_nano. 且已经基本可以点亮一颗灯,和串口。且还挂载了finsh组件。

      说一下步骤吧。

      1. cubeMX 生成起码项目,启动UART1和PA8.  这些看你们硬件。具体如下图操作如图:

     

     说说这个东西吧,其实建立工程有好多种方法,我发现这个是最简单的,但是需要cubeMX工具。如果你想从事STM32工作的,

      还得多学习用库建立的方法,那些我就不描述了。百度一下一大把。主要是HAL库建立工程。

  2. 建立好生成工程后打开如下几步骤,如下介绍。

     

 

  

  1 #include "main.h"
  2 #include <rtthread.h>
  3 
  4 
  5     #ifndef RT_USING_HEAP
  6         rt_err_t hdle1;
  7         static struct rt_thread led_thread ;
  8         static char led_stack[256] ;
  9     #else
 10         static rt_thread_t led_thread ;
 11     #endif
 12 
 13 UART_HandleTypeDef huart1;
 14 
 15 
 16 void led_entry(void *parameter)
 17 {
 18     while(1)
 19     {
 20         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);
 21         rt_thread_mdelay(500);
 22         
 23         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);
 24         rt_thread_mdelay(500);
 25     }
 26 }
 27 
 28 
 29 
 30 /* USER CODE END PV */
 31 
 32 void SystemClock_Config(void);
 33 static void MX_GPIO_Init(void);
 34 static void MX_USART1_UART_Init(void);
 35 
 36 int main(void)
 37 {
 38   HAL_Init();
 39 
 40   SystemClock_Config();
 41   MX_GPIO_Init();
 42   MX_USART1_UART_Init();
 43   while (1)
 44   {
 45         rt_thread_mdelay(100) ;
 46   }
 47 }
 48 void SystemClock_Config(void)
 49 {
 50   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 51   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 52 
 53   /** Initializes the RCC Oscillators according to the specified parameters
 54   * in the RCC_OscInitTypeDef structure.
 55   */
 56   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 57   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 58   RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
 59   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
 60   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 61   {
 62     Error_Handler();
 63   }
 64   /** Initializes the CPU, AHB and APB buses clocks
 65   */
 66   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 67                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 68   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
 69   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 70   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 71   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 72 
 73   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
 74   {
 75     Error_Handler();
 76   }
 77 }
 78 
 79 
 80 static void MX_USART1_UART_Init(void)
 81 {
 82 
 83   /* USER CODE BEGIN USART1_Init 0 */
 84 
 85   /* USER CODE END USART1_Init 0 */
 86 
 87   /* USER CODE BEGIN USART1_Init 1 */
 88 
 89   /* USER CODE END USART1_Init 1 */
 90   huart1.Instance = USART1;
 91   huart1.Init.BaudRate = 115200;
 92   huart1.Init.WordLength = UART_WORDLENGTH_8B;
 93   huart1.Init.StopBits = UART_STOPBITS_1;
 94   huart1.Init.Parity = UART_PARITY_NONE;
 95   huart1.Init.Mode = UART_MODE_TX_RX;
 96   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 97   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 98   if (HAL_UART_Init(&huart1) != HAL_OK)
 99   {
100     Error_Handler();
101   }
102   /* USER CODE BEGIN USART1_Init 2 */
103 
104   /* USER CODE END USART1_Init 2 */
105 
106 }
107 
108 
109 static void MX_GPIO_Init(void)
110 {
111   GPIO_InitTypeDef GPIO_InitStruct = {0};
112 
113   /* GPIO Ports Clock Enable */
114   __HAL_RCC_GPIOA_CLK_ENABLE();
115 
116   /*Configure GPIO pin Output Level */
117   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
118 
119   /*Configure GPIO pin : PA8 */
120   GPIO_InitStruct.Pin = GPIO_PIN_8;
121   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
122   GPIO_InitStruct.Pull = GPIO_NOPULL;
123   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
124   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
125 
126 }
127 
128 /* USER CODE BEGIN 4 */
129 
130 void rt_hw_console_output(const char *str)
131 {
132     rt_size_t i = 0, size = 0;
133     char a = '\r';
134 
135     __HAL_UNLOCK(&huart1);
136 
137     size = rt_strlen(str);
138     for (i = 0; i < size; i++)
139     {
140         if (*(str + i) == '\n')
141         {
142             HAL_UART_Transmit(&huart1, (uint8_t *)&a, 1, 1);
143         }
144         HAL_UART_Transmit(&huart1, (uint8_t *)(str + i), 1, 1);
145     }
146 }
147 char rt_hw_console_getchar(void)
148 {
149     int ch = -1;
150 
151     if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET)
152     {
153         ch = huart1.Instance->DR & 0xff;
154     }
155     else
156     {
157         if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_ORE) != RESET)
158         {
159             __HAL_UART_CLEAR_OREFLAG(&huart1);
160         }
161         rt_thread_mdelay(10);
162     }
163     return ch;
164 }
165 
166 void led_start(void)
167 {
168     #ifndef RT_USING_HEAP
169     hdle1 = rt_thread_init(&led_thread,
170                                                     "ledshine",
171                                                     led_entry,
172                                                     RT_NULL,
173                                                     &led_stack[0],
174                                                     sizeof(led_stack),
175                                                     RT_THREAD_PRIORITY_MAX-2,
176                                                     20);
177     if(hdle1 != RT_EOK)
178     {
179         rt_thread_startup(&led_thread) ;
180         
181     }
182     #else
183        if(led_thread == RT_NULL)
184          {
185             led_thread = rt_thread_create("ledshine",
186                                                                 led_entry,
187                                                                 RT_NULL,
188                                                                 128,
189                                                                 RT_THREAD_PRIORITY_MAX-2,
190                                                                 20);
191             if(led_thread != RT_NULL)
192             {
193                 rt_thread_startup(led_thread) ;
194             }
195         }
196     
197     #endif
198 
199 }
200 void led_exit(void)
201 {
202     if(led_thread != RT_NULL)  
203     {
204         #ifdef RT_USING_HEAP
205             rt_thread_delete(led_thread) ;// 
206             led_thread = RT_NULL ;
207         #endif
208     }
209 }
210 
211 INIT_BOARD_EXPORT(MX_USART1_UART_Init) ;
212 MSH_CMD_EXPORT(led_start,ledon) ;
213 MSH_CMD_EXPORT(led_exit,ledexit) ;
214 
215 /* USER CODE END 4 */
216 
217 void Error_Handler(void)
218 {
219   /* USER CODE BEGIN Error_Handler_Debug */
220   /* User can add his own implementation to report the HAL error return state */
221   __disable_irq();
222   while (1)
223   {
224   }
225   /* USER CODE END Error_Handler_Debug */
226 }
227 
228 #ifdef  USE_FULL_ASSERT
229 /**
230   * @brief  Reports the name of the source file and the source line number
231   *         where the assert_param error has occurred.
232   * @param  file: pointer to the source file name
233   * @param  line: assert_param error line source number
234   * @retval None
235   */
236 void assert_failed(uint8_t *file, uint32_t line)
237 {
238   /* USER CODE BEGIN 6 */
239   /* User can add his own implementation to report the file name and line number,
240      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
241   /* USER CODE END 6 */
242 }
243 #endif /* USE_FULL_ASSERT */
244 
245 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
main函数代码

 

   说明一下:

   a. 我这里分两种建立线程的方式: 使用RT_USING_HEAP.  动态和静态.使用宏#ifndef #else #endif, 这里只有动态才能删除线程。

   b. 增加了两条接收串口和发送数据的函数rt_hw_console_output/rt_hw_console_getchar .   

   c. 增加了两条命令:分别是启动led闪烁线程和关闭led闪烁线程

     MSH_CMD_EXPORT(led_start,ledon) ;

     MSH_CMD_EXPORT(led_exit,ledexit) ;

   d. 串口出事话必须要在启动mian前就初始化:

                  INIT_BOARD_EXPORT(MX_USART1_UART_Init) ; 

   调试:  使用过putty,mobaxterm.但是知道怎么设置,最终选用了xshell。 

    驱动后如下:

    

 

    可以通过help命令来看系统都有什么命令:

    以下我发几个命令给大家看,具体大家自行学习研究。(其实我目前就知道这几个)

 

 

    上图我是还没有驱动led线程,下方我启动线程前、后、关闭后的对比。如下图:

    

 

   总结一下:

         虽然是第一阶段的学习,但是也是从0-1的过程,往下就应该更加简单了,但是需要的时间也越来越多。学习无止境。

         有任何不解和建议QQ:2382213313.