1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-27 16:54:15 +01:00

More work on osx simulation engine

This commit is contained in:
James Cotton 2012-03-12 20:12:56 -05:00
parent 3c0b65fbf8
commit 51f0c3453b
6 changed files with 250 additions and 39 deletions

View File

@ -1267,6 +1267,8 @@ void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUN
*/ */
signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION; signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION;
void printTasks();
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -89,6 +89,8 @@ typedef struct XPARAMS
void *pvParams; void *pvParams;
} xParams; } xParams;
enum thread_status {RUNNING, INTERRUPTED, STOPPED};
/* Each task maintains its own interrupt status in the critical nesting variable. */ /* Each task maintains its own interrupt status in the critical nesting variable. */
typedef struct THREAD_SUSPENSIONS typedef struct THREAD_SUSPENSIONS
{ {
@ -97,11 +99,12 @@ typedef struct THREAD_SUSPENSIONS
pthread_mutex_t * hMutex; pthread_mutex_t * hMutex;
xTaskHandle hTask; xTaskHandle hTask;
portBASE_TYPE xThreadState; portBASE_TYPE xThreadState;
enum thread_status status;
unsigned portBASE_TYPE uxCriticalNesting; unsigned portBASE_TYPE uxCriticalNesting;
} xThreadState; } xThreadState;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static xThreadState *pxThreads; static xThreadState pxThreads[MAX_NUMBER_OF_TASKS];
static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT; static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT;
static pthread_attr_t xThreadAttributes; static pthread_attr_t xThreadAttributes;
#ifdef RUNNING_THREAD_MUTEX #ifdef RUNNING_THREAD_MUTEX
@ -109,7 +112,7 @@ static pthread_mutex_t xRunningThread = PTHREAD_MUTEX_INITIALIZER;
#endif #endif
static pthread_mutex_t xSuspendResumeThreadMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t xSuspendResumeThreadMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t xSwappingThreadMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t xSwappingThreadMutex = PTHREAD_MUTEX_INITIALIZER;
//static pthread_mutex_t xIrqMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t xIrqMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t hMainThread = ( pthread_t )NULL; static pthread_t hMainThread = ( pthread_t )NULL;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -119,7 +122,7 @@ static volatile portBASE_TYPE xSuspended = pdFALSE;
static volatile portBASE_TYPE xStarted = pdFALSE; static volatile portBASE_TYPE xStarted = pdFALSE;
static volatile portBASE_TYPE xHandover = 0; static volatile portBASE_TYPE xHandover = 0;
static volatile portBASE_TYPE xSchedulerEnd = pdFALSE; static volatile portBASE_TYPE xSchedulerEnd = pdFALSE;
static volatile portBASE_TYPE xInterruptsEnabled = pdTRUE; volatile portBASE_TYPE xInterruptsEnabled = pdTRUE;
static volatile portBASE_TYPE xServicingTick = pdFALSE; static volatile portBASE_TYPE xServicingTick = pdFALSE;
static volatile portBASE_TYPE xPendYield = pdFALSE; static volatile portBASE_TYPE xPendYield = pdFALSE;
static volatile portLONG lIndexOfLastAddedTask = 0; static volatile portLONG lIndexOfLastAddedTask = 0;
@ -139,6 +142,7 @@ static pthread_cond_t * prvGetConditionHandle( xTaskHandle hTask );
static pthread_mutex_t * prvGetMutexHandle( xTaskHandle hTask ); static pthread_mutex_t * prvGetMutexHandle( xTaskHandle hTask );
#endif #endif
static xTaskHandle prvGetTaskHandle( pthread_t hThread ); static xTaskHandle prvGetTaskHandle( pthread_t hThread );
static void prvSetThreadStatus( pthread_t hThread, enum thread_status status );
static portLONG prvGetFreeThreadState( void ); static portLONG prvGetFreeThreadState( void );
static void prvSetTaskCriticalNesting( pthread_t xThreadId, unsigned portBASE_TYPE uxNesting ); static void prvSetTaskCriticalNesting( pthread_t xThreadId, unsigned portBASE_TYPE uxNesting );
static unsigned portBASE_TYPE prvGetTaskCriticalNesting( pthread_t xThreadId ); static unsigned portBASE_TYPE prvGetTaskCriticalNesting( pthread_t xThreadId );
@ -339,6 +343,9 @@ portBASE_TYPE xResult;
sigset_t xSignalToBlock; sigset_t xSignalToBlock;
portLONG lIndex; portLONG lIndex;
fid = fopen("log.txt", "w");
debug_printf( "xPortStartScheduler\r\n" ); debug_printf( "xPortStartScheduler\r\n" );
/* Establish the signals to block before they are needed. */ /* Establish the signals to block before they are needed. */
@ -353,15 +360,17 @@ portLONG lIndex;
pxThreads[ lIndex ].uxCriticalNesting = 0; pxThreads[ lIndex ].uxCriticalNesting = 0;
} }
fid = fopen("log.txt", "w");
/* Start the first task. Will not return unless all threads are killed. */ /* Start the first task. Will not return unless all threads are killed. */
vPortStartFirstTask(); vPortStartFirstTask();
usleep(1000000); usleep(1000000);
int i = 0;
while( pdTRUE != xSchedulerEnd ) { while( pdTRUE != xSchedulerEnd ) {
usleep(portTICK_RATE_MICROSECONDS); usleep(portTICK_RATE_MICROSECONDS);
vPortSystemTickHandler(SIG_TICK); vPortSystemTickHandler(SIG_TICK);
i++;
//if (i % 2000 == 0)
// printTasks();
} }
debug_printf( "Cleaning Up, Exiting.\n" ); debug_printf( "Cleaning Up, Exiting.\n" );
@ -429,13 +438,14 @@ void vPortExitCritical( void )
if ( pdTRUE == xPendYield ) if ( pdTRUE == xPendYield )
{ {
xPendYield = pdFALSE; xPendYield = pdFALSE;
vPortYield(); // vPortYield();
} }
vPortEnableInterrupts(); vPortEnableInterrupts();
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
tskTCB *lastYield;
void vPortYield( void ) void vPortYield( void )
{ {
pthread_t xTaskToSuspend; pthread_t xTaskToSuspend;
@ -470,6 +480,7 @@ tskTCB * oldTask, * newTask;
return; return;
} }
lastYield = oldTask;
xStarted = pdFALSE; xStarted = pdFALSE;
/* Get new task then release the task switching mutex */ /* Get new task then release the task switching mutex */
@ -511,21 +522,50 @@ tskTCB * oldTask, * newTask;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void maskSuspend()
{
sigset_t xSignals;
sigemptyset( &xSignals );
sigaddset( &xSignals, SIG_SUSPEND );
pthread_sigmask( SIG_SETMASK, &xSignals, NULL );
}
void unmaskSuspend()
{
sigset_t xSignals;
sigemptyset( &xSignals );
pthread_sigmask( SIG_SETMASK, &xSignals, NULL );
}
int irq_lock;
void vPortDisableInterrupts( void ) void vPortDisableInterrupts( void )
{ {
//debug_printf("\r\n"); //debug_printf("\r\n");
//assert( pthread_mutex_lock( &xIrqMutex ) == 0); maskSuspend();
irq_lock = 1;
assert( pthread_mutex_lock( &xIrqMutex ) == 0);
xInterruptsEnabled = pdFALSE; xInterruptsEnabled = pdFALSE;
//assert( pthread_mutex_unlock( &xIrqMutex) == 0); assert( pthread_mutex_unlock( &xIrqMutex) == 0);
irq_lock = 0;
unmaskSuspend();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/**
* Obvious the simulated interrupts status must be thread safe.
* This means we also must mask these threads ever being suspended
* while they have the irqMutex.
*/
void vPortEnableInterrupts( void ) void vPortEnableInterrupts( void )
{ {
//debug_printf("\r\n"); //debug_printf("\r\n");
//assert( pthread_mutex_lock( &xIrqMutex ) == 0); maskSuspend();
irq_lock = 1;
assert( pthread_mutex_lock( &xIrqMutex ) == 0);
xInterruptsEnabled = pdTRUE; xInterruptsEnabled = pdTRUE;
//assert( pthread_mutex_unlock( &xIrqMutex) == 0); assert( pthread_mutex_unlock( &xIrqMutex) == 0);
irq_lock = 0;
unmaskSuspend();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -546,32 +586,38 @@ void vPortClearInterruptMask( portBASE_TYPE xMask )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
tskTCB * oldTask, * newTask;
void vPortSystemTickHandler( int sig ) void vPortSystemTickHandler( int sig )
{ {
pthread_t xTaskToSuspend; pthread_t xTaskToSuspend;
pthread_t xTaskToResume; pthread_t xTaskToResume;
tskTCB * oldTask, * newTask;
debug_printf( "\r\n\r\n" ); debug_printf( "\r\n\r\n" );
debug_printf( "(xInterruptsEnabled = %i, xServicingTick = %i)\r\n", (int) xInterruptsEnabled != 0, (int) xServicingTick != 0); debug_printf( "(xInterruptsEnabled = %i, xServicingTick = %i)\r\n", (int) xInterruptsEnabled != 0, (int) xServicingTick != 0);
/* Tick Increment. */
vTaskIncrementTick();
if (pthread_mutex_trylock( &xIrqMutex ) == EBUSY) {
fprintf(stderr, "Systick could not block interrupts\r\n");
return;
}
if ( ( pdTRUE == xInterruptsEnabled ) && ( pdTRUE != xServicingTick ) ) if ( ( pdTRUE == xInterruptsEnabled ) && ( pdTRUE != xServicingTick ) )
{ {
// debug_printf( "Checking for lock ...\r\n" ); // debug_printf( "Checking for lock ...\r\n" );
if ( 0 == pthread_mutex_trylock( &xSwappingThreadMutex ) ) if ( 0 == pthread_mutex_trylock( &xSwappingThreadMutex ) )
{ {
/* Select Next Task. */
#if ( configUSE_PREEMPTION == 1 )
debug_printf( "Handling\r\n"); debug_printf( "Handling\r\n");
xServicingTick = pdTRUE; xServicingTick = pdTRUE;
oldTask = xTaskGetCurrentTaskHandle(); oldTask = xTaskGetCurrentTaskHandle();
xTaskToSuspend = prvGetThreadHandle( xTaskGetCurrentTaskHandle() ); xTaskToSuspend = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
/* Tick Increment. */
vTaskIncrementTick();
/* Select Next Task. */
#if ( configUSE_PREEMPTION == 1 )
vTaskSwitchContext(); vTaskSwitchContext();
#endif
newTask = xTaskGetCurrentTaskHandle(); newTask = xTaskGetCurrentTaskHandle();
xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() ); xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
@ -580,6 +626,7 @@ tskTCB * oldTask, * newTask;
/* The only thread that can process this tick is the running thread. */ /* The only thread that can process this tick is the running thread. */
if ( xTaskToSuspend != xTaskToResume ) if ( xTaskToSuspend != xTaskToResume )
{ {
//fprintf(stderr,"Suspending: %s\r\n", oldTask->pcTaskName);
xSuspended = pdFALSE; xSuspended = pdFALSE;
xStarted = pdFALSE; xStarted = pdFALSE;
@ -609,7 +656,7 @@ tskTCB * oldTask, * newTask;
pthread_cond_t * hCond = prvGetConditionHandle( xTaskGetCurrentTaskHandle() ); pthread_cond_t * hCond = prvGetConditionHandle( xTaskGetCurrentTaskHandle() );
assert( pthread_cond_signal( hCond ) == 0 ); assert( pthread_cond_signal( hCond ) == 0 );
#endif #endif
assert( pthread_kill( xTaskToSuspend, SIG_SUSPEND ) == 0); //assert( pthread_kill( xTaskToSuspend, SIG_SUSPEND ) == 0);
sched_yield(); sched_yield();
} }
@ -619,21 +666,22 @@ tskTCB * oldTask, * newTask;
{ {
// debug_error ("Want %s running \r\n", newTask->pcTaskName ); // debug_error ("Want %s running \r\n", newTask->pcTaskName );
} }
#endif configUSE_PREEMPTION
xServicingTick = pdFALSE; xServicingTick = pdFALSE;
(void)pthread_mutex_unlock( &xSwappingThreadMutex ); (void)pthread_mutex_unlock( &xSwappingThreadMutex );
} }
else else
{ {
fprintf(stderr, "Cannot get swap thread mutex\r\n");
debug_error( "Pending yield here (portYield has lock - hopefully)\r\n" ); debug_error( "Pending yield here (portYield has lock - hopefully)\r\n" );
xPendYield = pdTRUE; xPendYield = pdTRUE;
} }
} }
else
{ assert( pthread_mutex_unlock( &xIrqMutex) == 0);
debug_printf( "Pending yield or here\r\n");
xPendYield = pdTRUE;
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -733,6 +781,8 @@ void * pParams = pxParams->pvParams;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
extern volatile unsigned portBASE_TYPE uxSchedulerSuspended;
void pauseThread( portBASE_TYPE pauseMode ) void pauseThread( portBASE_TYPE pauseMode )
{ {
debug_printf( "Pausing thread %li. Set xSuspended false\r\n", (long int) pthread_self() ); debug_printf( "Pausing thread %li. Set xSuspended false\r\n", (long int) pthread_self() );
@ -770,15 +820,52 @@ void pauseThread( portBASE_TYPE pauseMode )
assert( 0 == pthread_mutex_lock( &xRunningThread ) ); assert( 0 == pthread_mutex_lock( &xRunningThread ) );
#endif #endif
debug_printf("Resuming\r\n"); debug_printf("Resuming\r\n");
prvSetThreadStatus( pthread_self(), RUNNING );
return; return;
} }
else { else {
if(pauseMode == THREAD_PAUSE_INTERRUPT)
prvSetThreadStatus( pthread_self(), INTERRUPTED );
else
prvSetThreadStatus( pthread_self(), STOPPED );
if( uxSchedulerSuspended != 0) {
// fprintf(stderr, "This is probably a fuckup\r\n");
}
#ifdef COND_SIGNALING #ifdef COND_SIGNALING
gettimeofday( &tv, NULL ); gettimeofday( &tv, NULL );
ts.tv_sec = ts.tv_sec + 1; ts.tv_sec = tv.tv_sec + 1;
ts.tv_nsec = 0; ts.tv_nsec = tv.tv_usec * 1000;
xResult = pthread_cond_timedwait( hCond, hMutex, &ts ); xResult = pthread_cond_timedwait( hCond, hMutex, &ts );
assert( xResult != EINVAL ); assert( xResult != EINVAL );
if (xResult == ETIMEDOUT) {
debug_task_handle = prvGetTaskHandle(pthread_self());
signed char * str;
if(debug_task_handle)
str = debug_task_handle->pcTaskName;
else
str = (signed char *) "Unknown";
if(pthread_self() == prvGetThreadHandle(xTaskGetCurrentTaskHandle()))
fprintf(stderr,"Timed out %s and should be running\n", str);
else {
fprintf(stderr,"Timed out %s. Sould be running %s\n", str, ((tskTCB *)xTaskGetCurrentTaskHandle())->pcTaskName);
#if 0 && defined(COND_SIGNALING)
fprintf(stderr,"Resending resume signal\r\n");
/* Set resume condition for specific thread */
pthread_cond_t * hCond = prvGetConditionHandle( xTaskGetCurrentTaskHandle() );
assert( pthread_cond_signal( hCond ) == 0 );
#endif
}
printTasks();
} else {
static int i;
i ++;
//if(i % 1000 == 0)
//printTasks();
}
#else #else
/* For windows where conditional signaling is buggy */ /* For windows where conditional signaling is buggy */
/* It would be wonderful to put a nanosleep here, but since its not reentrant safe */ /* It would be wonderful to put a nanosleep here, but since its not reentrant safe */
@ -793,6 +880,7 @@ void pauseThread( portBASE_TYPE pauseMode )
} }
} }
assert(0);
} }
void prvSuspendSignalHandler(int sig) void prvSuspendSignalHandler(int sig)
@ -802,12 +890,12 @@ sigset_t xBlockSignals;
/* This signal is set here instead of pauseThread because it is checked by the tick handler */ /* This signal is set here instead of pauseThread because it is checked by the tick handler */
/* which means if there were a swap it should result in a suspend interrupt */ /* which means if there were a swap it should result in a suspend interrupt */
debug_printf( "Caught signal %i\r\n", sig ); debug_error( "Caught signal %i\r\n", sig );
/* Check that we aren't suspending when we should be running. This bug would need tracking down */ /* Check that we aren't suspending when we should be running. This bug would need tracking down */
//assert( pthread_self() != prvGetThreadHandle(xTaskGetCurrentTaskHandle() ) ); //assert( pthread_self() != prvGetThreadHandle(xTaskGetCurrentTaskHandle() ) );
if( pthread_self() == prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) ) if( pthread_self() == prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) )
{ {
debug_printf( "Suspend ISR called while this thread still marked active. Reflects buggy behavior in scheduler\r\n" ); debug_error( "Suspend ISR called while this thread still marked active. Reflects buggy behavior in scheduler. Signals %d\r\n" , sig);
return; return;
} }
@ -821,7 +909,7 @@ sigset_t xBlockSignals;
// assert( pthread_self() == prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) ); // assert( pthread_self() == prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) );
while( pthread_self() != prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) ) while( pthread_self() != prvGetThreadHandle( xTaskGetCurrentTaskHandle() ) )
{ {
debug_printf( "Incorrectly woke up. Repausing\r\n" ); debug_error( "Incorrectly woke up. Repausing\r\n" );
pauseThread( THREAD_PAUSE_INTERRUPT ); pauseThread( THREAD_PAUSE_INTERRUPT );
} }
@ -870,7 +958,7 @@ portLONG lIndex;
debug_printf("prvSetupSignalAndSchedulerPolicy\r\n"); debug_printf("prvSetupSignalAndSchedulerPolicy\r\n");
pxThreads = ( xThreadState *)pvPortMalloc( sizeof( xThreadState ) * MAX_NUMBER_OF_TASKS ); //pxThreads = ( xThreadState *)pvPortMalloc( sizeof( xThreadState ) * MAX_NUMBER_OF_TASKS );
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ ) for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{ {
pxThreads[ lIndex ].hThread = ( pthread_t )NULL; pxThreads[ lIndex ].hThread = ( pthread_t )NULL;
@ -920,7 +1008,25 @@ portLONG lIndex;
} }
} }
return hTask; return hTask;
} }
/*-----------------------------------------------------------*/
static void prvSetThreadStatus( pthread_t hThread, enum thread_status status )
{
portLONG lIndex;
/* If not initialized yet */
if( pxThreads == NULL ) return;
for ( lIndex = 0; lIndex < MAX_NUMBER_OF_TASKS; lIndex++ )
{
if ( pxThreads[ lIndex ].hThread == hThread )
{
pxThreads[ lIndex ].status = status;
break;
}
}
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
pthread_cond_t * prvGetConditionHandle( xTaskHandle hTask ) pthread_cond_t * prvGetConditionHandle( xTaskHandle hTask )

View File

@ -81,11 +81,9 @@ void *pvPortMalloc( size_t xWantedSize )
{ {
void *pvReturn; void *pvReturn;
vTaskSuspendAll();
{ {
pvReturn = malloc( xWantedSize ); pvReturn = malloc( xWantedSize );
} }
xTaskResumeAll();
#if( configUSE_MALLOC_FAILED_HOOK == 1 ) #if( configUSE_MALLOC_FAILED_HOOK == 1 )
{ {
@ -105,11 +103,9 @@ void vPortFree( void *pv )
{ {
if( pv ) if( pv )
{ {
vTaskSuspendAll();
{ {
free( pv ); free( pv );
} }
xTaskResumeAll();
} }
} }

View File

@ -59,6 +59,7 @@
#include <signal.h> #include <signal.h>
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <assert.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when all the API functions to use the MPU wrappers. That should only be done when
@ -160,7 +161,7 @@ PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType )
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY; PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY; PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE; PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE; PRIVILEGED_DATA volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;
PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0; PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0;
PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE; PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0; PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
@ -378,7 +379,6 @@ static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TY
#endif #endif
/*lint +e956 */ /*lint +e956 */
@ -1078,7 +1078,9 @@ void vTaskSuspendAll( void )
{ {
/* A critical section is not required as the variable is of type /* A critical section is not required as the variable is of type
portBASE_TYPE. */ portBASE_TYPE. */
portENTER_CRITICAL();
++uxSchedulerSuspended; ++uxSchedulerSuspended;
portEXIT_CRITICAL();
} }
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
@ -1571,12 +1573,20 @@ void vTaskIncrementTick( void )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
int missed_threshold = 100;
void vTaskSwitchContext( void ) void vTaskSwitchContext( void )
{ {
if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE ) if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE )
{ {
static int missed_count = 0;
missed_count++;
if (missed_count > missed_threshold) {
fprintf(stderr, "Missed switch\n");
}
/* The scheduler is currently suspended - do not allow a context /* The scheduler is currently suspended - do not allow a context
switch. */ switch. */
//fprintf(stderr, "Missed switch\n");
xMissedYield = pdTRUE; xMissedYield = pdTRUE;
return; return;
} }
@ -1614,6 +1624,7 @@ void vTaskSwitchContext( void )
vWriteTraceToBuffer(); vWriteTraceToBuffer();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
extern volatile portBASE_TYPE xInterruptsEnabled;
void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )
{ {
@ -1622,6 +1633,10 @@ portTickType xTimeToWake;
/* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
SCHEDULER SUSPENDED. */ SCHEDULER SUSPENDED. */
if(!(uxSchedulerSuspended == pdTRUE || xInterruptsEnabled == pdFALSE)) {
// assert(0);
fprintf(stderr,"vTaskPlaceOnEventList while scheduler enabled: %d and interrupts enabled %ld\r\n", uxSchedulerSuspended == pdFALSE, xInterruptsEnabled);
}
/* Place the event list item of the TCB in the appropriate event list. /* Place the event list item of the TCB in the appropriate event list.
This is placed in the list in priority order so the highest priority task This is placed in the list in priority order so the highest priority task
is the first to be woken by the event. */ is the first to be woken by the event. */
@ -1802,9 +1817,10 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
{ {
/* Stop warnings. */ /* Stop warnings. */
( void ) pvParameters; ( void ) pvParameters;
int i =0;
for( ;; ) for( ;; )
{ {
i++;
/* See if any tasks have been deleted. */ /* See if any tasks have been deleted. */
prvCheckTasksWaitingTermination(); prvCheckTasksWaitingTermination();
@ -2082,6 +2098,95 @@ tskTCB *pxNewTCB;
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void printNamesInList( const signed char *pcWriteBuffer, xList *pxList)
{
volatile tskTCB *pxNextTCB, *pxFirstTCB;
char pcStatsString[100];
/* Write the run time stats of all the TCB's in pxList into the buffer. */
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
do
{
/* Get next TCB in from the list. */
listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
if(pxNextTCB) {
sprintf( pcStatsString, ( char * ) "%s, ", pxNextTCB->pcTaskName);
strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString );
}
} while( pxNextTCB != pxFirstTCB );
}
void printTasks()
{
signed char pcWriteBuffer[500];
int uxQueue;
vTaskSuspendAll();
{
/* Run through all the lists that could potentially contain a TCB,
generating a table of run timer percentages in the provided
buffer. */
pcWriteBuffer[ 0 ] = ( signed char ) 0x00;
uxQueue = uxTopUsedPriority + 1;
do
{
uxQueue--;
if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )
{
char readyMessage[30];
sprintf(readyMessage, "\r\nReady priority %d: ", uxQueue);
strcat( ( char * ) pcWriteBuffer,readyMessage);
printNamesInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ));
}
}while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );
if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )
{
strcat( ( char * ) pcWriteBuffer, "\r\nDelay: ");
printNamesInList( pcWriteBuffer, ( xList * ) &( pxDelayedTaskList));
}
if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )
{
strcat( ( char * ) pcWriteBuffer, "\r\nDelay Overflow: ");
printNamesInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList);
}
if( !listLIST_IS_EMPTY( &xPendingReadyList ) )
{
strcat( ( char * ) pcWriteBuffer, "\r\nPending ready: ");
printNamesInList( pcWriteBuffer, ( xList * ) &xPendingReadyList);
}
#if ( INCLUDE_vTaskDelete == 1 )
{
if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )
{
strcat( ( char * ) pcWriteBuffer, "\r\nWaiting termination: ");
printNamesInList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination);
}
}
#endif
#if ( INCLUDE_vTaskSuspend == 1 )
{
if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )
{
strcat( ( char * ) pcWriteBuffer, "\r\nSuspended: ");
printNamesInList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList);
}
}
#endif
}
strcat( (char *) pcWriteBuffer, "\r\n\r\n");
fprintf(stderr, "%s", ( char * ) pcWriteBuffer);
xTaskResumeAll();
}
#if ( configGENERATE_RUN_TIME_STATS == 1 ) #if ( configGENERATE_RUN_TIME_STATS == 1 )
static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime )

View File

@ -635,6 +635,7 @@ void vPortEnableInterrupts( void )
portBASE_TYPE xPortSetInterruptMask( void ) portBASE_TYPE xPortSetInterruptMask( void )
{ {
fprintf(stderr, "This is called!\r\n");
portBASE_TYPE xReturn = xInterruptsEnabled; portBASE_TYPE xReturn = xInterruptsEnabled;
debug_printf("\r\n"); debug_printf("\r\n");
xInterruptsEnabled = pdFALSE; xInterruptsEnabled = pdFALSE;

View File

@ -53,7 +53,8 @@ FLASH_TOOL = OPENOCD
USE_THUMB_MODE = YES USE_THUMB_MODE = YES
# List of modules to include # List of modules to include
MODULES = Telemetry Actuator ManualControl Stabilization MODULES = Telemetry
MODULES += Actuator ManualControl Stabilization
MODULES += Attitude/revolution MODULES += Attitude/revolution
#MODULES += SimulatedAttitude #MODULES += SimulatedAttitude