文章目錄
- 一、新建工程
- 1.1 創建基于芯片的工程
- 1.1.1 選擇創建的rtt版本
- 1.1.2 配置工程基本屬性
- 1.1.3 初創工程目錄結構
- 1.1.4 修改時鐘配置
- 1.1.5 配置調試下載器
- 1.2 創建基于開發板的工程
- 二、配置內核
- 三、配置組件
- 四、配置軟件包
- 五、適配配置
- 六、其它問題
一、新建工程
1.1 創建基于芯片的工程
1.1.1 選擇創建的rtt版本
rt-thread有標準版和nano版兩種版本,標準版支持豐富的軟件包和各種組件,而nano版本僅支持msh shell功能,我們本次就創建標準版本的rtt工程,以便后面使用AT組件和mqtt軟件包,選擇rtt版本如圖所示:
也可以使用圖標來新建,如圖所示:
1.1.2 配置工程基本屬性
在上一步點擊“RT-Thread項目”后,就進入了工程基本屬性的配置界面,如圖所示:
圖中各項的作用描述如下表:
序號 | 名稱 | 描述 |
---|---|---|
① | 工程名 | 指定新建工程的名稱。如果不想讓此工程保存在默認的工作空間內,可以將此欄下面的使用缺省位置去勾選然后指定工程的保存路徑 |
② | 工程模板 | RT-Thread Studio支持兩種模板,一種是基于芯片,另一種是基于開發板,基于芯片目前只有ST公司的處理器支持的很好;基于開發板則有很多廠家提供他們的rtt bsp sdk |
③ | RT-Thread內核版本 | 更新了RT-Thread Studio之后,選擇最新版本即可 |
④ | 廠商 | RT-Thread Studio支持的芯片廠商,目前ST處理器支持的最好 |
⑤ | 芯片系列 | ST處理器有F1/F3/F4/F7/H7系列的MCU,根據實際情況選擇 |
⑥ | 芯片子系列 | 當選擇號了芯片系列之后,芯片子系列就會列出該系列芯片的子系列,比如STM32F103系列 |
⑦ | 芯片型號 | 根據芯片系列和芯片子系列就圈定了芯片型號的范圍,我們在此范圍內找到我們要開發的目標芯片,比如STM32F103ZE |
⑧ | 控制臺串口 | 就是msh shell功能使用的串口,這里指向我們板卡上用于輸出調試信息的或者其它信息的串口,百問網的調試串口使用的是USART1,引腳是PA9和PA10 |
⑨ | 調試器 | 調試芯片的工具,通常由j-link/st-link/daplink等,根據自己手里面的工具來選擇 |
⑩ | 調試接口 | 有JTAG接口和SWD接口,根據板卡的實際設計來選擇 |
根據這些信息和我們板卡的實際情況,我們的配置如下圖所示:
然后點擊完成,等待工程初創成功:
1.1.3 初創工程目錄結構
工程初創成功后,得到如下圖的工程,其目錄結構如圖所示:
每項對應的功能描述如下表:
序號 | 名稱 | 描述 |
---|---|---|
1 | RT-Thread Settings | RTT Studio內置配置工具,可以配置內核、組件、軟件包,并將配置保存生成到工程中 |
2 | CubeMX Settings | RTT Stduio內置STM32CubeMX工具,用以配置ST處理器的外設 |
3 | Includes | 其中展示了此工程包含使用的所有頭文件 |
4 | applications | 其中包含了用戶開發的應用層的源文件,默認包含了main.c,里面實現了main函數 |
5 | drivers | 里面包含了基于該芯片的外設驅動源文件和頭文件,不一定所有的外設都支持,還有待持續維護開發。對于不支持的外設還是要用戶自己去實現驅動函數 |
6 | libraries | 基于該芯片的庫文件,一般是由廠商提供,RTT Studio將其整理打包放到了工程目錄結構中。在ST芯片的工程中有CMSIS和STM32XXX_HAL_Driver,前者是存放CMSIS標準的頭文件和庫文件,后者是放STM32處理器的HAL庫文件 |
7 | linkscripts | 存放該芯片編譯時的鏈接文件 |
8 | rt-thread | rtt的內核文件和組件、軟件包源文件,使用RT-Thread Settings配置的內核、組件和軟件包對應的源代碼會在這一級中生效 |
9 | rtconfig.h | rtt的配置文件,用以表明會用到哪些內核機制、組件和軟件包,使用RT-Thread Settings配置后會覆蓋之前的改動,所以不建議在rtt studio中手動修改此文件 |
1.1.4 修改時鐘配置
在前面初創工程的時候有提示說:默認的時鐘使用的是HSI
來配置系統時鐘,如果要使用別的時鐘源來配置系統時鐘就要去修改drv_clk.c
,我們的開發板有使用精度更高的HSE
,所以我們先去修改時鐘配置。
重點要關注的是這幾行代碼:
// 原本的代碼使用的HSI
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
...
...
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;// 修改成HSI
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
...
...
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
如果不會自己配置系統時鐘,就可以打開Studio中內置的CubeMX Settings去配置,然后生成工程。如何配置STM32CubeMX并且生成工程就不再多說了,我們說一說生成工程之后的事兒。
先來記錄下生成工程前,我們的工程結構,特別是drivers下的文件,如圖所示:
使用CubeMX配置完生成工程之后:
可以看到多出了cubemx文件夾,而且drivers下的stm32f1xx_hal_conf.h被備份成了stm32f1xx_hal_conf_bak.h,為了保證工程在studio中能夠編譯成功,我們需要做以下幾件事:
-
將我們需要參考的配置源碼復制到rtt studio工程中,比如我們現在想要做的事情就是利用cubemx配置系統時鐘,然后我們這段代碼復制到drv_clk.c中,如圖所示:
我們可以將cubemx目錄下main.c
中配置系統時鐘函數中的所有內容復制到rtt工程的drv_clk.c
里面去,完成對時鐘的配置。其它的外設配置,特別是rtt的drivers中沒有支持的外設的驅動,我們就可以利用這個方法來快速完成初始化。 -
將我們需要的代碼添加到rtt studio工程之后,為了能夠編譯通過,我們需要將cubemx settings生成的文件夾cubemx中的一些文件或者全部文件排除構建,比如main.c,一個工程不可能存在兩個同名的.c源文件,還有新生的
stm32f1xx_hal_conf.h
,它是有可能缺省原本的rtt studio中使用的外設的,所以我們需要將其排除構建,為了方便,我建議是將cubemx整個目錄都排除構建。如圖所示:
對著cubemx目錄右鍵,然后再資源配置那里選擇排除構建。將某項排除構建后,該項就會從當前的工程目錄被移除,但是還是存在工程文件夾中的,沒有被刪除掉。如果想要回復,可以去菜單欄打開“導航”,選擇“打開資源”,如圖所示:
然后點擊左下角的“顯示位置”,選擇“C/C++項目”:
這樣,在“項目資源管理器”的邊上就有一個“C/C++項目”,如圖所示:
可以看到外面之前選擇排除構建的cubemx就出現了,圖標上有個/,表示該項不會被構建,要恢復就鼠標右鍵此項,將此項選擇加入構建,如圖所示:
- 恢復hal配置頭文件
在使用cubemx配置生成代碼后,drivers下的stm32f1xx_hal_conf.h
變成了stm32f1xx_hal_conf_bak.h
,在cubemx目錄下新生了一個stm32f1xx_hal_conf.h
文件,我們現在已經將cubemx目錄排除構建了,現在需要將被備份的hal庫配置文件還原,即重命名回來即可:
經過上面的配置,構建工程,查看是否有配置錯誤。構建成功,那么一個工程就新建好了,可以開始后面對具體外設、內核、組件和軟件包的配置了。
1.1.5 配置調試下載器
在調試或者下載程序之前,需要先去配置調試下載器,如圖所示:
點擊圖中紅圈中的下拉圖標進行配置,根據自己實際情況選擇即可。
1.2 創建基于開發板的工程
基于開發板的和基于芯片的思路是一樣的,只是基于開發板的會有更多廠商的芯片可以選擇,不過他們對于驅動的支持可能沒有ST那樣好,很多驅動需要自己去完成。
二、配置內核
雙擊RT-Thread Settings進入配置界面:
點擊紅圈中的左拉箭頭,進入細節配置:
在這里可以配置內核的參數,比如Tick頻率、堆棧、線程通信、內存管理等等,按需配置,和FreeRTOS中修改FreeRTOSConfig.h類似的功能。
三、配置組件
還是使用RT-Thread Settings,打開后可以看到圖形界面和細節配置,組件的配置既可以通過圖形界面選擇點擊使用,也可以在細節配置中使能配置參數:
可以在這些組件中右鍵查看配置項,必須要先使能才能進入配置項:
這些同樣是根據自己的內存、外設、中間組件選用等的實際需求來選擇配置。
四、配置軟件包
軟件包可以在RT-Thread Settings的圖形界面選擇“添加軟件包”進入軟件包搜索添加界面:
這里可以搜索軟件包也可以按分類查找軟件包,比如我想要SPI OLED的軟件包,但是我不知道有哪些軟件包且屬于哪一類,那我就搜索OLED,如圖所示:
這里顯示有3種,剛好我們使用的是SSD1306,我們就點進去看一下:
它說現在僅支持I2C,但是我們想要的是SPI接口的,不滿足,所以就不添加軟件包到工程,但是這個軟件包依然有參考意義,看一下別人是如何實現RTT下的SSD1306驅動的,可以嘗試移植,這時候我們就可以點擊邊上的“github”把源碼clone下來參考。
我們同樣也可以去細節配置里面的軟件包去配置:
我們以paho mqtt為例,先使能這個軟件包,然后去配置細節,比如模式、堆棧、是否使用示例等。
需要注意的是,使用軟件包還需要關心它的依賴項:
點擊“依賴項”它就會告訴我們它依賴的組件和應用層有哪些。
設置好RT-Thread Settings之后,按CTRL+S保存,就會將改動添加生效到工程中,在工程的packages和rt-thread下的components中可以看到文件變化:
在rtconfig.h中看到具體的參數配置變化。
五、適配配置
這里我們先對前面的mqtt進行適配,使能完 AT 客戶端和 MQTT 示例后編譯出錯:
說明在工程中我們未定義BSP_USING_I2Cx
,一般BSP開頭的為板級支持包,一般在 drivers/borad.h
中定義,所以我們需要到該文件下找到I2C相關定義進行配置:
其中有兩個I2C接口,我們只需要使能其中一個,同時去找到板子相應I2C引腳,去修改引腳項即可:
再次編譯,報錯消失:
接下里是另一個適配配置:最后清空項目,然后重新構建,查看是否能變成通過,一般一開始都會有問題,需要查漏補缺一點一點的調整好。比如我在組件中使用了pwm,編譯后提示了一堆找不到定時器相關的宏定義,且drv_pwm.c還有個紅叉,如圖所示:
類似這樣的問題,先去hal_conf.h中看一下我們是否使能了芯片的定時器外設:
可以看到我們這里是沒有放開的,將注釋去掉之后重新編譯,還是出錯:
這種看提示看不出來什么,我們就去源文件看看具體情況:
可以看到是這個枚舉類型因為沒有前置宏定義變成了一個空枚舉
,所以編譯出錯。而這些BSP_USING_XXX
預處理條件,有些是無法在RT-Thread Settings
里面設置的,需要手動進行宏定義,我們前面說過,最好不要手動去修改rtconfig.h
,所以我們將這些BSP_USING_XXX
宏定義放到board.h
里面宏定義,這樣就避開了rtconfig.h
被RT-Thread Settings覆蓋修改,如圖所示:
可以看到在board.h里面由各個組件的配置項(沒有也沒關系),ST這里提供了示例,只有3路PWM,如果我們是其它的,就自己添加定義就好,比如PWM12(根據自己的設計選擇,這里只是舉例),如圖所示:
然后保存重新構建工程,還是提示有個錯誤:
說是沒有PWM12_CONFIG,我們去源文件看看:
我們一開始看到這個錯誤會一頭霧水,不知道下面該怎么辦了,這時候我們就可以參考官方給的例子,他不是給了三路PWM的宏定義示例嗎,我們放開一路,比如PWM1:
然后保存構建(因為沒有修改PWM12,所以肯定會報錯):
結果PWM1也是一樣的錯誤,這說明官方也沒有支持PWM1,如果挨個的碰運氣肯定不是好方法,其實我們可以去看看這個源文件用到了哪些頭文件,因為這些配置肯定是在某個頭文件中會定義或者聲明的:
這里面和PWM配置最相似看著最有關聯的應該就是drv_config.h
這個頭文件了,我們把鼠標放在頭文件名稱上,按鼠標左鍵跳過去:
在這里看到了有個pwm_config.h,我們同樣跳過去:
從這個文件中我們可以看到這些類似的PWMx_CONFIG配置,官方僅支持了PWM2/3/4/5,沒有我們要使用的PWM12,那么我們就仿照這些格式,寫我們自己的PWM12_CONFIG:
#ifdef BSP_USING_PWM12
#ifndef PWM12_CONFIG
#define PWM12_CONFIG \{ \.tim_handle.Instance = TIM2, \.name = "pwm12", \.channel = 12 \}
#endif /* PWM12_CONFIG */
#endif /* BSP_USING_PWM12 */
然后再保存構建工程(記得把PWM1還原):
我們雙擊這個錯誤跳過去看下:
這個意思就是說這個函數沒有定義,這個函數的作用是初始化TIM PWM通道的引腳的。根據HAL庫的開發經驗,這個需要用戶自定義,我們也可以使用cubemx配置參考下:
再次構建工程,就順利通過了:
這是因為配置完cubemx后,stm32f1xx_hal_msp.c
文件中定義了HAL_TIM_MspPostInit
函數,完成了對pwm的初始化:
將開發板連接stlink燒錄器并連接電腦,打開串口,點擊燒錄觀察現象:
此時我們會發現在串口工具中敲回車沒反應,是因為在main.c中將UART重新初始化了一次,所以我們需要注釋掉幾個初始化,但是我們會發現,每次使用cubemx配置后幾個初始化會被重新打開,所以相比與cubemx生成的main.c,RTT中的main.c更為好用,但是drivers_clk中的時鐘配置與main.c中的時鐘息息相關,所以我們干脆將cubemx生成的main.c的時鐘配置代碼復制粘貼到driver_clk中,并將main.c排除構建,將RTT中的main.c添加構建:
同時將原先cubemx生成main.c的時鐘配置函數在drivers_clk中的聲明刪除掉:
那么此時我們的燒錄就需要展開一些工作:關掉開發板電源,將啟動方式改成系統內部程序,即將紅色boot的開關的on的1撥向另一端,然后打開電源,打開STM32Programmer工具,將連接方式改成UART,選擇對應串口號(我這里是COM7),點擊連接:
接著需要擦除程序,并斷開連接,操作如下:
擦除并斷開后界面如下:
重新將連接方式換成stlink,點擊連接(在這里連接時,我發現一直連接不上stlink,我重新換了個stlink即可):
于是我們斷開連接,燒錄程序到開發板,同時打開串口觀察現象:
這里串口會打印是因為切換到RTT的main.c,同時按下回車串口會換行
六、其它問題
我們在使用RT-Thread Studio中的CubeMX使時,由于將cubemx里面的一些文件排除了構建,特別是stm32f1xx_hal_conf.h
,但是使用cubemx后關掉它的話,每次都會將原本在drivers
下的stm32f1xx_hal_conf.h
備份創建新的stm32f1xx_hal_conf.h
,且時鐘配置那里也會變成使用cubemx配置生成的SystemClock_Config
函數,所以如果要使用cubemx,最好的辦法是將rtt studio中的applications
里面的main.c
排除構建,而cubemx里面講main.c/stm32f1xx_hal_msp.c/Inc
文件夾添加構建,直接使用cubemx創建的代碼: