FREERTOS 手冊閱讀筆記

鄭重聲明,版權全部!緩存

轉載需說明。架構

 

 

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

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

 

vTaskDelay() delay from call the vTaskDelay 函數

vTaskDelayUntil delay from last wake up time oop

 

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’  ui

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

 

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.

相關文章
相關標籤/搜索