Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to apply FreeRTOS lists and list items

2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Today, I would like to share with you the FreeRTOS list and list items how to apply the relevant knowledge points, detailed content, clear logic, I believe that most people still know too much about this knowledge, so share this article for your reference, I hope you can learn something after reading this article, let's take a look at it.

Preface

FreeRTOS kernel scheduling makes extensive use of list (list) and list item (list item) data structures. If we want to explore the operation mechanism behind FreeRTOS, the first obstacles we encounter are lists and list items. Lists are the most basic part of the FreeRTOS kernel.

Lists are used by the FreeRTOS scheduler to track tasks, and tasks that are ready, suspended, or delayed are hooked to their respective lists. User programs can also use lists if necessary.

The FreeRTOS list uses a pointer to the list item. There may be many list items (list item) under a list, each with a pointer to the list. As shown in figure 1-1.

Figure 1-1: list and list items

There are two forms of list items, the fully functional version of the list item xLIST_ITEM and the mini version of the list item xMINI_LIST_ITEM. Let's take a look at their specific definitions, first take a look at the full-featured version.

Struct xLIST_ITEM {listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE / * is used to check whether the list item data is complete * / configLIST_VOLATILE TickType_t xItemValue; / * list item value * / struct xLIST_ITEM * configLIST_VOLATILE pxNext; / * points to the next list item in the list * / struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; / * points to the previous list item in the list * / void * pvOwner / * point to a task TCB*/ void * configLIST_VOLATILE pvContainer; / * point to the list containing the list item * / listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE / * to check whether the list item data is complete * /}; typedef struct xLIST_ITEM ListItem_t

The macros listFIRST _ LIST_ITEM_INTEGRITY_CHECK_VALUE and listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE are used to check whether the list item data is complete. In projdefs.h, if the macro configUSE _ LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1, the list item data integrity check is enabled, and the macrolistFIRST _ LIST_ITEM_INTEGRITY_CHECK_VALUE and listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE are replaced by two known values.

XItemValue is a list item value, usually a tracked task priority or a counter value for a scheduled event. If a task enters a blocking state because it is waiting to fetch data from the queue, the list item value of the task's event list item stores information about the task priority, and the list item value of the status list item stores information about the blocking time. This variable is modified by configLIST_VOLATILE, and configLIST_VOLATILE is mapped to the C language keyword volatile, indicating that the variable is "variable", telling the compiler not to code optimize this variable, because the members of the list items may be updated in the interrupt service program.

PxNext and pxPrevious are list item type pointers that are used to point to the next and previous list items in the list. With these two pointers, a two-way linked list structure can be formed between list items.

The pointer pvOwner usually points to a task TCB.

The pointer pvContainer points to the list that contains the list items.

The mini version of the list item xMINI_LIST_ITEM is a subset of the full feature version of the list item xLIST_ITEM, defined as follows:

