FREERTOS 手冊閱讀筆記


鄭重聲明,版權所有!

轉載需說明。

 

 

FREERTOS堆棧大小的單位是word,不是byte.

根據處理器架構優化系統的任務優先級不能超過32,If the architecture optimized method is used then configMAX_PRIORITIES cannot be greater than 32.

 

vTaskDelay() delay from call the vTaskDelay 

vTaskDelayUntil delay from last wake up time

 

It is the responsibility of the idle task to free memory allocated to tasks that have since been deleted.

 

Ready state tasks of equal priority will enter the Running state in turn.  ‘Round Robin Scheduling’  

同一優先級任務實行時間片輪轉調度。

 

A time slice is equal to the time between two RTOS tick interrupts.

時間片值等於TICK時鍾值

 

消息序列讓局部變量存放在序列中,函數退出時局部變量仍然在序列中

 

In practice it is very common for a queue to have multiple writers, but much less common for a queue to have multiple readers.

 

多個任務等待同一序列:Queues can have multiple readers, so it is possible for a single queue to have more than one task blocked on it waiting for data. When this is the case, only one task will be unblocked when data becomes available. The task that is unblocked will always be the highest priority task that is waiting for data. If the blocked tasks have equal priority, then the task that has been waiting for data the longest will be unblocked.

 

應該任務等待多個序列:Queues can be grouped into sets, allowing a task to enter the Blocked state to wait for data to become available on any of the queues in the set.

 

創建序列返回的是序列指針,序列本身由OS內部動態分配在OS的Heap中:The xQueueCreate() API function creates a queue and returns a QueueHandle_t that references the queue it created.

 

清空序列:xQueueReset() API function can be used to return the queue to its original empty state.

 

xQueueSendToBack() is used to send data to the back (tail) of a queue xQueueSendToFront() is used to send data to the front (head) of a queue.

xQueueSend() = xQueueSendToBack().

 

xTicksToWait 是0則立即返回,Both xQueueSendToFront() and xQueueSendToBack() will return immediately if xTicksToWait is zero and the queue is already full.

 

 

xTicksToWait 是portMAX_DELAY則一直等待:Setting xTicksToWait to portMAX_DELAY will cause the task to wait indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.

 

請求序列有多少個信息:uxQueueMessagesWaiting() is used to query the number of items that are currently in a queue.

 

序列傳指針注意事項:when queuing pointers, extreme care must be taken to ensure that:

1. The owner of the RAM being pointed to is clearly defined.

2. The RAM being pointed to remains valid.動態分配必須沒有被free

 

序列集:

xQueueAddToSet() adds a queue or semaphore to a queue set

 

 

FREERTOS CAN Using a Queue to Create a Mailbox

郵箱是長度為1的序列:In this book the term mailbox is used to refer to a queue that has a length of one

郵箱被讀取后並不會被消耗,只會在重新發送時被覆蓋:A mailbox is used to hold data that can be read by any task, or any interrupt service routine. The data does not pass through the mailbox, but instead remains in the mailbox until it is overwritten. The sender overwrites the value in the mailbox. The receiver reads the value from the mailbox, but does not remove the value from the mailbox.

 

郵箱具有廣播特性!!!,任務讀取后不被覆蓋,別的任務依然可以讀取,郵箱大小永遠是1,只能讀到發送的最新的郵件,讀消息郵箱每次都會讀到,根據時間戳可以判斷是不是被更新。

 

if the queue is already full, then xQueueOverwrite() will overwrite data that is already in the queue.

xQueuePeek() is used to receive (read) an item from a queue without the item being removed from the queue.

參考手冊4.7節設計消息郵箱功能。

 

Software Timer

軟件定時器適合的應用場合:

l  事件發生后加一個延遲產生一個動作

l  周期性執行某個函數(任務中系統調用只有delay的任務)

They should be kept short, and must not enter the Blocked state.

會在上下文切換時調用

 

The xTimerDelete() API function deletes a timer. A timer can be deleted at any time.

 

 

All software timer callback functions execute in the context of the same RTOS daemon (or ‘timer service’) task1.

The daemon task is a standard FreeRTOS task that is created automatically when the scheduler is started. Its priority and stack size are set by the configTIMER_TASK_PRIORITY and configTIMER_TASK_STACK_DEPTH compile time configuration constants respectively. Both constants are defined within FreeRTOSConfig.h.

 

軟件定時器回調函數由系統守護進程(定時器服務)調用,在配置里可以配置它的優先級和堆棧大小。

 

configTIMER_TASK_STACK_DEPTH決定最多由多少個在線軟件定時器,為保證軟件定時器無阻塞正常執行,執行后不需要的定時器需要刪除

 

xTimerChangePeriod()改變定時器周期

 

軟件定時器可以做超時檢測並處理,類似於看門狗,當正常接收時reset定時器,溢出時調用定時器回調函數做超時處理

 

 

任務優先級低於任何硬件的中斷優先級,任務無法搶占中斷!

Tasks will only run when there are no ISRs running, so the lowest priority interrupt will interrupt the highest priority task, and there is no way for a task to pre-empt an ISR.

 

任務中函數引起上下文切換立即切換,中斷引起的上下文切換在中斷退出后開始切換(中斷優先級高於內核調度)

 

中斷中如需進行上下文切換需調用portYIELD_FROM_ISR()如不調用,則中斷引起的上下文切換會在下一次上下文切換時發生(最晚在ostick中斷中發生)

中斷盡量短,中斷把工作延遲給任務有以下優點:

