]> granicus.if.org Git - esp-idf/commitdiff
Merge latest master in
authorJeroen Domburg <git@j0h.nl>
Thu, 27 Oct 2016 08:18:55 +0000 (16:18 +0800)
committerJeroen Domburg <git@j0h.nl>
Thu, 27 Oct 2016 08:18:55 +0000 (16:18 +0800)
1  2 
components/freertos/Kconfig
components/freertos/include/freertos/FreeRTOSConfig.h
components/freertos/include/freertos/portable.h
components/freertos/tasks.c

index 881c7616f38be2e8c5071bf4bf63b63f07c170f6,1a65e1eeb7eb52834867504f29d458d2444a8a7c..e821d7445b6524cb67703d84e238f92cdb7629e7
@@@ -172,6 -172,6 +172,14 @@@ menuconfig ENABLE_MEMORY_DEBU
      help
          Enable this option to show malloc heap block and memory crash detect
  
++config FREERTOS_ISR_STACKSIZE
++    int "ISR stack size"
++    range 1536 32768
++    default 1536
++    help
++        The interrupt handlers have their own stack. The size of the stack can be defined here. 
++        Each processor has its own stack, so the total size occupied will be twice this.
++
  menuconfig FREERTOS_DEBUG_INTERNALS
      bool "Debug FreeRTOS internals"
      default n
@@@ -197,15 -197,6 +205,8 @@@ config FREERTOS_PORTMUX_DEBUG_RECURSIV
          If enabled, additional debug information will be printed for recursive
          portMUX usage.
  
- config FREERTOS_ISR_STACKSIZE
-     int "ISR stack size"
-     range 1536 32768
-     default 1536
-     help
-         The interrupt handlers have their own stack. The size of the stack can be defined here. 
-         Each processor has its own stack, so the total size occupied will be twice this.
 +
 +
  endif # FREERTOS_DEBUG_INTERNALS
  
  endmenu
