1. 簡介
WRTnode2R大的特征,便是雙核雙系統:MTK7688+STM32F103T8U6以及它們對應的操作系統OpenWrt+RT-Thread。
在OpenWrt之外引入了MCU:既有完善OpenWrt的可用資源,如:模擬采集、定時器的捕獲、PWM的輸入,以及更多的PWM輸出,更多的GPIO和其他輸出具備可靠的“硬”實時能力,在Linux中無法承載毫秒級的精確延時,而MCU則正好擅長此任務;由此嫁接OpenWrt所帶來的Linux廣泛的現有軟件資源和多媒體、人工智能應用的能力,同時STM32核心提供了更底層的開發能力和更加可靠的物理交互能力。
2. WRTnode 的stm32開發
在WRTnode2R核心板上,STM32和7688之間通過SPI總線連接,占用7688的CS1引腳。在WRTnode2R標準底板上,引出STM32的JTAG調試引腳、串口、I2C以及其他未使用的所有GPIO引腳。具體引腳布局圖,詳見WRTnode2R針腳定義和底板針腳定義
WRTnode2R的STM32上運行著RT-Thread實時操作系統,受益于RTT中友好的msh命令行調試組件,在出廠固件中實現了RTT的spi slave設備驅動,并且將msh的輸入輸出端口都映射到了spi總線上。同時提供了在7688上與STM32通過SPI總線通信的軟件(包括spiS0設備驅動、spi-bridge通信軟件和flash-stm32固件升級程序)。
體驗stm32上的msh: 登錄到WRTnode2R上。(登錄的方式有串口、telnet、ssh) 升級stm32固件
本文檔主要是針對新版本的stm32固件做的一些闡述,所以建議大家更新stm32固件。
$ wget //d.wrtnode.com/2R-stm32/flash-stm32 -O /usr/bin/flash-stm32$ flash-stm32
注:如果flash-stm32后面不跟參數,會自動下載并請求升級新的stm32固件;flash-stm32加上指定版本的固件(服務器上的或本地的版本),請求升級指定版的stm32固件。升級完以后stm32會自動重啟。
root@OpenWrt:~# flash-stm32 --help
---------------------------------------------------------------------------Usage: flash-stm32
Example #1: Updated to the latest version
flash-stm32
Example #2: Update to the specified version(server or local)
flash-stm32 //d.wrtnode.com/2R-stm32/$Stm32Firmware
or
flash-stm32 /tmp/$Stm32Firmware
---------------------------------------------------------------------------
root@OpenWrt:~# flash-stm32
Download the latest version form //d.wrtnode.com/2R-stm32/update
Connecting to d.wrtnode.com (66.33.205.160:80)
- 100% |********************************************************************************************| 5 0:00:00 ETA
Connecting to d.wrtnode.com (66.33.205.160:80)
WRTnode2r_STM32_rtth 100% |********************************************************************************************| 30404 0:00:00 ETA
The latest version is 0.7
No gets to the current STM32 version. Ple input "Y" to continue to upgrade or input "N" to cancel upgrade!
input Y or N:Y
write ...###############################################################################################write end!
check ...
###############################################################################################check end!
restart ...
restart end
root@OpenWrt:~#
輸入spi-bridge即可打開和stm32的msh命令行終端,先按下tab鍵再按下enter鍵列出msh支持的所有命令。
$ spi-bridge
若要執行某一條命令,輸入命令后按下enter即可執行。
exit退出msh。
如果要單命令方式執行,亦可以通過spi-bridge來實現,僅需要輸入spi-bridge write [cmd]即可。如果stm32正在執行之前的指令,導致寫緩存滿的話,此命令將阻塞,直至可以執行。
如果要讀取命令執行的結果,輸入spi-bridge read即可。如果stm32讀數據緩存為空,則命令會阻塞,直至有數據可讀。
[注]由于7688芯片上SPI總線的特殊性,現階段暫時未能給用戶提供標準的SPI CS1的操作接口,所以用戶暫時只能通過spi-bridge進行通信。
$ spi-bridge write list_timer
$ spi-bridge read
Arduino函數的兼容:maple
WRTnode2R的STM32上已經移植好了Maple固件庫。Maple固件庫為使用stm32的用戶提供了兼容Arduino代碼的接口。用戶如果要移植Arduino上的代碼到WRTnode2R的stm32上,需要做一點簡單的移植工作即可。
[注]因為Arduino的應用工程均為C++代碼,但是WRTnode2R的stm32上運行的rtt是在c編譯器下編譯執行的,所以在移植工程時必然需要做一點移植工作。現有的工程中,已經將maple庫的所有接口增加了一層c語言的封裝,讓用戶可以在c代碼中直接調用,所以用戶可以選擇將Arduino的應用代碼用C語言重構,或者將應用代碼增加一層C語言的封裝,供RTT調用。
通過spi-bridge對STM32的IO口進行控制 當前版本已經為用戶提供了msh調用Maple的GPIO庫的命令,這里為大家提供了一個參考例程。 控制IO語句的使用十分簡單,與arduino相仿,目前可以使用的語句包括pinMode/digitalRead/digitalWrite/togglePin/analogRead/pmwWrite 本文主要演示pinMode、digitalWrite及pwmWrite的用法。 先看針腳的定義:
extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = {
PMAP_ROW(GPIOA, 0, TIMER2, 1, ADC1, 0), /* D0/PA0 */
PMAP_ROW(GPIOA, 1, TIMER2, 2, ADC1, 1), /* D1/PA1 */
PMAP_ROW(GPIOA, 8, TIMER1, 1, NULL, ADCx), /* D2/PA8 */
PMAP_ROW(GPIOB, 2, NULL, 0, NULL, ADCx), /* D3/PB2 */
PMAP_ROW(GPIOA, 3, TIMER2, 4, ADC1, 3), /* D4/PA3 */
PMAP_ROW(GPIOB, 0, TIMER3, 3, ADC1, 8), /* D5/PB0 */
PMAP_ROW(GPIOA, 11, TIMER1, 4, NULL, ADCx), /* D6/PA11 */
PMAP_ROW(GPIOA, 12, NULL, 0, NULL, ADCx), /* D7/PA12 */
PMAP_ROW(GPIOB, 5, NULL, 0, NULL, ADCx), /* D8/PB5 */
PMAP_ROW(GPIOA, 10, TIMER1, 3, NULL, ADCx), /* D9/PA10 */
PMAP_ROW(GPIOA, 9, TIMER1, 2, NULL, ADCx), /* D10/PA9 */
PMAP_ROW(GPIOB, 6, TIMER4, 1, NULL, ADCx), /* D11/PB6 */
PMAP_ROW(GPIOB, 7, TIMER4, 2, NULL, ADCx), /* D12/PB7 */
PMAP_ROW(GPIOB, 1, TIMER3, 4, ADC1, 9), /* D13/PB1 */
PMAP_ROW(GPIOA, 2, TIMER2, 3, ADC1, 2), /* D14/PA2 */
PMAP_ROW(GPIOA, 4, NULL, 0, NULL, ADCx), /* D15/PA4 */
PMAP_ROW(GPIOA, 5, NULL, 0, NULL, ADCx), /* D16/PA5 */
PMAP_ROW(GPIOA, 6, NULL, 0, NULL, ADCx), /* D17/PA6 */
PMAP_ROW(GPIOA, 7, NULL, 0, NULL, ADCx), /* D18/PA7 */
};
注釋/* D0/PA0 / / D5/PB0 */等,Dxx就代表的xx引腳,Pxx就是對應芯片的引腳(也就是對應WRTnode2R標準底板絲印上的引腳);比如,下面我操作的是3引腳(D3),對應底板上的PB2。 其中支持PWM的PIN為0, 1, 2, 4, 5, 6, 9, 10, 11, 12, 13, 14 支持ADC的PIN為0, 1, 4, 5, 13, 14 其中D15-D18引腳已經被spi占用 完整的定義在github上可以找到: https://github.com/WRTnode/wrtnode2r_stm32/blob/master/maple/wirish/boards/wrtnode2/board.cpp#L67
root@OpenWrt:~# spi-bridge
RT-Thread shell commands:reset - reset to bootloader.2r_version - get wrtnode2r stm32 version.
pwmWrite - pwmWrite pinNum duty_cycle.
analogRead - analogRead pinNum.
togglePin - togglePin pinNum.
digitalWrite -digitalWrite pinNum 0x1/0x0.
digitalRead - digitalRead pinNum.
pinMode - pinMode pinNum mode.
list_device - list device in system
list_timer - list timer in system
list_mempool - list memory pool in system
list_mutex - lst mutex in system
list_event - list event in system
list_sem - list semaphore in system
list_thread - list threadversion - show RT-Thread version informationhelp - RT-Thread shell help.
free - Show th memory usage in the system.time - Execute command with time.
ps - List threads in the system.
msh >
msh > pinMode 3 OUTPUT //pinMode第一個參數指引腳3;第二個參數設置引腳3狀態為OUTPUT ;pinMode沒有返回值,命令執行之后直接按下enter鍵即可
msh > digitalWrite 3 HIGH //digitalWrit第一個參數指引腳3;第二個參數設置引腳3的電平為高
msh > digitalWrite 3 LOW //digitalWrit第一個參數指引腳3;第二個參數設置引腳3的電平為低
pinMode用于設置管腳的屬性(輸入還是輸出),命令格式為
pinMode pinNum mode
mode可以數字或以下關鍵詞
OUTPUT
OUTPUT_OPEN_DRAIN
INPUT_ANALOG
INPUT_PULLUP
INPUT_PULLDOWN
INPUT_FLOATING
PWM
PWM_OPEN_DRAIN
完整的定義在github上可以找到: https://github.com/WRTnode/wrtnode2r_stm32/blob/master/applications/application.c#L66
digitalWrite用于控制輸出管腳的輸出電平,命令格式如下:
digitalWrite pinNum HIGH/LOW
再來介紹pwmWrite命令,命令格式如下:
pwmWrite pinNum duty_cycle
其中,duty_cycle的取值范圍是0~65535,占空比就是duty_cycle/65535 當然,首先要將管腳設置為PWM模式,通過以下命令
$ pinMode 0 PWM
3. 在腳本語言中調用Arduino函數與STM32交互
用0、1、2、6引腳(PA0、PA1、PA8、PA11)做跑馬燈
#!/bin/sh
spi-bridge write "pinMode 0 0"
spi-bridge write "pinMode 1 0"
spi-bridge write "pinMode 2 0"
spi-bridge write "pinMode 6 0"while truedo
spi-bridge write "digitalWrite 0 1"
sleep 1
spi-bridge write "digitalWrite 0 0"
spi-bridge write "digitalWrite 1 1"
sleep 1
spi-bridge write "digitalWrite 1 0"
spi-bridge write "digitalWrite 2 1"
sleep 1
spi-bridge write "digitalWrite 2 0"
spi-bridge write "digitalWrite 6 1"
sleep 1
spi-bridge write "digitalWrite 6 0"
done
4. 代碼下載及編譯
WRTnode2R上STM32的全部代碼均開源,用戶可以任意下載。
Github repo:https://github.com/WRTnode/wrtnode2r_stm32
有些用戶希望能夠在usart1上使用msh,而不是通過7688的spi,將msh映射到usart1的branch,代碼庫如下:https://github.com/WRTnode/wrtnode2r_stm32/tree/uart-msh
編譯流程:
首先安裝python scons gcc-arm-none-eabi(4.8 or above),然后執行以下代碼:$ mkdir wrtnode2r-stm32$ cd wrtnode2r-stm32$ git clone https://github.com/WRTnode/wrtnode2r_stm32 wrtnode2r_stm32$ git clone https://git.oschina.net/SchumyHao/rt-thread.git rtt$ cd wrtnode2r_stm32
設置gcc路徑:
$ vi rtconfig.py$ scons
編譯成功后,生成的rtthread.bin即為stm32的固件。 固件更新
在WRTnode2R的stm32上,為了實現在7688上更新stm32的固件,在stm32的前4k地址燒寫了一個bootloader程序,同時在7688上也提供了刷寫固件的程序flash-stm32。 如果使用flash-stm32,用戶僅需要執行
flash-stm32 URL
URL這個命令行參數可以是stm32固件的鏈接,也可以是指定的本地stm32系統;就可以將存在服務器上的固件或者本地的固件燒寫到stm32中。
如果用戶希望進行stm32的開發,建議用戶使用stlink等在線調試工具來開發、調試和燒寫代碼。在開發前只需要注意點三: 1.用戶開發的代碼中要將中斷向量表重定向到0x08001000位置。 2.用戶代碼下載時,要下載到0x08001000位置。 3.如果用戶完全拋棄提供的代碼進行開發,但是又希望能夠支持在線更新固件的功能,需要在用戶開發的代碼中實現7688控制stm32復位的功能。(在提供的代碼中,已經實現了reset這個cmd,所以基于提供的代碼進行開發,不需要完成這一步)