Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.
croutine.c
00001 /* 00002 FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd. 00003 All rights reserved 00004 00005 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 00006 00007 This file is part of the FreeRTOS distribution. 00008 00009 FreeRTOS is free software; you can redistribute it and/or modify it under 00010 the terms of the GNU General Public License (version 2) as published by the 00011 Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. 00012 00013 *************************************************************************** 00014 >>! NOTE: The modification to the GPL is included to allow you to !<< 00015 >>! distribute a combined work that includes FreeRTOS without being !<< 00016 >>! obliged to provide the source code for proprietary components !<< 00017 >>! outside of the FreeRTOS kernel. !<< 00018 *************************************************************************** 00019 00020 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 00021 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00022 FOR A PARTICULAR PURPOSE. Full license text is available on the following 00023 link: http://www.freertos.org/a00114.html 00024 00025 *************************************************************************** 00026 * * 00027 * FreeRTOS provides completely free yet professionally developed, * 00028 * robust, strictly quality controlled, supported, and cross * 00029 * platform software that is more than just the market leader, it * 00030 * is the industry's de facto standard. * 00031 * * 00032 * Help yourself get started quickly while simultaneously helping * 00033 * to support the FreeRTOS project by purchasing a FreeRTOS * 00034 * tutorial book, reference manual, or both: * 00035 * http://www.FreeRTOS.org/Documentation * 00036 * * 00037 *************************************************************************** 00038 00039 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 00040 the FAQ page "My application does not run, what could be wrong?". Have you 00041 defined configASSERT()? 00042 00043 http://www.FreeRTOS.org/support - In return for receiving this top quality 00044 embedded software for free we request you assist our global community by 00045 participating in the support forum. 00046 00047 http://www.FreeRTOS.org/training - Investing in training allows your team to 00048 be as productive as possible as early as possible. Now you can receive 00049 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 00050 Ltd, and the world's leading authority on the world's leading RTOS. 00051 00052 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 00053 including FreeRTOS+Trace - an indispensable productivity tool, a DOS 00054 compatible FAT file system, and our tiny thread aware UDP/IP stack. 00055 00056 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 00057 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 00058 00059 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 00060 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 00061 licenses offer ticketed support, indemnification and commercial middleware. 00062 00063 http://www.SafeRTOS.com - High Integrity Systems also provide a safety 00064 engineered and independently SIL3 certified version for use in safety and 00065 mission critical applications that require provable dependability. 00066 00067 1 tab == 4 spaces! 00068 */ 00069 00070 #include "FreeRTOS.h" 00071 #include "task.h" 00072 #include "croutine.h" 00073 00074 /* Remove the whole file is co-routines are not being used. */ 00075 #if( configUSE_CO_ROUTINES != 0 ) 00076 00077 /* 00078 * Some kernel aware debuggers require data to be viewed to be global, rather 00079 * than file scope. 00080 */ 00081 #ifdef portREMOVE_STATIC_QUALIFIER 00082 #define static 00083 #endif 00084 00085 00086 /* Lists for ready and blocked co-routines. --------------------*/ 00087 static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ 00088 static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ 00089 static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ 00090 static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ 00091 static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ 00092 static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ 00093 00094 /* Other file private variables. --------------------------------*/ 00095 CRCB_t * pxCurrentCoRoutine = NULL; 00096 static UBaseType_t uxTopCoRoutineReadyPriority = 0; 00097 static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; 00098 00099 /* The initial state of the co-routine when it is created. */ 00100 #define corINITIAL_STATE ( 0 ) 00101 00102 /* 00103 * Place the co-routine represented by pxCRCB into the appropriate ready queue 00104 * for the priority. It is inserted at the end of the list. 00105 * 00106 * This macro accesses the co-routine ready lists and therefore must not be 00107 * used from within an ISR. 00108 */ 00109 #define prvAddCoRoutineToReadyQueue( pxCRCB ) \ 00110 { \ 00111 if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ 00112 { \ 00113 uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ 00114 } \ 00115 vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ 00116 } 00117 00118 /* 00119 * Utility to ready all the lists used by the scheduler. This is called 00120 * automatically upon the creation of the first co-routine. 00121 */ 00122 static void prvInitialiseCoRoutineLists( void ); 00123 00124 /* 00125 * Co-routines that are readied by an interrupt cannot be placed directly into 00126 * the ready lists (there is no mutual exclusion). Instead they are placed in 00127 * in the pending ready list in order that they can later be moved to the ready 00128 * list by the co-routine scheduler. 00129 */ 00130 static void prvCheckPendingReadyList( void ); 00131 00132 /* 00133 * Macro that looks at the list of co-routines that are currently delayed to 00134 * see if any require waking. 00135 * 00136 * Co-routines are stored in the queue in the order of their wake time - 00137 * meaning once one co-routine has been found whose timer has not expired 00138 * we need not look any further down the list. 00139 */ 00140 static void prvCheckDelayedList( void ); 00141 00142 /*-----------------------------------------------------------*/ 00143 00144 BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) 00145 { 00146 BaseType_t xReturn; 00147 CRCB_t *pxCoRoutine; 00148 00149 /* Allocate the memory that will store the co-routine control block. */ 00150 pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); 00151 if( pxCoRoutine ) 00152 { 00153 /* If pxCurrentCoRoutine is NULL then this is the first co-routine to 00154 be created and the co-routine data structures need initialising. */ 00155 if( pxCurrentCoRoutine == NULL ) 00156 { 00157 pxCurrentCoRoutine = pxCoRoutine; 00158 prvInitialiseCoRoutineLists(); 00159 } 00160 00161 /* Check the priority is within limits. */ 00162 if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) 00163 { 00164 uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; 00165 } 00166 00167 /* Fill out the co-routine control block from the function parameters. */ 00168 pxCoRoutine->uxState = corINITIAL_STATE; 00169 pxCoRoutine->uxPriority = uxPriority; 00170 pxCoRoutine->uxIndex = uxIndex; 00171 pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; 00172 00173 /* Initialise all the other co-routine control block parameters. */ 00174 vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); 00175 vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); 00176 00177 /* Set the co-routine control block as a link back from the ListItem_t. 00178 This is so we can get back to the containing CRCB from a generic item 00179 in a list. */ 00180 listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); 00181 listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); 00182 00183 /* Event lists are always in priority order. */ 00184 listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); 00185 00186 /* Now the co-routine has been initialised it can be added to the ready 00187 list at the correct priority. */ 00188 prvAddCoRoutineToReadyQueue( pxCoRoutine ); 00189 00190 xReturn = pdPASS; 00191 } 00192 else 00193 { 00194 xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; 00195 } 00196 00197 return xReturn; 00198 } 00199 /*-----------------------------------------------------------*/ 00200 00201 void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) 00202 { 00203 TickType_t xTimeToWake; 00204 00205 /* Calculate the time to wake - this may overflow but this is 00206 not a problem. */ 00207 xTimeToWake = xCoRoutineTickCount + xTicksToDelay; 00208 00209 /* We must remove ourselves from the ready list before adding 00210 ourselves to the blocked list as the same list item is used for 00211 both lists. */ 00212 ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 00213 00214 /* The list item will be inserted in wake time order. */ 00215 listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); 00216 00217 if( xTimeToWake < xCoRoutineTickCount ) 00218 { 00219 /* Wake time has overflowed. Place this item in the 00220 overflow list. */ 00221 vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 00222 } 00223 else 00224 { 00225 /* The wake time has not overflowed, so we can use the 00226 current block list. */ 00227 vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); 00228 } 00229 00230 if( pxEventList ) 00231 { 00232 /* Also add the co-routine to an event list. If this is done then the 00233 function must be called with interrupts disabled. */ 00234 vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); 00235 } 00236 } 00237 /*-----------------------------------------------------------*/ 00238 00239 static void prvCheckPendingReadyList( void ) 00240 { 00241 /* Are there any co-routines waiting to get moved to the ready list? These 00242 are co-routines that have been readied by an ISR. The ISR cannot access 00243 the ready lists itself. */ 00244 while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) 00245 { 00246 CRCB_t *pxUnblockedCRCB; 00247 00248 /* The pending ready list can be accessed by an ISR. */ 00249 portDISABLE_INTERRUPTS(); 00250 { 00251 pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); 00252 ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); 00253 } 00254 portENABLE_INTERRUPTS(); 00255 00256 ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); 00257 prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); 00258 } 00259 } 00260 /*-----------------------------------------------------------*/ 00261 00262 static void prvCheckDelayedList( void ) 00263 { 00264 CRCB_t *pxCRCB; 00265 00266 xPassedTicks = xTaskGetTickCount() - xLastTickCount; 00267 while( xPassedTicks ) 00268 { 00269 xCoRoutineTickCount++; 00270 xPassedTicks--; 00271 00272 /* If the tick count has overflowed we need to swap the ready lists. */ 00273 if( xCoRoutineTickCount == 0 ) 00274 { 00275 List_t * pxTemp; 00276 00277 /* Tick count has overflowed so we need to swap the delay lists. If there are 00278 any items in pxDelayedCoRoutineList here then there is an error! */ 00279 pxTemp = pxDelayedCoRoutineList; 00280 pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; 00281 pxOverflowDelayedCoRoutineList = pxTemp; 00282 } 00283 00284 /* See if this tick has made a timeout expire. */ 00285 while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) 00286 { 00287 pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); 00288 00289 if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) 00290 { 00291 /* Timeout not yet expired. */ 00292 break; 00293 } 00294 00295 portDISABLE_INTERRUPTS(); 00296 { 00297 /* The event could have occurred just before this critical 00298 section. If this is the case then the generic list item will 00299 have been moved to the pending ready list and the following 00300 line is still valid. Also the pvContainer parameter will have 00301 been set to NULL so the following lines are also valid. */ 00302 ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); 00303 00304 /* Is the co-routine waiting on an event also? */ 00305 if( pxCRCB->xEventListItem.pvContainer ) 00306 { 00307 ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); 00308 } 00309 } 00310 portENABLE_INTERRUPTS(); 00311 00312 prvAddCoRoutineToReadyQueue( pxCRCB ); 00313 } 00314 } 00315 00316 xLastTickCount = xCoRoutineTickCount; 00317 } 00318 /*-----------------------------------------------------------*/ 00319 00320 void vCoRoutineSchedule( void ) 00321 { 00322 /* See if any co-routines readied by events need moving to the ready lists. */ 00323 prvCheckPendingReadyList(); 00324 00325 /* See if any delayed co-routines have timed out. */ 00326 prvCheckDelayedList(); 00327 00328 /* Find the highest priority queue that contains ready co-routines. */ 00329 while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) 00330 { 00331 if( uxTopCoRoutineReadyPriority == 0 ) 00332 { 00333 /* No more co-routines to check. */ 00334 return; 00335 } 00336 --uxTopCoRoutineReadyPriority; 00337 } 00338 00339 /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines 00340 of the same priority get an equal share of the processor time. */ 00341 listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); 00342 00343 /* Call the co-routine. */ 00344 ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); 00345 00346 return; 00347 } 00348 /*-----------------------------------------------------------*/ 00349 00350 static void prvInitialiseCoRoutineLists( void ) 00351 { 00352 UBaseType_t uxPriority; 00353 00354 for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) 00355 { 00356 vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); 00357 } 00358 00359 vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); 00360 vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); 00361 vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); 00362 00363 /* Start with pxDelayedCoRoutineList using list1 and the 00364 pxOverflowDelayedCoRoutineList using list2. */ 00365 pxDelayedCoRoutineList = &xDelayedCoRoutineList1; 00366 pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; 00367 } 00368 /*-----------------------------------------------------------*/ 00369 00370 BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) 00371 { 00372 CRCB_t *pxUnblockedCRCB; 00373 BaseType_t xReturn; 00374 00375 /* This function is called from within an interrupt. It can only access 00376 event lists and the pending ready list. This function assumes that a 00377 check has already been made to ensure pxEventList is not empty. */ 00378 pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); 00379 ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); 00380 vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); 00381 00382 if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) 00383 { 00384 xReturn = pdTRUE; 00385 } 00386 else 00387 { 00388 xReturn = pdFALSE; 00389 } 00390 00391 return xReturn; 00392 } 00393 00394 #endif /* configUSE_CO_ROUTINES == 0 */ 00395 00396
Generated on Tue Jul 12 2022 22:22:38 by 1.7.2