index 82b97fe268a9a416e8d438ceb97c906b125f0667,386401904a2537e30357218563e9a2998eed67d9..3cdca4d43318e76edf828d58ce2a56c280436950
@@@ -584,70 -613,160 +616,188 @@@ static void prvAddNewTaskToReadyList( T
  
  /*-----------------------------------------------------------*/
  
 +/*
 + * This routine tries to send an interrupt to another core if needed to make it execute a task
 + * of higher priority. We try to figure out if needed first by inspecting the pxTCB of the 
 + * other CPU first. Specifically for Xtensa, we can do this because pxTCB is an atomic pointer. It
 + * is possible that it is inaccurate because the other CPU just did a task switch, but in that case
 + * at most a superfluous interrupt is generated.
 +*/
 +void taskYIELD_OTHER_CORE( BaseType_t xCoreID, UBaseType_t uxPriority )
 +{
 +      BaseType_t i;
 +      if (xCoreID != tskNO_AFFINITY) {
 +              if ( pxCurrentTCB[ xCoreID ]->uxPriority < uxPriority ) {
 +                      vPortYieldOtherCore( xCoreID );
 +              }
 +      }
 +      else
 +      {
 +              /* The task has no affinity. See if we can find a CPU to put it on.*/
 +              for (i=0; i<portNUM_PROCESSORS; i++) {
 +                      if (i != xPortGetCoreID() && pxCurrentTCB[ i ]->uxPriority < uxPriority)
 +                      {
 +                              vPortYieldOtherCore( i );
 +                              break;
 +                      }
 +              }
 +      }
 +}
 +
+ #if( configSUPPORT_STATIC_ALLOCATION == 1 )
  
- BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions, const BaseType_t xCoreID) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
- {
- BaseType_t xReturn;
- TCB_t * pxNewTCB;
- StackType_t *pxTopOfStack;
- BaseType_t i;
-       configASSERT( pxTaskCode );
-       configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) );
-       configASSERT( (xCoreID>=0 && xCoreID<portNUM_PROCESSORS) || (xCoreID==tskNO_AFFINITY) );
+       TaskHandle_t xTaskCreateStaticPinnedToCore(     TaskFunction_t pxTaskCode,
+                                                                       const char * const pcName,
+                                                                       const uint32_t ulStackDepth,
+                                                                       void * const pvParameters,
+                                                                       UBaseType_t uxPriority,
+                                                                       StackType_t * const puxStackBuffer,
+                                                                       StaticTask_t * const pxTaskBuffer,
+                                     const BaseType_t xCoreID )
+       {
+       TCB_t *pxNewTCB;
+       TaskHandle_t xReturn;
  
-       /* Allocate the memory required by the TCB and stack for the new task,
-       checking that the allocation was successful. */
-       pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
+               configASSERT( puxStackBuffer != NULL );
+               configASSERT( pxTaskBuffer != NULL );
+               configASSERT( (xCoreID>=0 && xCoreID<portNUM_PROCESSORS) || (xCoreID==tskNO_AFFINITY) );
  
-       if( pxNewTCB != NULL )
+               if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )
+               {
+                       /* The memory used for the task's TCB and stack are passed into this
+                       function - use them. */
+                       pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
+                       pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer;
+                       #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
+                       {
+                               /* Tasks can be created statically or dynamically, so note this
+                               task was created statically in case the task is later deleted. */
+                               pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;
+                       }
+                       #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
+                       prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL, xCoreID );
+                       prvAddNewTaskToReadyList( pxNewTCB, pxTaskCode, xCoreID );
+               }
+               else
+               {
+                       xReturn = NULL;
+               }
+               return xReturn;
+       }
+ #endif /* SUPPORT_STATIC_ALLOCATION */
+ /*-----------------------------------------------------------*/
+ #if( portUSING_MPU_WRAPPERS == 1 )
+       BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask )
        {
-               #if( portUSING_MPU_WRAPPERS == 1 )
-                       /* Should the task be created in privileged mode? */
-                       BaseType_t xRunPrivileged;
-                       if( ( uxPriority & portPRIVILEGE_BIT ) != 0U )
+       TCB_t *pxNewTCB;
+       BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
+               configASSERT( pxTaskDefinition->puxStackBuffer );
+               if( pxTaskDefinition->puxStackBuffer != NULL )
+               {
+                       /* Allocate space for the TCB.  Where the memory comes from depends
+                       on the implementation of the port malloc function and whether or
+                       not static allocation is being used. */
+                       pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
+                       if( pxNewTCB != NULL )
                        {
-                               xRunPrivileged = pdTRUE;
+                               /* Store the stack location in the TCB. */
+                               pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer;
+                               /* Tasks can be created statically or dynamically, so note
+                               this task had a statically allocated stack in case it is
+                               later deleted.  The TCB was allocated dynamically. */
+                               pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY;
+                               prvInitialiseNewTask(   pxTaskDefinition->pvTaskCode,
+                                                                               pxTaskDefinition->pcName,
+                                                                               ( uint32_t ) pxTaskDefinition->usStackDepth,
+                                                                               pxTaskDefinition->pvParameters,
+                                                                               pxTaskDefinition->uxPriority,
+                                                                               pxCreatedTask, pxNewTCB,
+                                                                               pxTaskDefinition->xRegions,
+                                                                               tskNO_AFFINITY );
+                               prvAddNewTaskToReadyList( pxNewTCB, pxTaskDefinition->pvTaskCode, tskNO_AFFINITY );
+                               xReturn = pdPASS;
                        }
-                       else
+               }
+               return xReturn;
+       }
+ #endif /* portUSING_MPU_WRAPPERS */
+ /*-----------------------------------------------------------*/
+ #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+       BaseType_t xTaskCreatePinnedToCore(     TaskFunction_t pxTaskCode,
+                                                       const char * const pcName,
+                                                       const uint16_t usStackDepth,
+                                                       void * const pvParameters,
+                                                       UBaseType_t uxPriority,
+                                                       TaskHandle_t * const pxCreatedTask,
+                             const BaseType_t xCoreID )
+       {
+       TCB_t *pxNewTCB;
+       BaseType_t xReturn;
+               /* If the stack grows down then allocate the stack then the TCB so the stack
+               does not grow into the TCB.  Likewise if the stack grows up then allocate
+               the TCB then the stack. */
+               #if( portSTACK_GROWTH > 0 )
+               {
+                       /* Allocate space for the TCB.  Where the memory comes from depends on
+                       the implementation of the port malloc function and whether or not static
+                       allocation is being used. */
+                       pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
+                       if( pxNewTCB != NULL )
                        {
-                               xRunPrivileged = pdFALSE;
+                               /* Allocate space for the stack used by the task being created.
+                               The base of the stack memory stored in the TCB so the task can
+                               be deleted later if required. */
+                               pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
+                               if( pxNewTCB->pxStack == NULL )
+                               {
+                                       /* Could not allocate the stack.  Delete the allocated TCB. */
+                                       vPortFree( pxNewTCB );
+                                       pxNewTCB = NULL;
+                               }
                        }
-                       uxPriority &= ~portPRIVILEGE_BIT;
+               }
+               #else /* portSTACK_GROWTH */
+               {
+               StackType_t *pxStack;
+                       /* Allocate space for the stack used by the task being created. */
+                       pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
  
-                       if( puxStackBuffer != NULL )
+                       if( pxStack != NULL )
                        {
-                               /* The application provided its own stack.  Note this so no
-                               attempt is made to delete the stack should that task be
-                               deleted. */
-                               pxNewTCB->xUsingStaticallyAllocatedStack = pdTRUE;
+                               /* Allocate space for the TCB. */
+                               pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */
+                               if( pxNewTCB != NULL )
+                               {
+                                       /* Store the stack location in the TCB. */
+                                       pxNewTCB->pxStack = pxStack;
+                               }
+                               else
+                               {
+                                       /* The stack cannot be used as the TCB was not created.  Free
+                                       it again. */
+                                       vPortFree( pxStack );
+                               }
                        }
                        else
                        {
@@@ -751,49 -1059,35 +1090,49 @@@ static void prvAddNewTaskToReadyList( T
                        {
                                mtCOVERAGE_TEST_MARKER();
                        }
+               }
  
-                       uxTaskNumber++;
+               uxTaskNumber++;
  
-                       #if ( configUSE_TRACE_FACILITY == 1 )
-                       {
-                               /* Add a counter into the TCB for tracing only. */
-                               pxNewTCB->uxTCBNumber = uxTaskNumber;
-                       }
-                       #endif /* configUSE_TRACE_FACILITY */
-                       traceTASK_CREATE( pxNewTCB );
+               #if ( configUSE_TRACE_FACILITY == 1 )
+               {
+                       /* Add a counter into the TCB for tracing only. */
+                       pxNewTCB->uxTCBNumber = uxTaskNumber;
+               }
+               #endif /* configUSE_TRACE_FACILITY */
+               traceTASK_CREATE( pxNewTCB );
  
-                       prvAddTaskToReadyList( pxNewTCB );
+               prvAddTaskToReadyList( pxNewTCB );
  
-                       xReturn = pdPASS;
-                       portSETUP_TCB( pxNewTCB );
-               }
-               taskEXIT_CRITICAL(&xTaskQueueMutex);
-       }
-       else
-       {
-               xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
-               traceTASK_CREATE_FAILED();
+               portSETUP_TCB( pxNewTCB );
        }
+       taskEXIT_CRITICAL(&xTaskQueueMutex);
  
-       if( xReturn == pdPASS )
+       if( xSchedulerRunning != pdFALSE )
        {
-               if( xSchedulerRunning != pdFALSE )
+               /* Scheduler is running. If the created task is of a higher priority than an executing task
+              then it should run now.
+                  ToDo: This only works for the current core. If a task is scheduled on an other processor,
+                  the other processor will keep running the task it's working on, and only switch to the newer 
+                  task on a timer interrupt. */
+               //No mux here, uxPriority is mostly atomic and there's not really any harm if this check misfires.
+               if( pxCurrentTCB[ xPortGetCoreID() ]->uxPriority < pxNewTCB->uxPriority )
                {
 -                      taskYIELD_IF_USING_PREEMPTION();
 +                      /* Scheduler is running. If the created task is of a higher priority than an executing task
 +                        then it should run now.
 +                        No mux here, uxPriority is mostly atomic and there's not really any harm if this check misfires.
 +                      */
-                       if( tskCAN_RUN_HERE( xCoreID ) && pxCurrentTCB[ xPortGetCoreID() ]->uxPriority < uxPriority )
++                      if( tskCAN_RUN_HERE( xCoreID ) && pxCurrentTCB[ xPortGetCoreID() ]->uxPriority < pxNewTCB->uxPriority )
 +                      {
 +                              taskYIELD_IF_USING_PREEMPTION();
 +                      }
 +                      else if( xCoreID != xPortGetCoreID() ) {
-                               taskYIELD_OTHER_CORE(xCoreID, uxPriority);
++                              taskYIELD_OTHER_CORE(xCoreID, pxNewTCB->uxPriority);
 +                      }
 +                      else
 +                      {
 +                              mtCOVERAGE_TEST_MARKER();
 +                      }
                }
                else
                {