STM32標準庫移植RT-Thread Nano
嗶哩嗶哩教程鏈接:STM32F1標準庫移植RT_Thread Nano
移植前的準備
- stm32標準庫的裸機代碼(最好帶有點燈和串口)
- RT-Thread Nano Pack
- 自己的開發板
移植前的說明
本人是在讀學生,正在學習階段,移植過程中,會有疏漏與不足,請有緣看到的讀者指出,且敬請諒解,我會積極更改錯誤之處
移植步驟
一、打開RT-Thread文檔中心作為參考: RT-Thread文檔中心
二、keil上安裝RT-Thread Nano Pack
1.用Keil IDE內安裝RT-Thread Nano Pack(在線安裝)
(1)打開Keil,選擇Pack Installer ,關閉提示窗口
(2)打開pack,選擇安裝(我這里已經安裝所以顯示Remove)
2.用離線安裝包安裝RT-Thread Nano Pack(離線安裝)
(1)下載離線包:RT-Thread Nano Pack 離線安裝包
(2)離線安裝(雙擊下載好的安裝包,進行安裝)
表示安裝完成
三、添加內核源碼
通過以上三個步驟,完成勾選以后,點擊OK,就可以完成內核的添加,在keil目錄結構中,就能夠看到如下所示的內容,表示內核添加成功
四、刪除與邏輯沖突的中斷相關的函數
1.打開stm32f10x_it.c 找到相關的中斷的函數
2.對與邏輯沖突的中斷的函數,進行注釋或刪除
3.添加systick的中斷函數到board.c中
void SysTick_Handler()
{rt_interrupt_enter();rt_tick_increase();rt_interrupt_leave();
}
五、刪除RT-Thread中的部分代碼,添加系統的時鐘配置
1.注釋或刪除以下一行代碼:
#error "TODO 1: OS Tick Configuration."
2.添加時鐘配置
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
3.board.c中添加需要的頭文件
#include "stm32f10x.h"
#include "gpio.h"
#include "usart.h"
#include "delay.h"
通過以上步驟,就完成了在STM32標準庫上進行RT-Thread Nano版本的移植,編譯一下,0警告0錯誤
六、創建任務進行驗證
1.在工程的user文件夾下,新建RT-Thread相關的頭文件和源文件,并添加到工程中
2.編寫user下的RT-Thread的源文件(我的是RT_Thread_demo.c)
(1)包含頭文件
#include "stm32f10x.h"
#include "RT_Thread_demo.h"
#include <rtthread.h>
#include "delay.h"
#include "gpio.h"
#include "usart.h"
(2)編寫需要用到的宏定義
#define TASK1_PRIO 1 /* 任務優先級 */
#define TASK1_STK_SIZE 128 /* 任務堆棧大小 */
static rt_thread_t Task1_Handler = RT_NULL; /* 任務句柄 */
void Task1(void *pvParameters); /* 任務函數 */#define TASK2_PRIO 2 /* 任務優先級 */
#define TASK2_STK_SIZE 128 /* 任務堆棧大小 */
static rt_thread_t Task2_Handler = RT_NULL; /* 任務句柄 */
void Task2(void *pvParameters); /* 任務函數 */#define TASK3_PRIO 3 /* 任務優先級 */
#define TASK3_STK_SIZE 128 /* 任務堆棧大小 */
static rt_thread_t Task3_Handler = RT_NULL; /* 任務句柄 */
void Task3(void *pvParameters); /* 任務函數 */
(3) 通過函數創建任務,并在main.c中調用
void RT_Thread_demo(void)
{Task1_Handler = rt_thread_create("Task1_Handler",Task1,RT_NULL,TASK1_STK_SIZE,TASK1_PRIO,20);rt_thread_startup(Task1_Handler);Task2_Handler = rt_thread_create("Task2_Handler",Task2,RT_NULL,TASK2_STK_SIZE,TASK2_PRIO,20);rt_thread_startup(Task2_Handler);Task3_Handler = rt_thread_create("Task3_Handler",Task3,RT_NULL,TASK3_STK_SIZE,TASK3_PRIO,20);rt_thread_startup(Task3_Handler);
}
(4) 編寫任務函數
void Task1(void *parameter)
{while(1){LED1_Toggle;//printf("Task1\r\n");USART_SendString(USART1,(unsigned char*)"Task1\r\n");rt_thread_mdelay(300);}rt_thread_delay(10);
}void Task2(void *parameter)
{while(1){LED2_Toggle;//printf("Task2\r\n");USART_SendString(USART1,(unsigned char*)"Task2\r\n");rt_thread_mdelay(600); }rt_thread_delay(10);
}void Task3(void *parameter)
{while(1){LED3_Toggle;//printf("Task3\r\n");USART_SendString(USART1,(unsigned char*)"Task3\r\n");rt_thread_mdelay(900); }rt_thread_delay(10);
}
(5) 模塊初始化
把用到的初始化函數都放在board.c的rt_hw_board_init 中
通過以上步驟,已經完成對RT_Thread的移植。接下來調試驗證
七、移植rt_kprintf函數
1. 在rtconfig.h中修改部分代碼
(1)定義 RT_USING_CONSOLE
(2)刪除或注釋 uart_init 中的部分代碼并加入usart的初始化函數(board.c中)
(3)刪除rt_hw_console_output部分代碼并修改
函數修改為:
void rt_hw_console_output(const char *str)
{rt_enter_critical();while(*str != '\0') {if(*str == '\n'){USART_SendData(RT_kprintf_USARTx,'\r');while(USART_GetFlagStatus(RT_kprintf_USARTx, USART_FLAG_TXE) == RESET); //等待上一個字節發送完成}USART_SendData(RT_kprintf_USARTx, *str++); //發送一個字節while(USART_GetFlagStatus(RT_kprintf_USARTx, USART_FLAG_TXE) == RESET); //等待上一個字節發送完成}rt_exit_critical();
}
八、finsh組件的移植
1. 添加組件源碼
keil的目錄結構中,會出現如下文件
2. rtconfig.h 中打開 finsh 選項
3. 修改 finsh_port.c 文件
#include <rthw.h>
#include <rtconfig.h>
#include "stm32f10x.h"
#include "usart.h"#ifndef RT_USING_FINSH
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h
#endif#ifdef RT_USING_FINSHRT_WEAK char rt_hw_console_getchar(void)
{int ch = -1;//查詢方式實現,記得將Usart1初始化中的中斷接收配置相關代碼注釋掉/*等待串口1輸入數據*/if( USART_GetFlagStatus( RT_kprintf_USARTx, USART_FLAG_RXNE ) != RESET ){ch = ( int )USART_ReceiveData( RT_kprintf_USARTx );USART_ClearFlag( RT_kprintf_USARTx, USART_FLAG_RXNE );}else{if( USART_GetFlagStatus( RT_kprintf_USARTx, USART_FLAG_ORE ) != RESET ){USART_ClearFlag( RT_kprintf_USARTx, USART_FLAG_ORE );}rt_thread_mdelay( 10 );}return ch;
}#endif /* RT_USING_FINSH */
4. 修改串口的初始化函數
void uart1_init(uint32_t bound)
{GPIO_InitTypeDef GPIO_InitStructure; //GPIOUSART_InitTypeDef USART_InitStructure; //USARTNVIC_InitTypeDef NVIC_InitStructure; //NVICRCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1_TXGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1_RXGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入GPIO_Init(GPIOA, &GPIO_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優先級3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子優先級3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure);USART_OverSampling8Cmd(USART1,ENABLE);USART_InitStructure.USART_BaudRate = bound;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_Cmd(USART1, ENABLE); //使能串口1
}
通過以上步驟,對RT-Thread Nano版本的移植到此結束,希望大家相互學習,相互鼓勵!!!!
九、keil調試驗證
詳細調試步驟,請移步至嗶哩嗶哩視頻教程:STM32F1標準庫移植RT_Thread Nano
九、燒錄到開發板驗證
詳細步驟,請移步至嗶哩嗶哩視頻教程:STM32F1標準庫移植RT_Thread Nano