RT-Thread初探--文件系統掛載norflash

來自專欄閑扯嵌入式9 人贊了文章

最近發現一個很有意思的國產Iot操作系統RT-Thread(以下簡稱RTT)

為什麼說很有意思?因為和我之前常用的FreeRTOS相比,RTT有很多額外的package。

如:命令行(finsh/msh shell),虛擬文件系統(FAT,YAFFS,UFFS,ROM/RAM文件系統等),TCP/IP網路協議棧(lwIP),Libc/POSIX標準層,以及更多的Iot軟體包(MQTT,Coap)

特別是shell,讓我在stm32上體驗到了和以往不同的樂趣,以往都是直接通過Jlink模擬調試,現在不接串口輸出一下shell總感覺少了什麼,哈哈。

昨天第一次正式玩了一下RTT,就寫下我分享下我一個實驗的過程。

硬體平臺:一塊STM32F407ZG的開發板,板載W25Q128BV SPI NorFlash

SPI介面:

使用硬體SPI1,

PB3 ------> SPI1_SCK

PB4 ------> SPI1_MISO

PB5 ------> SPI1_MOSI

步驟:

使用ENV(RTT的開發輔助工具)進入到rt-threadspstm32f4xx-HAL中:

使用menuconfig配置內核以及package。

進入 Components ---> Device virtual file system

打開fatfs支持

返回Components ---> Device Driver,打開SPI驅動以及W25QXXX支持

返回Components ---> POSIX

返回到最開始頁面向下滾動,選擇CS引腳

配置結束,保存退出。在env中執行

pkgs --force-update

更新所有選擇package。

scons --target=mdk5

生成mdk5的工程文件,使用mdk5打開如下圖

找到drv_spi.c中的void HAL_SPI_MspInit(SPI_HandleTypeDef *spiHandle)函數

因為開發板上雖然也使用的SPI1但是引腳復用和默認的並不相同,需要修改此處代碼才能正確的使用flash。代碼修改如下。

if (spiHandle->Instance == SPI1){ /* // SPI1 clock enable __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); //SPI1 GPIO Configuration PA5 ------> SPI1_SCK PA6 ------> SPI1_MISO PA7 ------> SPI1_MOSI GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); */ // SPI1 clock enable __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); //SPI1 GPIO Configuration //PB3 ------> SPI1_SCK //PB4 ------> SPI1_MISO //PB5 ------> SPI1_MOSI GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}

同樣再找到void HAL_SPI_MspDeInit(SPI_HandleTypeDef *spiHandle),代碼修改如下:

if (spiHandle->Instance == SPI1){ /* Peripheral clock disable */ //__HAL_RCC_SPI1_CLK_DISABLE(); /**SPI1 GPIO Configuration PA5 ------> SPI1_SCK PA6 ------> SPI1_MISO PA7 ------> SPI1_MOSI */ //HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); /* Peripheral clock disable */ __HAL_RCC_SPI1_CLK_DISABLE(); /**SPI1 GPIO Configuration PB3 ------> SPI1_SCK PB4 ------> SPI1_MISO PB5 ------> SPI1_MOSI */ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);}

此時,驅動添加的工作已經全部結束,現在是需要掛載我們的flash到根目錄下,回到我們的主函數main()。添加一個函數,並在main中調用他。

void flash_test(void){ rt_device_t dev; while(1) { dev = rt_device_find("flash0"); if(dev != RT_NULL) { if(dfs_mount("flash0", "/", "elm", 0, 0) == 0) { rt_kprintf("flash mount to / success!
"); } else { rt_kprintf("flash mount to / failed!
"); } break; } rt_thread_delay(50); }}

編譯燒錄程序後,就到我們最期待的shell操作環節(???),連接串口,複位,輸出如下:

當然第一次可能是失敗的,此時需要格式化flash,使用命令:

mkfs -t elm flash0

此時複位晶元,就會看到如上輸出了,list_device就可以看到flash0的ref已經為1,說明掛載成功。

至此第一次試驗圓滿結束,期間也經歷過很多波折,比如修改配置文件,修改spi驅動,格式化flash以及掛載都花了不少時間。不過總的來說,RTT還是比較好上手,且比較易用的,之後還會繼續研究他關於iot協議這塊的支持情況,繼續保持關注吧。


推薦閱讀:
查看原文 >>
相關文章