一直都是使用大神们提供的BSP包,各种设备组件齐全,十分方便;
但是这些BSP包和STM32CubeMX结合的不是很好,如果BSP包内没有我们需要的芯片,那就得自己动手移植了;
此篇文档适用于,只想要精简的nano内核,但又不想放弃finsh以及STM32CubeMX,这些实用工具的小伙伴,已经实际在板测试ok,可以直接使用;
软件资源:
STM32CubeMX V5.6.1
MDK V5.29.0.0
nano V3.1.3
XCOM V2.0
硬件资源:
ALIENTEK MiniSTM32开发板
(MCU STM32F103RCT6)
控制台使用串口:UART1
开始移植
1. 在STM32CubeMX加载nano内核和shell;
详细步骤请参考官方文档:https://www.rt-thread.org/document/site/tutorial/nano/finsh-port/an0045-finsh-port/
官方文档已经写得很详细了,此处不再过多描述;
2. 配置UART1串口参数,并打开UART1串口中断(STM32CubeMX中完成)
其他参数都设置完毕后,点击生成代码,然后打开工程文件;
3. 参考官方关于移植finsh,中断示例,进行移植(在MDK中完成)
3.1 将官方文档提供的各种定义复制,并添加到“main.c”文件头部,请特别注意添加的位置。
必须放置在/ USER CODE BEGIN ××××× / 与 / USER CODE END ××××× / 中间,
否则下次在STM32CubeMX中改变设置,生成代码时,你的代码都会被清除掉;
```/ Includes —————————————————————————————————/
/ Private includes —————————————————————————————/
/ USER CODE BEGIN Includes /
/ USER CODE END Includes /
/ Private typedef —————————————————————————————-/
/ USER CODE BEGIN PTD /
struct rt_ringbuffer
{
rt_uint8_t *buffer_ptr;
};
enum rt_ringbuffer_state
{
RT_RINGBUFFER_EMPTY,
RT_RINGBUFFER_FULL,
/ half full is neither full nor empty /
RT_RINGBUFFER_HALFFULL,
};
/ USER CODE END PTD /
/ Private define ——————————————————————————————/
/ USER CODE BEGIN PD /
/ USER CODE END PD /
/ Private macro ——————————————————————————————-/
/ USER CODE BEGIN PM /
/ USER CODE END PM /
/ Private variables ————————————————————————————-/
UART_HandleTypeDef huart1;
/ USER CODE BEGIN PV /
/ 第二部分:finsh 移植对接部分 /
rt_uint8_t uart_rx_buf[UART_RX_BUF_LEN] = {0};
struct rt_ringbuffer uart_rxcb; / 定义丿丿 ringbuffer cb /
//static UART_HandleTypeDef UartHandle;
struct rt_semaphore shell_rx_sem; / 定义丿个静态信号量 /
/ USER CODE END PV /```
3.2 复制函数**(ctrl+c and **ctrl+v)
复制如下所有函数及内容到“main.c”文件中(注意:此工程中我们使用的是huart1)这些函数是干什么用的,请自行参看官方文档,官方文档的注释已经写得很详细了;
3.3 与**STM32CubeMX高度融合(注意:*和**官方文档不一样的地方出现了*) 官方文档中还有三个函数,我们尚未移植:
static int uart_init(void) void HAL_UART_MspInit(UART_HandleTypeDef *huart) void USART2_IRQHandler(void)
由于我们使用STM32CubeMX自动生成了工程和代码(很是方便),所以上面三个函数STM32CubeMX其实已经帮我们写好了,我们只需要在工程中找到这些函数,加上我们需要的代码就可以了,和芯片寄存器操作的活就全部交给STM32CubeMX;
3.3.1 STM32CubeMX生成的工程中,串口初始化在“main.c”文件中,名字“void MX_USART1_UART_Init(void)”;我们迅速定位到这个函数,将官方文档中“static int uart_init(void)”部分代码复制过来,见下方蓝色部分;只修改/ USER CODE BEGIN ××××× / 与 / USER CODE END ××××× / 中间**部分,其他不要动,其他部分是STM32CubeMX自动生成的;
```static void MX_USART1_UART_Init(void)
{
/ USER CODE BEGIN USART1_Init 0 /
/ USER CODE END USART1_Init 0 /
/ USER CODE BEGIN USART1_Init 1 /
/ 初始化串口接政 ringbuffer / / USER CODE END USART1_Init 1 /
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/ USER CODE BEGIN USART1_Init 2 /
/ USER CODE END USART1_Init 2 /
}```
3.3.2 STM32CubeMX生成的工程中,串口IO口初始化在“void MX_USART1_UART_Init(void)”已经由STM32CubeMX自动生成,这里不再详述,感兴趣自己找找看看,STM32CubeMX是怎么帮我们初始化的;
字数限制,下页接着发
3.3.3 STM32CubeMX生成的工程中,串口中断在“stm32f1xx_it.c”文件中,名字“void USART1_IRQHandler(void)”;
我们迅速定位到这个函数,将官方文档中“void USART2_IRQHandler(void)”部分代码复制过来,见下方蓝色部分;
只修改蓝色代码部分,其他不要动,其他部分是STM32CubeMX自动生成的;
[attach]15840[/attach]
[attach]15841[/attach]
至此所有关键代码都已经移植完毕,最后点击“build”,编译整个工程文件;
应该会报一个故障,因为void USART1_IRQHandler(void) 函数使用了很多外部文件使用的变量,
需要在“stm32f1xx_it.c”文件头部进行声明;
/ USER CODE BEGIN PV /
extern rt_uint8_t uart_rx_buf[UART_RX_BUF_LEN];
extern struct rt_ringbuffer uart_rxcb; / 定义丿丿 ringbuffer cb /
extern struct rt_semaphore shell_rx_sem; / 定义丿个静态信号量 /
/ USER CODE END PV /
所有移植工作结束,点击“build”,编译整个工程文件,其他故障请自行解决;
[attach]15842[/attach]