RT-Thread初探--文件系統掛載norflash
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協議這塊的支持情況,繼續保持關注吧。
推薦閱讀: