Quellcode durchsuchen

Merge branch 'workaround/pin_noaffinity_task_to_core_when_fpu_used' into 'master'

Workaround: Automatically pin no-cpu-affinity task to a core when FPU is used

FPU status at the moment does not migrate cleanly between cores, so tasks without affinity that happen to migrate across FPUs will run into problems. As a workaround, this modification will automatically pin the task to the current CPU when FPU activity is detected. If anything, it's better than getting all kinds of weird and wonderful FPU corruption issues...

See merge request !124

Jeroen Domburg vor 9 Jahren
Ursprung
Commit
0383bc8599

+ 6 - 0
components/freertos/include/freertos/task.h

@@ -1979,6 +1979,12 @@ BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcN
  */
  */
 UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 
 
+
+/*
+ * Get the current core affinity of a task
+ */
+BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
+
 /*
 /*
  * Set the uxTaskNumber of the task referenced by the xTask parameter to
  * Set the uxTaskNumber of the task referenced by the xTask parameter to
  * uxHandle.
  * uxHandle.

+ 13 - 1
components/freertos/tasks.c

@@ -160,7 +160,7 @@ typedef struct tskTaskControlBlock
 	StackType_t			*pxStack;			/*< Points to the start of the stack. */
 	StackType_t			*pxStack;			/*< Points to the start of the stack. */
 	char				pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 	char				pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 	BaseType_t			xCoreID;			/*< Core this task is pinned to */
 	BaseType_t			xCoreID;			/*< Core this task is pinned to */
-
+											/* If this moves around (other than pcTaskName size changes), please change the define in xtensa_vectors.S as well. */
 	#if ( portSTACK_GROWTH > 0 )
 	#if ( portSTACK_GROWTH > 0 )
 		StackType_t		*pxEndOfStack;		/*< Points to the end of the stack on architectures where the stack grows up from low memory. */
 		StackType_t		*pxEndOfStack;		/*< Points to the end of the stack on architectures where the stack grows up from low memory. */
 	#endif
 	#endif
@@ -3339,6 +3339,18 @@ TCB_t *pxNewTCB;
 }
 }
 /*-----------------------------------------------------------*/
 /*-----------------------------------------------------------*/
 
 
+BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
+{
+	TCB_t *pxTCB;
+	UBaseType_t uxReturn;
+
+	pxTCB = prvGetTCBFromHandle( xTask );
+
+	return pxTCB->xCoreID;
+}
+/*-----------------------------------------------------------*/
+
+
 #if ( configUSE_TRACE_FACILITY == 1 )
 #if ( configUSE_TRACE_FACILITY == 1 )
 
 
 	static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState )
 	static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState )

+ 20 - 0
components/freertos/xtensa_vectors.S

@@ -92,6 +92,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 #include "xtensa_rtos.h"
 #include "xtensa_rtos.h"
 
 
+/*
+  Define for workaround: pin no-cpu-affinity tasks to a cpu when fpu is used.
+  Please change this when the tcb structure is changed
+*/
+#define TASKTCB_XCOREID_OFFSET (0x3C+configMAX_TASK_NAME_LEN+3)&~3
+.extern pxCurrentTCB
 
 
 /* Enable stack backtrace across exception/interrupt - see below */
 /* Enable stack backtrace across exception/interrupt - see below */
 #define XT_DEBUG_BACKTRACE    0
 #define XT_DEBUG_BACKTRACE    0
@@ -892,6 +898,20 @@ _xt_coproc_exc:
     addx4   a0, a5, a0                      /* a0 = &_xt_coproc_mask[n] */
     addx4   a0, a5, a0                      /* a0 = &_xt_coproc_mask[n] */
     l32i    a0, a0, 0                       /* a0 = (n << 16) | (1 << n) */
     l32i    a0, a0, 0                       /* a0 = (n << 16) | (1 << n) */
 
 
+    /* TODO: Remove this as soon as coprocessor state moving works across cores - JD */
+    /* FPU operations are incompatible with non-pinned tasks. If we have a FPU operation
+       here, to keep the entire thing from crashing, it's better to pin the task to whatever
+       core we're running on now. */
+    movi    a2, pxCurrentTCB
+    getcoreid a3
+    slli    a3,  a3, 2
+    add     a2,  a2, a3
+    l32i    a2, a2, 0                       /* a2 = start of pxCurrentTCB[cpuid] */
+    addi    a2, a2, TASKTCB_XCOREID_OFFSET  /* offset to xCoreID in tcb struct */
+    getcoreid a3
+    s32i    a3, a2, 0                       /* store current cpuid */
+
+	/* Grab correct xt_coproc_owner_sa for this core */
 	getcoreid a2
 	getcoreid a2
 	movi    a3, XCHAL_CP_MAX << 2
 	movi    a3, XCHAL_CP_MAX << 2
 	mull    a2, a2, a3
 	mull    a2, a2, a3