亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現在的位置是:首頁 > 技術閱讀 >  stm32移植threadx rtos

stm32移植threadx rtos

時間:2024-06-01

文章目錄

  • 寫在前面

  • 準備移植

  • 開始移植

  • 驗證

  • 最后一點


點擊下方閱讀原文可訪問文中超鏈接


寫在前面

ThreadX 是由 Express Logic 公司開發的實時操作系統。目前已被微軟收購,并且前不久開源了,當開源的時候很多論壇都第一時間發布了相關文章,可見其影響力還是很不錯的,剛好最近有一個新項目,需要用到網絡協議棧,而threadx有自己的網絡協議棧組件,之前打算用freeRTOS加LWIP的方式,現在直接用threadx加netx的方式。
首先到github上下載threadx的源碼,建議使用git,下載zip的話非常慢,而且容易失敗,點擊鏈接threadx下載。

準備移植

下載好源碼后就準備開始移植了,我以stm32f407為例,keil版本5.31,threax版本6.0.1,其它系列都差不多,最近的一次更新增加了非常多的器件支持。看下源碼目錄:

這次是移植,主要關心ports文件夾就行了,里面是針對各種內核寫的移植文件,我這里對應的是cortex_m4這個文件夾,打開后里面有四個目錄:

我用的是keil,但是我選擇的是ac5這個文件夾,因為我用的也是ac5編譯器,我對比了一下keil文件夾和ac5文件夾里面的內容不一樣的地方只有一個,這個后面再說。

開始移植

首先搭建一個簡單的裸機工程,然后添加threadx的源碼及移植文件,添加完后如下:

我們主要修改tx_initialize_low_level.s文件,其它幾個文件都是可以不用動的,這個文件和st提供的啟動文件沖突了,但是這個文件內容又不全。采用的方法類似freeRTOS的移植方法,不動st的啟動文件。

  • 首先更改時鐘頻率及給滴答定時器設置的重裝載值

SYSTEM_CLOCK EQU 168000000
SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 1000) -1)
  • 刪掉堆棧大小定義代碼段(沖突)

  • 刪掉向量表的定義(沖突)

  • 刪掉Reset_Handler代碼段(沖突)

  • 刪掉__user_initial_stackheap代碼段(沖突)

  • 刪掉__tx_BadHandler代碼段(沒用)

  • 刪掉__tx_SVCallHandler代碼段(沒用)

  • 刪掉__tx_IntHandler代碼段(沒用)

  • 刪掉__tx_NMIHandler代碼段(沒用)

  • 刪掉__tx_DBGHandler代碼段(沒用)

編譯一下,報了兩個錯說是__tx_vectors未定義

這個是向量表的基地址,在st提供的啟動文件中已經定義了,改成啟動文件中的向量表__Vectors,注意要先在前面導入這個符號。

IMPORT __Vectors

再次編譯提示PendSV_Handler重復定義,但是卻未提示SysTick_Handler重復定義,從以往移植其它rtos的經驗來看,基本上都是使用滴答定時器作為系統心跳,我們暫且繼續往下看

屏蔽掉stm32f4xx_it.c文件中的PendSV_Handler函數,threadx需要用來進行上下文切換。
再次編譯提示tx_application_define未定義,這個是在threadx系統啟動的時候會自動調用,我們如果需要創建任務或者信號量等資源的話都是在這個函數里面完成,參考實現可仿照sample_threadx.c文件。

在main函數中添加頭文件并且添加此函數的實體

#include "tx_api.h"

VOID tx_application_define(VOID *first_unused_memory)
{
/*暫時留空*/
}

這個問題解決后再次編譯又報了幾個錯,也是未定義,猜測這幾個符號是編譯完代碼后在某個中間文件生成的,在鏈接的時候這里再獲取其值,因為keil編譯完程序生成的map文件有類似的符號

經過搜索,發現只有ImageZILimit有用(這里$顯示不出來),其它都沒有使用,從官方提供的其它移植的例程得知這里是用戶可用內存(運行環境需要的除外,比如C運行環境的堆棧)的起始地址,設置為__initial_sp,同樣的需要在前面IMPORT這個符號,__initial_sp有點特殊,需要勾選keil選項中的Use MicroLIB選項,不然的話提示找不到這個符號的定義,這是從啟動文件得知的。

;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
IF :DEF:__MICROLIB

EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit

ELSE

IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
...

現在已經編譯成功了,但是你會發現系統跑不起來,這就是前面為什么說SysTick_Handler這個函數沒有報重復定義的錯,因為系統的心跳還沒有提供,看下PendSV_Handler是怎么實現的。

; /* Generic context switching PendSV handler. */
;
EXPORT __tx_PendSVHandler
EXPORT PendSV_Handler
__tx_PendSVHandler
PendSV_Handler

這里將兩個標號寫在一起,也就是相當于一個函數的兩個名字,實際上是同一個東西,模仿一下,添加SysTick_Handler,然后屏蔽掉stm32f4xx_it.c文件中的SysTick_Handler函數。

EXPORT __tx_SysTickHandler
EXPORT SysTick_Handler
__tx_SysTickHandler
SysTick_Handler

