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:
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;
|
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
|
||||||
|
@ -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 )
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 )
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user