Struct xMINI_LIST_ITEM {listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE / * is used to check whether the list item data is complete * / configLIST_VOLATILE TickType_t xItemValue; struct xLIST_ITEM * configLIST_VOLATILE pxNext; struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;typedef struct xMINI_LIST_ITEM MiniListItem_t

Why declare a mini version of a list item when you have a full-featured version of it? This is because the list structure requires a list item member, but it does not need all the fields in the list item, so there is a mini version of the list item. The list structure is defined as:

Typedef struct xLIST {listFIRST_LIST_INTEGRITY_CHECK_VALUE / * used to check whether the list item data is complete * / configLIST_VOLATILE UBaseType_t uxNumberOfItems; ListItem_t * configLIST_VOLATILE pxIndex; / * used to traverse the list * / MiniListItem_t xListEnd / * list item * / listSECOND_LIST_INTEGRITY_CHECK_VALUE / * is used to check whether the list item data is complete * /} List_t

As with the list item definition, the macros listFIRST _ LIST_INTEGRITY_CHECK_VALUE and listSECOND_LIST_INTEGRITY_CHECK_VALUE are used to check whether the list item data is complete. In projdefs.h, if the macro configUSE _ LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1, the list item data integrity check is enabled, and the macrolistFIRST _ LIST_ITEM_INTEGRITY_CHECK_VALUE and listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE are replaced by two known values.

UxNumberOfItems indicates the number of list items attached to the list, and 0 indicates that the list is empty.

The list item type pointer is used to traverse the list, and after the list is initialized, the pointer points to & xListEnd. Use the macro listGet _ OWNER_OF_NEXT_ENTRY () to get the next list item in the list.

The list item xListEnd is used to mark the end of the list. XListEnd.xItemValue is initialized to a constant whose value is related to the hardware architecture, either 0xFFFF (16-bit architecture) or 0xFFFFFFFF (32-bit architecture).

Let's take a look at the list operation. FreeROTS provides several API functions for initializing list and list items and list item insertion operations.

1. Initialization list

The list structure contains a list item member, which is mainly used to mark the end of the list. Initializing the list is to insert the list item into the list.

Void vListInitialise (List_t * const pxList) {/ * list index points to list item * / pxList- > pxIndex = (ListItem_t *) & (pxList- > xListEnd); / * set to the highest possible value * / pxList- > xListEnd.xItemValue = portMAX_DELAY; / * pxNext and pxPrevious pointers of list item xListEnd point to itself * / pxList- > xListEnd.pxNext = (ListItem_t *) & (pxList- > xListEnd) PxList- > xListEnd.pxPrevious= (ListItem_t *) & (pxList- > xListEnd); pxList- > uxNumberOfItems = (UBaseType_t) 0U; / * set to a known value to check whether the list data is complete * / listSET_LIST_INTEGRITY_CHECK_1_VALUE (pxList); listSET_LIST_INTEGRITY_CHECK_2_VALUE (pxList);}

If the macro configUSE _ LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1, the list item data integrity check is enabled, and the macrolistSET _ LIST_INTEGRITY_CHECK_1_VALUE () and listSET_LIST_INTEGRITY_CHECK_2_VALUE are replaced by a known value, which defaults to 0x5a5a (16-bit schema) or 0x5a5a5a5a (32-bit schema).

Assuming that the list data integrity check is disabled and the initialized list is shown in figure 1-2, uxNumberOfItems is initialized to 0xListEnd.xItemValue and initialized to 0xffffffpxIndex, xListEnd.pxNext, and xListEnd.pxPrevious to point to the list item xListEnd.

Figure 1-2: list after initialization

two。 Initialize list items

The start of a list item is relatively simple, as long as you make sure that the list item is not in any list.

Void vListInitialiseItem (ListItem_t * const pxItem) {pxItem- > pvContainer = NULL; / * is set to a known value to check whether the list item data is complete * / listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE (pxItem); listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE (pxItem);}

If the macro configUSE _ LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1, the list item data integrity check is enabled, and the macrolistFIRST _ LIST_ITEM_INTEGRITY_CHECK_VALUE and listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE are replaced by two known values, default to 0x5a5a (16-bit schema) or 0x5a5a5a5a (32-bit schema).

Assuming that the data integrity check of list items is disabled, the initialized list items are shown in figure 1-3. Simply set the pointer pvContainer to a null pointer, which is used to point to the list containing the list item, which is set to NULL to indicate that the list item does not belong to any list.

Figure 1-3: list items after initialization

3. Inserts a list item into the list, depending on the list item value (xItemValue) of the list item.

Each list item object has a list item value (xItemValue), usually a tracked task priority or a counter value for scheduled events. Call the API function vListInsert (List_t * const pxList, ListItem_t * const pxNewListItem) to insert the list items pointed to by pxNewListItem into the list pointed to by pxList. The position of the list items in the list is determined by pxNewListItem- > xItemValue, and is arranged in ascending order.

Void vListInsert (List_t * const pxList, ListItem_t * const pxNewListItem) {ListItem_t * pxIterator;const TickType_t xValueOfInsertion = pxNewListItem- > xItemValue; / * checks the integrity of list and list item data and is valid only when configASSERT () is defined. * / listTEST_LIST_INTEGRITY (pxList); listTEST_LIST_ITEM_INTEGRITY (pxNewListItem); / * insert new list items into the list and insert the list according to the ascending order of xItemValue values. * / if (xValueOfInsertion = = portMAX_DELAY) {pxIterator = pxList- > xListEnd.pxPrevious;} else {for (pxIterator = (ListItem_t *) & (pxList- > xListEnd) PxIterator- > pxNext- > xItemValue pxNext) {/ * empty * /}} pxNewListItem- > pxNext = pxIterator- > pxNext; pxNewListItem- > pxNext- > pxPrevious= pxNewListItem; pxNewListItem- > pxPrevious= pxIterator; pxIterator- > pxNext = pxNewListItem; pxNewListItem- > pvContainer = (void*) pxList; (pxList- > uxNumberOfItems) + +;}

Inserts a new list item into the list based on the value of xItemValue. If there is a list item in the list that has the same value as the new list item xItemValue, the newly inserted list item follows it. If the xItemValue value of a list item is equal to portMAX_DELAY (the list closing tag, when we talk about the list data structure, we say that each list data structure has a list item member xListEnd that marks the end of the list. XListEnd.xItemValue is initialized to a constant whose value is related to the hardware architecture, either 0xFFFF or 0xFFFFFFFF. This constant is defined in the migration layer, that is, the macro portMax _ DELAY), which indicates that the end of the list has been reached.

We illustrate this function graphically. We assume that a list item with a xItemValue of 32 is inserted into the initialized list shown in figure 1-2. After calling the vListInsert () function, the relationship between the list and the list item is shown in figure 1-4. The member pointers pxNext and pxPrevious of the list item xListItem_1 point to xListEnd, while the member pointers pxNext and pxPrevious of xListEnd point to the member pointer pvContainer of the list item xListItem_1; list item xListItem_1 and point to the list xList_1; list member uxNumberOfItems is 1.

Figure 1-4: inserting list items into the list

On this basis, if you insert a list item with a xItemValue of 40, after calling the vListInsert () function, the relationship between the list and the list item is shown in figure 1-5.

Figure 1-5: inserting list items into the list

4. Insert a list item at the end of the list

The API insert function described in section 3 determines the insertion position based on the list item value (xItemValue) in the list item, and the API function vListInsertEnd () described in this section simply inserts the list item at the end of the list. In the next chapter of the task creation analysis article, you will encounter this API function, then analyze the function in the form of an icon, and now give the source code for this function.

Void vListInsertEnd (List_t * const pxList, ListItem_t* const pxNewListItem) {ListItem_t* const pxIndex = pxList- > pxIndex; / * checks the integrity of list and list item data and is valid only when configASSERT () is defined. * / listTEST_LIST_INTEGRITY (pxList); listTEST_LIST_ITEM_INTEGRITY (pxNewListItem); / * insert new list items into the list * / pxNewListItem- > pxNext = pxIndex; pxNewListItem- > pxPrevious = pxIndex- > pxPrevious; mtCOVERAGE_TEST_DELAY (); pxIndex- > pxPrevious- > pxNext = pxNewListItem; pxIndex- > pxPrevious = pxNewListItem; pxNewListItem- > pvContainer = (void*) pxList; (pxList- > uxNumberOfItems) + + } these are all the contents of the article "how to apply FreeRTOS lists and list items". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report