1 | /*
|
---|
2 | * FreeRTOS Kernel V10.3.1
|
---|
3 | * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
---|
4 | *
|
---|
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of
|
---|
6 | * this software and associated documentation files (the "Software"), to deal in
|
---|
7 | * the Software without restriction, including without limitation the rights to
|
---|
8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
---|
9 | * the Software, and to permit persons to whom the Software is furnished to do so,
|
---|
10 | * subject to the following conditions:
|
---|
11 | *
|
---|
12 | * The above copyright notice and this permission notice shall be included in all
|
---|
13 | * copies or substantial portions of the Software.
|
---|
14 | *
|
---|
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
---|
17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
---|
18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
---|
19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
---|
20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
---|
21 | *
|
---|
22 | * http://www.FreeRTOS.org
|
---|
23 | * http://aws.amazon.com/freertos
|
---|
24 | *
|
---|
25 | * 1 tab == 4 spaces!
|
---|
26 | */
|
---|
27 |
|
---|
28 |
|
---|
29 | #include <stdlib.h>
|
---|
30 | #include "FreeRTOS.h"
|
---|
31 | #include "list.h"
|
---|
32 |
|
---|
33 | /*-----------------------------------------------------------
|
---|
34 | * PUBLIC LIST API documented in list.h
|
---|
35 | *----------------------------------------------------------*/
|
---|
36 |
|
---|
37 | void vListInitialise( List_t * const pxList )
|
---|
38 | {
|
---|
39 | /* The list structure contains a list item which is used to mark the
|
---|
40 | end of the list. To initialise the list the list end is inserted
|
---|
41 | as the only list entry. */
|
---|
42 | pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
---|
43 |
|
---|
44 | /* The list end value is the highest possible value in the list to
|
---|
45 | ensure it remains at the end of the list. */
|
---|
46 | pxList->xListEnd.xItemValue = portMAX_DELAY;
|
---|
47 |
|
---|
48 | /* The list end next and previous pointers point to itself so we know
|
---|
49 | when the list is empty. */
|
---|
50 | pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
---|
51 | pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
---|
52 |
|
---|
53 | pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
---|
54 |
|
---|
55 | /* Write known values into the list if
|
---|
56 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
---|
57 | listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
---|
58 | listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
---|
59 | }
|
---|
60 | /*-----------------------------------------------------------*/
|
---|
61 |
|
---|
62 | void vListInitialiseItem( ListItem_t * const pxItem )
|
---|
63 | {
|
---|
64 | /* Make sure the list item is not recorded as being on a list. */
|
---|
65 | pxItem->pxContainer = NULL;
|
---|
66 |
|
---|
67 | /* Write known values into the list item if
|
---|
68 | configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
---|
69 | listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
---|
70 | listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
---|
71 | }
|
---|
72 | /*-----------------------------------------------------------*/
|
---|
73 |
|
---|
74 | void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
|
---|
75 | {
|
---|
76 | ListItem_t * const pxIndex = pxList->pxIndex;
|
---|
77 |
|
---|
78 | /* Only effective when configASSERT() is also defined, these tests may catch
|
---|
79 | the list data structures being overwritten in memory. They will not catch
|
---|
80 | data errors caused by incorrect configuration or use of FreeRTOS. */
|
---|
81 | listTEST_LIST_INTEGRITY( pxList );
|
---|
82 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
---|
83 |
|
---|
84 | /* Insert a new list item into pxList, but rather than sort the list,
|
---|
85 | makes the new list item the last item to be removed by a call to
|
---|
86 | listGET_OWNER_OF_NEXT_ENTRY(). */
|
---|
87 | pxNewListItem->pxNext = pxIndex;
|
---|
88 | pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
---|
89 |
|
---|
90 | /* Only used during decision coverage testing. */
|
---|
91 | mtCOVERAGE_TEST_DELAY();
|
---|
92 |
|
---|
93 | pxIndex->pxPrevious->pxNext = pxNewListItem;
|
---|
94 | pxIndex->pxPrevious = pxNewListItem;
|
---|
95 |
|
---|
96 | /* Remember which list the item is in. */
|
---|
97 | pxNewListItem->pxContainer = pxList;
|
---|
98 |
|
---|
99 | ( pxList->uxNumberOfItems )++;
|
---|
100 | }
|
---|
101 | /*-----------------------------------------------------------*/
|
---|
102 |
|
---|
103 | void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
|
---|
104 | {
|
---|
105 | ListItem_t *pxIterator;
|
---|
106 | const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
---|
107 |
|
---|
108 | /* Only effective when configASSERT() is also defined, these tests may catch
|
---|
109 | the list data structures being overwritten in memory. They will not catch
|
---|
110 | data errors caused by incorrect configuration or use of FreeRTOS. */
|
---|
111 | listTEST_LIST_INTEGRITY( pxList );
|
---|
112 | listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
---|
113 |
|
---|
114 | /* Insert the new list item into the list, sorted in xItemValue order.
|
---|
115 |
|
---|
116 | If the list already contains a list item with the same item value then the
|
---|
117 | new list item should be placed after it. This ensures that TCBs which are
|
---|
118 | stored in ready lists (all of which have the same xItemValue value) get a
|
---|
119 | share of the CPU. However, if the xItemValue is the same as the back marker
|
---|
120 | the iteration loop below will not end. Therefore the value is checked
|
---|
121 | first, and the algorithm slightly modified if necessary. */
|
---|
122 | if( xValueOfInsertion == portMAX_DELAY )
|
---|
123 | {
|
---|
124 | pxIterator = pxList->xListEnd.pxPrevious;
|
---|
125 | }
|
---|
126 | else
|
---|
127 | {
|
---|
128 | /* *** NOTE ***********************************************************
|
---|
129 | If you find your application is crashing here then likely causes are
|
---|
130 | listed below. In addition see https://www.freertos.org/FAQHelp.html for
|
---|
131 | more tips, and ensure configASSERT() is defined!
|
---|
132 | https://www.freertos.org/a00110.html#configASSERT
|
---|
133 |
|
---|
134 | 1) Stack overflow -
|
---|
135 | see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
---|
136 | 2) Incorrect interrupt priority assignment, especially on Cortex-M
|
---|
137 | parts where numerically high priority values denote low actual
|
---|
138 | interrupt priorities, which can seem counter intuitive. See
|
---|
139 | https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
---|
140 | of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
---|
141 | https://www.freertos.org/a00110.html
|
---|
142 | 3) Calling an API function from within a critical section or when
|
---|
143 | the scheduler is suspended, or calling an API function that does
|
---|
144 | not end in "FromISR" from an interrupt.
|
---|
145 | 4) Using a queue or semaphore before it has been initialised or
|
---|
146 | before the scheduler has been started (are interrupts firing
|
---|
147 | before vTaskStartScheduler() has been called?).
|
---|
148 | **********************************************************************/
|
---|
149 |
|
---|
150 | for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
---|
151 | {
|
---|
152 | /* There is nothing to do here, just iterating to the wanted
|
---|
153 | insertion position. */
|
---|
154 | }
|
---|
155 | }
|
---|
156 |
|
---|
157 | pxNewListItem->pxNext = pxIterator->pxNext;
|
---|
158 | pxNewListItem->pxNext->pxPrevious = pxNewListItem;
|
---|
159 | pxNewListItem->pxPrevious = pxIterator;
|
---|
160 | pxIterator->pxNext = pxNewListItem;
|
---|
161 |
|
---|
162 | /* Remember which list the item is in. This allows fast removal of the
|
---|
163 | item later. */
|
---|
164 | pxNewListItem->pxContainer = pxList;
|
---|
165 |
|
---|
166 | ( pxList->uxNumberOfItems )++;
|
---|
167 | }
|
---|
168 | /*-----------------------------------------------------------*/
|
---|
169 |
|
---|
170 | UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
---|
171 | {
|
---|
172 | /* The list item knows which list it is in. Obtain the list from the list
|
---|
173 | item. */
|
---|
174 | List_t * const pxList = pxItemToRemove->pxContainer;
|
---|
175 |
|
---|
176 | pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
---|
177 | pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
---|
178 |
|
---|
179 | /* Only used during decision coverage testing. */
|
---|
180 | mtCOVERAGE_TEST_DELAY();
|
---|
181 |
|
---|
182 | /* Make sure the index is left pointing to a valid item. */
|
---|
183 | if( pxList->pxIndex == pxItemToRemove )
|
---|
184 | {
|
---|
185 | pxList->pxIndex = pxItemToRemove->pxPrevious;
|
---|
186 | }
|
---|
187 | else
|
---|
188 | {
|
---|
189 | mtCOVERAGE_TEST_MARKER();
|
---|
190 | }
|
---|
191 |
|
---|
192 | pxItemToRemove->pxContainer = NULL;
|
---|
193 | ( pxList->uxNumberOfItems )--;
|
---|
194 |
|
---|
195 | return pxList->uxNumberOfItems;
|
---|
196 | }
|
---|
197 | /*-----------------------------------------------------------*/
|
---|
198 |
|
---|