編譯成功,現在移植已經就大功告成了,添加兩個線程測試下(參考sample_threadx.c文件)

void thread_0_entry(ULONG thread_input)
{
/* This thread simply sits in while-forever-sleep loop. */
while(1)
{
PRINTF("thread 0 is running..\r\n");

tx_thread_sleep(1000);
}
}

void thread_1_entry(ULONG thread_input)
{
/* This thread simply sends messages to a queue shared by thread 2. */
while(1)
{
PRINTF("thread 1 is running..\r\n");

tx_thread_sleep(500);
}
}

測試結果,目前運行良好,暫時還不知道有沒有其它問題

驗證

雖然系統移植好了,但是怎么才能驗證呢,比如我這里延時的時間是準確的嗎?我們可以將HAL_GetTick這個函數移植進來,然后測試下時間是否準確,當然也有其它方式。
將HAL庫里面stm32f4xx_hal_timebase_tim_template.c文件拷貝出來,重命名為stm32f4xx_hal_timebase_tim.c,然后添加到工程中,本來裸機的時候使用滴答定時器來實現HAL_GetTick函數的功能,但是現在滴答定時器被用了,st提供了這個文件使用timer6來替代。注意HAL庫F4的庫版本1.25.0有個BUG在這里,我們還需要修改下stm32f4xx_hal_timebase_tim.c文件HAL_InitTick函數,否則會出現斷言失敗(如果開啟了斷言檢測),因為這個函數在HAL_Init被調用了一次,傳入的參數是TICK_INT_PRIORITY(0x0F),然后在SystemClock_Config函數又調用了一下,這次調用的時候入參是一個全局變量,而在老版本的庫中,這里入參還是TICK_INT_PRIORITY,就是因為這里入參現在傳了個全局變量才會導致斷言失敗,并且優先級設置的是個錯誤的值,修改如下:

/*略*/
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0U);

/*新版BUG,這里參考stm32f4xx_hal.c文件的HAL_InitTick函數*/
uwTickPrio = TickPriority;

/* Enable the TIM6 global Interrupt */
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
/*略*/

但是測試結果卻出乎意料

我明明延時的1秒,但是出來的兩個值間隔時間根本就不是1秒,最開始懷疑系統移植哪里有錯誤,無奈只好看ports里面那幾個匯編文件,看來看去也沒有發現問題,各種測試都是一樣的結果,最后嘗試更改stm32f4xx_hal_timebase_tim.c文件的函數HAL_InitTick傳入的優先級參數,試了一下,時間準確了,多次測試發現,只要優先級設置的不是0x0F就正確,又在tx_initialize_low_level.s文件的_tx_initialize_low_level代碼段看到里面將PnSV和SVC設置的0x0F優先級,所以猜測這個中斷優先級被threadx用了后,其它地方就不能用了,這個和以前用的uCOS和freeRTOS還有所不同。再次修改代碼。

/*略*/
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0U);

/*0x0f優先級已被threadx系統使用*/
TickPriority -= 1;
/*新版BUG,這里參考stm32f4xx_hal.c文件的HAL_InitTick函數*/
uwTickPrio = TickPriority;

/* Enable the TIM6 global Interrupt */
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
/*略*/

這次修改后,正確了

最后一點

前面有一段說了ports文件夾下面的ac5和keil移植文件就只有一個區別,如下

這里是出棧操作,按理說正確的匯編代碼應該是右邊的寫法,但是左邊的寫法編譯時居然沒報錯,而且運行也是正常的,兩種寫法我都測試了,都可以正常穩定運行,暫時不知道具體原因,只有看官方之后的更新到底是怎樣的,可能這里本身就是個BUG,也可能左邊寫法有其它含義。
文章的整個測試源碼可以在我的碼云倉庫獲取。源碼點這兒

歡迎掃碼關注我的微信公眾號


亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产一区二区毛片| 在线精品国产成人综合| 在线精品高清中文字幕| 欧美国产亚洲另类动漫| 日韩亚洲精品视频| 欧美体内谢she精2性欧美| 亚洲欧美在线aaa| 国产精品久久久| 一本色道久久综合亚洲精品不卡 | 亚洲人成久久| 可以免费看不卡的av网站| 亚洲视频在线观看网站| 亚洲人成网站在线播| 国内精品久久久久久久影视蜜臀 | 久久亚洲一区二区| 亚洲制服av| 久久精品人人做人人爽| 欧美日韩视频在线一区二区| 亚洲婷婷综合久久一本伊一区| 亚洲精品人人| 久久久爽爽爽美女图片| 开心色5月久久精品| 在线观看国产欧美| 国外视频精品毛片| 国产精品播放| 亚洲高清久久网| 亚洲人成啪啪网站| 伊人婷婷久久| 欧美日韩亚洲一区二区三区在线观看| 亚洲自拍偷拍网址| 亚洲视频在线观看免费| 国产欧美日韩在线播放| 亚洲一区二区影院| 极品少妇一区二区三区精品视频| 亚洲国产激情| 国产在线精品一区二区中文| 欧美在线免费视屏| 欧美在线免费观看视频| 欧美亚洲一区| 久久亚洲综合| 欧美精品v日韩精品v国产精品| 伊人久久婷婷色综合98网| 欧美亚洲成人免费| 国产一区二区三区久久久| 经典三级久久| 亚洲人体影院| 中文欧美字幕免费| 精品电影一区| 亚洲精品日韩综合观看成人91| 亚洲精品美女在线观看播放| 亚洲欧洲一区| 欧美在线视频免费| 欧美电影专区| 欧美日韩在线视频首页| 国产亚洲福利社区一区| 欧美天天在线| 国产日韩欧美亚洲| 欧美承认网站| 日韩亚洲欧美综合| 亚洲午夜国产成人av电影男同| 欧美亚洲日本网站| 欧美精品一区三区| 久久综合给合| 欧美午夜大胆人体| 国产日本亚洲高清| 亚洲人体1000| 久久精品视频va| 欧美国产日韩精品| 国产美女精品一区二区三区 | 欧美制服丝袜| 久久av一区二区| 欧美午夜精品| 欧美在线视频一区二区| 欧美激情国产精品| 午夜精彩视频在线观看不卡 | 精品成人a区在线观看| 亚洲精品国产视频| 久久久久久一区二区三区| 国产精品亚洲аv天堂网| 国产日韩亚洲| 一区二区国产在线观看| 亚洲成人在线视频播放| 亚洲欧美日韩爽爽影院| 欧美日韩国产丝袜另类| 亚洲片区在线| 中文av一区二区| 亚洲视频欧美在线| 欧美国产日韩一二三区| 精品91久久久久| 久久国产天堂福利天堂| 久久尤物视频| 国产精品色午夜在线观看| 鲁大师成人一区二区三区| 国产精品久久久久久久久免费桃花| 亚洲狠狠婷婷| 欧美成ee人免费视频| 精品动漫一区二区| 久久精品主播| 一区二区三区亚洲| 久久先锋影音| 亚洲第一主播视频| 欧美成ee人免费视频| 亚洲人成亚洲人成在线观看| 欧美激情视频网站| 日韩亚洲在线观看| 欧美日韩mp4| 国产女优一区| 午夜久久福利| 国产一区在线视频| 亚洲精品影院在线观看| 欧美成人xxx| 亚洲精品在线观看视频| 欧美日本亚洲| 午夜精品免费在线| 亚洲欧洲在线观看| 国产精品伊人日日| 国产精品久久国产愉拍| 99爱精品视频| 欧美成人午夜77777| 玖玖玖国产精品| 国产精品日韩久久久久| 亚洲午夜高清视频| 国产女精品视频网站免费| 国产日本欧美视频| 欧美aⅴ99久久黑人专区| 亚洲人午夜精品免费| 亚洲免费视频一区二区| 国产一区免费视频| 欧美国产日韩一区二区在线观看 | 久久亚洲精品伦理| 欧美一区影院| 国产综合精品一区| 国产美女高潮久久白浆| 亚洲欧美国产精品桃花| 国模叶桐国产精品一区| 亚洲综合日韩| 欧美成人国产一区二区| 黄色日韩网站| 欧美精品色综合| 欧美一区二区女人| 极品少妇一区二区三区| 亚洲欧美国产毛片在线| 黄色一区二区在线| 欧美日韩在线播| 久久综合九九| 国产精品99久久久久久久久久久久| 国产精品久久午夜夜伦鲁鲁| 一本色道久久综合狠狠躁篇的优点| 欧美视频一区二| 久久综合色综合88| 亚洲综合国产| 999亚洲国产精| 在线日本欧美| 欧美福利视频一区| 亚洲欧美国产日韩中文字幕| 亚洲激情欧美激情| 免费视频一区| 亚洲精选久久| 在线观看91精品国产麻豆| 欧美日韩亚洲不卡| 裸体素人女欧美日韩| 午夜影视日本亚洲欧洲精品| 亚洲国产一区二区视频| 狠狠色狠色综合曰曰| 国产精品久久久久高潮| 欧美国产日韩精品| 久久影院亚洲| 久久gogo国模啪啪人体图| 一片黄亚洲嫩模| 日韩视频不卡| 亚洲精品视频一区| 91久久在线视频| 亚洲福利视频在线| 国产一区二区0| 国产精品亚洲成人| 欧美三级乱码| 欧美视频中文字幕| 欧美精品播放| 欧美精品情趣视频| 欧美精品不卡| 欧美黄网免费在线观看| 美女日韩在线中文字幕| 久久久久久成人| 久久漫画官网| 美女露胸一区二区三区| 你懂的视频一区二区| 亚洲尤物在线| 亚洲一区二区黄| 午夜精品久久久久| 欧美中文字幕在线| 久久久久久69| 久久综合色综合88| 久久午夜精品一区二区| 久久人体大胆视频| 欧美va天堂va视频va在线| 欧美精选在线| 国产精品二区在线| 国产精品一区亚洲| 亚洲欧美精品在线观看| 午夜天堂精品久久久久|