最高優先級任務優先級比中斷低,中斷過長阻塞高優先級任務

中斷是隨機的,影響任務執行的連續性

中斷中有新中斷產生優先級比當前中斷低則會被延遲

中斷嵌套會增加調度復雜性,中斷短之后嵌套概率變小

 

短時間可以執行完的在中斷內執行,否則延遲到任務執行

 

二進制信號量和互斥信號量的區別:

二進制信號量進程本身獲得之后不需要再給出,而互斥信號量必須是誰獲得誰給出。

二進制信號量只借不還,互斥信號量有借有還!

互斥信號量不同於二進制信號量的是互斥信號量有優先級繼承特性(防止優先級反轉)

 

二進制信號量與計數信號量

慢速信號或單次信號可以通過二進制信號量進行同步,連續快速隨機信號可以通過計數信號量緩存,保證信號不被丟失,計數值表示產生的信號數與已經處理的信號數之差,如果計數信號量一直處於滿的狀態說明信號處理程序過慢不能達到要求

 

同時計數信號量還可以用於有限個資源管理,進程需要資源時獲取信號量,使用完資源后釋放信號量。

 

低時間延遲要求的事件可以通過xTimerPendFunctionCallFromISR()直接調用守護進程執行事件處理函數,減少單獨處理任務,簡化設計。

中斷產生消息序列不太可取(這樣使用操作系統API速度會變慢速度慢),最好用DMA或者環形緩沖區

 

中斷邏輯優先級高於configMAX_SYSCALL_INTERRUPT_PRIORITY不會被FREERTOS臨界段屏蔽,小於等於的的會被屏蔽

只有邏輯優先級小於等於configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷可以調用OS的API

 

Typically, functionality that requires very strict timing accuracy (motor control, for example) would use a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY to ensure the scheduler does not introduce jitter into the interrupt response time.

 

If a function does not access any data other than data stored on the stack or held in a

register, then the function is reentrant, and thread safe

 

盡量減少任務共享資源,所有任務共享資源需要保護。

 

進出臨界段只會屏蔽優先級低於configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷

taskENTER_CRITICAL()

taskEXIT_CRITICAL(),

Basic critical sections must be kept very short, otherwise they will adversely affect interrupt response times. 臨界段要短!

 

掛起和解掛調度(未關閉中斷)

vTaskSuspendAll()

xTaskResumeAll()

 

最好把使用互斥信號量的功能寫成函數,保證“有借有還”,成對使用。

 

it is normally bad practice for a task to wait indefinitely (without a time out) to obtain a mutex.沒用TIMEOUT的等待可能導致死鎖

 

遞歸互斥信號量可以被同一任務連續多次請求,然后多次釋放。

 

vApplicationTickHook()中的OS函數必須用FromISR()形式,因為tick函數是再tick中斷中調用的。

 

Gatekeeper Tasks(守門員任務):此任務用來替代互斥信號量,避免出現優先級反轉或死鎖的情況,此任務由用戶自己設計,所有任務中只有此任務可以訪問共享資源,此任務輪詢等待一個消息,得到消息后此任務開始對共享資源進行訪問,之后繼續掛起等待消息。需要訪問共享資源的任務想此任務發送消息,之后此由任務進行共享資源訪問。

 

事件標志組可以用於多個任務同步,具有廣播特性。

 

事件標志組可以讓一個任務等待多個事件,或者讓一個任務等待多個事件之一;

 

事件標志組可以讓多個任務等待多個事件,或者讓多個任務等待多個事件之一;

 

等待事件標志組函數的參數可以配置函數調用后是否清除uxBitsToWaitFor對應事件位

 

可以單獨通過函數xEventGroupClearBits()清除事件標志位

 

事件標志組進行多任務同步(多個任務同時等待多個事件,期望同時進入就緒態)需要使用xEventGroupSync()進行同步,直接使用事件標志組掛起函數會導致調度不能同步。

 

 

Task Notifications

更加快速通知任務,更節省RAM空間。

針對單個任務的通知,中斷不能接收通知,但中斷可以發出通知

非緩存,非廣播。

 

task’s notification類似於一個針對任務的計數信號量,give讓任務通知加一,take收到並讓通知減一或清零。

 

xTaskNotify()可以看作是輕量級的二進制信號量,計數信號量,事件標志組,甚至是通知任務的消息郵箱。

 

調試手段

ConfigASSERT()

FREERTOS+Trace

DEBUG HOOK

Viewing run-time and task state information (statistics)

 

常見問題:

調用操作系統API的中斷優先級必須小於等於configMAX_SYSCALL_INTERRUPT_PRIORITY

 

Cortex-m內核處理器確保所有的中斷優先級都分配非搶占優先級,不要子優先級;

 

堆棧溢出問題:

uxTaskGetStackHighWaterMark() 獲取任務再整個系統運行過程中堆棧的最小剩余值

 

設置configCHECK_FOR_STACK_OVERFLOW為1或2

重寫函數vApplicationStackOverflowHook(),這個函數再上下文切換中斷中調用,其入口參數是任務句柄和任務名

 

針對嵌入式系統改進(重寫)printf()函數

Printf-stdarg.c是個不錯的選擇,其中的sprintf是一個最小實現,其中的printf是相對慢的,占用較大堆棧的,直接輸出的。

 

如果系統堆棧不足導致vTaskStartScheduler()失敗,vTaskStartScheduler()會返回Including a null loop [ for(;;); ] after the call to vTaskStartScheduler() can make this error easier to debug.

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM