1、使用的uTenux內核代碼:http://www.uloong.cc/cn/download/uTenux_V1.6.00r180.zip
2、uTenux的特性:
1、微內核 2、開放源碼、完全免費 3、不需要MMU,占用ROM/RAM少 4、可移植、可固化、可裁剪 5、搶占式實時多任務操作系統 6、支持所有32位ARM7/9和Cortex M系列的微控制器 7、可配置任意多個的任務、任務的優先級最多255個
3、實驗軟硬件環境:
OS軟件版本:uTexux1.60
開發板:STM32F4 Discovery
工具鏈:MDK470
4、最新版本使用單工程形式給出,不用再為查找不到變量而擔心。而舊版本OS的各個部分分成了獨立的工程,看代碼相對比較麻煩點,就連寫代碼時候,MDK的語法提示功能都不能使用。
5、依賴於宏定義和目錄結構的頭文件引用
uT工程中包含了很多芯片配置和應用,估計是為了方便編譯和擴展,使用了一種很奇怪的頭文件引用方式。對於一般的開發,感覺很繁瑣。
比如,我使用STM32F4VG這個芯片,按照悠龍提供的配置手冊就要打開D:\uLoong\uTenux\bin\app_stm32f4\workspace.uvmpw這個工程文件。
在這個工程的編譯選項里邊,定義了這么幾個宏定義:_APP_STM32F4_,_CHIP_STM32F407VG_,CPU_ARMV7E_M。
在Appusermain工程的usermain.c文件中,我們可以看到這么個引用:
#include <tk_config.h>
tk_config.h文件位於D:\uLoong\uTenux\config目錄下,這個文件中有這么個引用:
#include <sysdepend/tk_config_common.h>
我們可以在sysdepend這個文件夾找到tk_config_common.h。這里就將引用導向了另外一個位置。
在文件tk_config_common.h中,宏定義就開始登場了:這個文件里做的是一些根據宏定義而進行的條件編譯。這里的條件編譯,同樣是將引用指向另外的位置。
在F4的工程中定義了_APP_STM32F4_於是,引用又導向到了sysdepend/app_stm32f4/tk_config_depend.h
同樣,這個tk_config_depend.h也在做根據宏定義的導向:
#ifdef _CHIP_STM32F407IG_ #include <sysdepend/app_stm32f4/chip_stm32f407ig/tk_config_depend.h> #endif #ifdef _CHIP_STM32F407VG_ #include <sysdepend/app_stm32f4/chip_stm32f407vg/tk_config_depend.h> #endif #ifdef _CHIP_STM32F407ZG_ #include <sysdepend/app_stm32f4/chip_stm32f407zg/tk_config_depend.h> #endif我們定義了_CHIP_STM32F407VG_於是引用被最終導向到了這里
D:\uLoong\uTenux\config\sysdepend\app_stm32f4\chip_stm32f407vg\tk_config_depend.h
這才是真正的系統配置文件。各種芯片信息都在這里了。
還有幾個地方使用的也是這種配置引用導向的方式,比如各種MakeFile,暫時還沒去關心。
這種引用方式,對於程序的擴展,添加更多的 MCU 確實很方便。可是我在看代碼的時候卻費死了勁。也許悠龍這么做,就是為了讓俺們不要關心最底層的代碼吧!
6、一點總結:
1、uT的WorkSpace里邊所有的工程都會引用根目錄下include和config這兩個文件夾。
2、使用宏定義確定使用的是哪個系列的哪種芯片。如果uT沒有提供,可以自己加。
3、uT的跳轉很多,引用包含很多。但是結構一致,搞懂一個剩下的就容易了。
4、要添加自己的驅動,將文件放到D:\uLoong\uTenux\lib\libdev\src\sysdepend\app_stm32f4中,並將驅動文件添加到工程目錄的libdev目錄里。
5、各個工程有不同的分工,寫哪個部分將哪個工程設置為活躍,不然就會有各種難題出現。
7、每次修改代碼之后,都要Batch Build。
Bin這個工程每次都需要重新編譯
Appusermain工程中操作使用OS提供的功能,比如創建/刪除任務。當更改這個工程內容時需要重新編譯
Kernel工程只需要在首次編譯時候或者修改了配置文件之后編譯下即可,因為我們一般是不需要修改內核的。
Libcpu、libtm、libdev在修改了與芯片有關的內容時候才需要重新編譯。
8、關於工程中的libtm
這個工程中,有用到 tm_monitor這個東西。
昨天咨詢了uTenux的工程師,工程中tm_monitor是一只打開的,不管配置文件中的USE_TMONITOR是1還是0.
於是,這個monitor就完全可以作為一個串口處理類來使用了。
先了解一下tm_monitor.c中的幾個函數(內核規范中沒得介紹,可能是因為不屬於內核吧)。
1、uint32_t tm_getchar( uint32_t wait );
關中斷,然后從控制台接收字符。
2、uint32_t tm_getline( uint8_t *buff );
關中斷,然后接收一行字符。直到遇見結束符(空字符)
3、void tm_monitor( void );
就是一個空的for死循環
4、uint32_t tm_putchar( uint32_t c );
向控制台發送一個字符
5、uint32_t tm_putstring( const uint8_t *buff );
向控制台發送字符串
這里的各個功能都依賴於串口實現。串口的實現在libdev中的ts_uart.c中完成。只有三個函數:初始化,接收字符,發送字符:
1、void uart_init(void)
串口初始化
2、void uart_sendchar(uint8_t c)
串口發送一個字符
3、uint8_t uart_recvchar(void)
通過串口接收一個字符。如果沒有字符進來,就一直死循環。
9、向工程中添加底層驅動:
將驅動文件放入D:\uLoong\uTenux\lib\libdev\src\sysdepend\app_at91sam3文件夾中
將文件添加到工程libdev的src目錄中
在D:\uLoong\uTenux\include\dev\sysdepend\ts_devdef_common.h中添加對驅動頭文件的引用。
將硬件初始化函數添加到文件D:\uLoong\uTenux\include\dev\sysdepend\ts_devdef_common.h中的函數Inline void bsp_init ( void )中。
重新編譯。之后就可以使用你寫的硬件驅動了。
當然,想文件中添加這些內容的時候,要注意宏定義,別搞錯了MCU
10、在示例工程中打開STM32F4的FPU功能
先在編譯選項中設置使用FPU,然后在內核文件knl_kernel.h中第97行設置即可
#define __FPU_PRESENT 1
當然,我不知道為什么要用FPU。但是有這個功能就打開好了