mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
More work on osx simulation engine
This commit is contained in:
parent
3c0b65fbf8
commit
51f0c3453b
@ -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;
|
||||
|
||||
void printTasks();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -89,6 +89,8 @@ typedef struct XPARAMS
|
||||
void *pvParams;
|
||||
} xParams;
|
||||
|
||||
enum thread_status {RUNNING, INTERRUPTED, STOPPED};
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting variable. */
|
||||
typedef struct THREAD_SUSPENSIONS
|
||||
{
|
||||
@ -97,11 +99,12 @@ typedef struct THREAD_SUSPENSIONS
|
||||
pthread_mutex_t * hMutex;
|
||||
xTaskHandle hTask;
|
||||
portBASE_TYPE xThreadState;
|
||||
enum thread_status status;
|
||||
unsigned portBASE_TYPE uxCriticalNesting;
|
||||
} xThreadState;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static xThreadState *pxThreads;
|
||||
static xThreadState pxThreads[MAX_NUMBER_OF_TASKS];
|
||||
static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT;
|
||||
static pthread_attr_t xThreadAttributes;
|
||||
#ifdef RUNNING_THREAD_MUTEX
|
||||
@ -109,7 +112,7 @@ static pthread_mutex_t xRunningThread = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
static pthread_mutex_t xSuspendResumeThreadMutex = 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;
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@ -119,7 +122,7 @@ static volatile portBASE_TYPE xSuspended = pdFALSE;
|
||||
static volatile portBASE_TYPE xStarted = pdFALSE;
|
||||
static volatile portBASE_TYPE xHandover = 0;
|
||||
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 xPendYield = pdFALSE;
|
||||
static volatile portLONG lIndexOfLastAddedTask = 0;
|
||||
@ -139,6 +142,7 @@ static pthread_cond_t * prvGetConditionHandle( xTaskHandle hTask );
|
||||
static pthread_mutex_t * prvGetMutexHandle( xTaskHandle hTask );
|
||||
#endif
|
||||
static xTaskHandle prvGetTaskHandle( pthread_t hThread );
|
||||
static void prvSetThreadStatus( pthread_t hThread, enum thread_status status );
|
||||
static portLONG prvGetFreeThreadState( void );
|
||||
static void prvSetTaskCriticalNesting( pthread_t xThreadId, unsigned portBASE_TYPE uxNesting );
|
||||
static unsigned portBASE_TYPE prvGetTaskCriticalNesting( pthread_t xThreadId );
|
||||
@ -339,6 +343,9 @@ portBASE_TYPE xResult;
|
||||
sigset_t xSignalToBlock;
|
||||
portLONG lIndex;
|
||||
|
||||
fid = fopen("log.txt", "w");
|
||||
|
||||
|
||||
debug_printf( "xPortStartScheduler\r\n" );
|
||||
|
||||
/* Establish the signals to block before they are needed. */
|
||||
@ -353,15 +360,17 @@ portLONG lIndex;
|
||||
pxThreads[ lIndex ].uxCriticalNesting = 0;
|
||||
}
|
||||
|
||||
fid = fopen("log.txt", "w");
|
||||
|
||||
/* Start the first task. Will not return unless all threads are killed. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
usleep(1000000);
|
||||
int i = 0;
|
||||
while( pdTRUE != xSchedulerEnd ) {
|
||||
usleep(portTICK_RATE_MICROSECONDS);
|
||||
vPortSystemTickHandler(SIG_TICK);
|
||||
vPortSystemTickHandler(SIG_TICK);
|
||||
i++;
|
||||
//if (i % 2000 == 0)
|
||||
// printTasks();
|
||||
}
|
||||
|
||||
debug_printf( "Cleaning Up, Exiting.\n" );
|
||||
@ -429,13 +438,14 @@ void vPortExitCritical( void )
|
||||
if ( pdTRUE == xPendYield )
|
||||
{
|
||||
xPendYield = pdFALSE;
|
||||
vPortYield();
|
||||
// vPortYield();
|
||||
}
|
||||
vPortEnableInterrupts();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
tskTCB *lastYield;
|
||||
void vPortYield( void )
|
||||
{
|
||||
pthread_t xTaskToSuspend;
|
||||
@ -470,6 +480,7 @@ tskTCB * oldTask, * newTask;
|
||||
return;
|
||||
}
|
||||
|
||||
lastYield = oldTask;
|
||||
xStarted = pdFALSE;
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
//debug_printf("\r\n");
|
||||
//assert( pthread_mutex_lock( &xIrqMutex ) == 0);
|
||||
maskSuspend();
|
||||
irq_lock = 1;
|
||||
assert( pthread_mutex_lock( &xIrqMutex ) == 0);
|
||||
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 )
|
||||
{
|
||||
//debug_printf("\r\n");
|
||||
//assert( pthread_mutex_lock( &xIrqMutex ) == 0);
|
||||
maskSuspend();
|
||||
irq_lock = 1;
|
||||
assert( pthread_mutex_lock( &xIrqMutex ) == 0);
|
||||
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 )
|
||||
{
|
||||
pthread_t xTaskToSuspend;
|
||||
pthread_t xTaskToResume;
|
||||
tskTCB * oldTask, * newTask;
|
||||
|
||||
debug_printf( "\r\n\r\n" );
|
||||
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 ) )
|
||||
{
|
||||
// debug_printf( "Checking for lock ...\r\n" );
|
||||
if ( 0 == pthread_mutex_trylock( &xSwappingThreadMutex ) )
|
||||
{
|
||||
|
||||
/* Select Next Task. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
debug_printf( "Handling\r\n");
|
||||
xServicingTick = pdTRUE;
|
||||
|
||||
oldTask = xTaskGetCurrentTaskHandle();
|
||||
xTaskToSuspend = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
|
||||
|
||||
/* Tick Increment. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
/* Select Next Task. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
vTaskSwitchContext();
|
||||
#endif
|
||||
|
||||
newTask = xTaskGetCurrentTaskHandle();
|
||||
xTaskToResume = prvGetThreadHandle( xTaskGetCurrentTaskHandle() );
|
||||
@ -580,6 +626,7 @@ tskTCB * oldTask, * newTask;
|
||||
/* The only thread that can process this tick is the running thread. */
|
||||
if ( xTaskToSuspend != xTaskToResume )
|
||||
{
|
||||
//fprintf(stderr,"Suspending: %s\r\n", oldTask->pcTaskName);
|
||||
xSuspended = pdFALSE;
|
||||
xStarted = pdFALSE;
|
||||
|
||||
@ -609,7 +656,7 @@ tskTCB * oldTask, * newTask;
|
||||
pthread_cond_t * hCond = prvGetConditionHandle( xTaskGetCurrentTaskHandle() );
|
||||
assert( pthread_cond_signal( hCond ) == 0 );
|
||||
#endif
|
||||
assert( pthread_kill( xTaskToSuspend, SIG_SUSPEND ) == 0);
|
||||
//assert( pthread_kill( xTaskToSuspend, SIG_SUSPEND ) == 0);
|
||||
|
||||
sched_yield();
|
||||
}
|
||||
@ -619,21 +666,22 @@ tskTCB * oldTask, * newTask;
|
||||
{
|
||||
// debug_error ("Want %s running \r\n", newTask->pcTaskName );
|
||||
}
|
||||
#endif configUSE_PREEMPTION
|
||||
|
||||
xServicingTick = pdFALSE;
|
||||
(void)pthread_mutex_unlock( &xSwappingThreadMutex );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Cannot get swap thread mutex\r\n");
|
||||
debug_error( "Pending yield here (portYield has lock - hopefully)\r\n" );
|
||||
xPendYield = pdTRUE;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf( "Pending yield or here\r\n");
|
||||
xPendYield = pdTRUE;
|
||||
}
|
||||
|
||||
assert( pthread_mutex_unlock( &xIrqMutex) == 0);
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@ -733,6 +781,8 @@ void * pParams = pxParams->pvParams;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
extern volatile unsigned portBASE_TYPE uxSchedulerSuspended;
|
||||
|
||||
void pauseThread( portBASE_TYPE pauseMode )
|
||||
{
|
||||
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 ) );
|
||||
#endif
|
||||
debug_printf("Resuming\r\n");
|
||||
prvSetThreadStatus( pthread_self(), RUNNING );
|
||||
return;
|
||||
}
|
||||
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
|
||||
gettimeofday( &tv, NULL );
|
||||
ts.tv_sec = ts.tv_sec + 1;
|
||||
ts.tv_nsec = 0;
|
||||
ts.tv_sec = tv.tv_sec + 1;
|
||||
ts.tv_nsec = tv.tv_usec * 1000;
|
||||
xResult = pthread_cond_timedwait( hCond, hMutex, &ts );
|
||||
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
|
||||
/* For windows where conditional signaling is buggy */
|
||||
/* 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)
|
||||
@ -802,12 +890,12 @@ sigset_t xBlockSignals;
|
||||
/* 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 */
|
||||
|
||||
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 */
|
||||
//assert( 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;
|
||||
}
|
||||
|
||||
@ -821,7 +909,7 @@ sigset_t xBlockSignals;
|
||||
// assert( 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 );
|
||||
}
|
||||
|
||||
@ -870,7 +958,7 @@ portLONG lIndex;
|
||||
|
||||
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++ )
|
||||
{
|
||||
pxThreads[ lIndex ].hThread = ( pthread_t )NULL;
|
||||
@ -920,7 +1008,25 @@ portLONG lIndex;
|
||||
}
|
||||
}
|
||||
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 )
|
||||
|
@ -81,11 +81,9 @@ void *pvPortMalloc( size_t xWantedSize )
|
||||
{
|
||||
void *pvReturn;
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
pvReturn = malloc( xWantedSize );
|
||||
}
|
||||
xTaskResumeAll();
|
||||
|
||||
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
@ -105,11 +103,9 @@ void vPortFree( void *pv )
|
||||
{
|
||||
if( pv )
|
||||
{
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
free( pv );
|
||||
}
|
||||
xTaskResumeAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* 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
|
||||
@ -160,7 +161,7 @@ PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType )
|
||||
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = 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 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 portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;
|
||||
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;
|
||||
@ -378,7 +379,6 @@ static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TY
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*lint +e956 */
|
||||
|
||||
|
||||
@ -1078,7 +1078,9 @@ void vTaskSuspendAll( void )
|
||||
{
|
||||
/* A critical section is not required as the variable is of type
|
||||
portBASE_TYPE. */
|
||||
portENTER_CRITICAL();
|
||||
++uxSchedulerSuspended;
|
||||
portEXIT_CRITICAL();
|
||||
}
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
@ -1571,12 +1573,20 @@ void vTaskIncrementTick( void )
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int missed_threshold = 100;
|
||||
void vTaskSwitchContext( void )
|
||||
{
|
||||
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
|
||||
switch. */
|
||||
//fprintf(stderr, "Missed switch\n");
|
||||
xMissedYield = pdTRUE;
|
||||
return;
|
||||
}
|
||||
@ -1614,6 +1624,7 @@ void vTaskSwitchContext( void )
|
||||
vWriteTraceToBuffer();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
extern volatile portBASE_TYPE xInterruptsEnabled;
|
||||
|
||||
void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )
|
||||
{
|
||||
@ -1622,6 +1633,10 @@ portTickType xTimeToWake;
|
||||
/* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
|
||||
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.
|
||||
This is placed in the list in priority order so the highest priority task
|
||||
is the first to be woken by the event. */
|
||||
@ -1802,9 +1817,10 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
|
||||
{
|
||||
/* Stop warnings. */
|
||||
( void ) pvParameters;
|
||||
|
||||
int i =0;
|
||||
for( ;; )
|
||||
{
|
||||
i++;
|
||||
/* See if any tasks have been deleted. */
|
||||
prvCheckTasksWaitingTermination();
|
||||
|
||||
@ -2082,6 +2098,95 @@ tskTCB *pxNewTCB;
|
||||
#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 )
|
||||
|
||||
static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime )
|
||||
|
@ -635,6 +635,7 @@ void vPortEnableInterrupts( void )
|
||||
|
||||
portBASE_TYPE xPortSetInterruptMask( void )
|
||||
{
|
||||
fprintf(stderr, "This is called!\r\n");
|
||||
portBASE_TYPE xReturn = xInterruptsEnabled;
|
||||
debug_printf("\r\n");
|
||||
xInterruptsEnabled = pdFALSE;
|
||||
|
@ -53,7 +53,8 @@ FLASH_TOOL = OPENOCD
|
||||
USE_THUMB_MODE = YES
|
||||
|
||||
# List of modules to include
|
||||
MODULES = Telemetry Actuator ManualControl Stabilization
|
||||
MODULES = Telemetry
|
||||
MODULES += Actuator ManualControl Stabilization
|
||||
MODULES += Attitude/revolution
|
||||
#MODULES += SimulatedAttitude
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user