示例#1
0
static void prvExerciseTaskNotificationAPI( void )
{
uint32_t ulNotificationValue;
BaseType_t xReturned;

	/* The task should not yet have a notification pending. */
	xReturned = xTaskNotifyWait( 0, 0, &ulNotificationValue, mainDONT_BLOCK );
	configASSERT( xReturned == pdFAIL );
	configASSERT( ulNotificationValue == 0UL );

	/* Exercise the 'give' and 'take' versions of the notification API. */
	xTaskNotifyGive( xTaskGetCurrentTaskHandle() );
	xTaskNotifyGive( xTaskGetCurrentTaskHandle() );
	ulNotificationValue = ulTaskNotifyTake( pdTRUE, mainDONT_BLOCK );
	configASSERT( ulNotificationValue == 2 );

	/* Exercise the 'notify' and 'clear' API. */
	ulNotificationValue = 20;
	xTaskNotify( xTaskGetCurrentTaskHandle(), ulNotificationValue, eSetValueWithOverwrite );
	ulNotificationValue = 0;
	xReturned = xTaskNotifyWait( 0, 0, &ulNotificationValue, mainDONT_BLOCK );
	configASSERT( xReturned == pdPASS );
	configASSERT( ulNotificationValue == 20 );
	xTaskNotify( xTaskGetCurrentTaskHandle(), ulNotificationValue, eSetValueWithOverwrite );
	xReturned = xTaskNotifyStateClear( NULL );
	configASSERT( xReturned == pdTRUE ); /* First time a notification was pending. */
	xReturned = xTaskNotifyStateClear( NULL );
	configASSERT( xReturned == pdFALSE ); /* Second time the notification was already clear. */
}
示例#2
0
static void example_task(void *p)
{
    example_event_data_t *arg = (example_event_data_t *) p;
    timer_isr_handle_t inth;

    ESP_LOGI(TAG, "%p: run task", xTaskGetCurrentTaskHandle());

    esp_err_t res = timer_isr_register(arg->group, arg->timer, example_timer_isr, arg, 0, &inth);
    if (res != ESP_OK) {
        ESP_LOGE(TAG, "%p: failed to register timer ISR", xTaskGetCurrentTaskHandle());
    } else {
        res = timer_start(arg->group, arg->timer);
        if (res != ESP_OK) {
            ESP_LOGE(TAG, "%p: failed to start timer", xTaskGetCurrentTaskHandle());
        }
    }

    while (1) {
        uint32_t event_val;
        SYSVIEW_EXAMPLE_WAIT_EVENT_START();
        xTaskNotifyWait(0, 0, &event_val, portMAX_DELAY);
        SYSVIEW_EXAMPLE_WAIT_EVENT_END(event_val);
        ESP_LOGI(TAG, "Task[%p]: received event %d", xTaskGetCurrentTaskHandle(), event_val);
    }
}
示例#3
0
// notifies user (currently via buzzer, maybe via vibrator motor in the future)
static portTASK_FUNCTION(notify_task, param)
{
    (void) param;

    uint32_t beep_idx;
    uint32_t cycles;

    while (true)
    {
        // wait for someone to request a notification
        //ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        xTaskNotifyWait(UINT32_MAX,UINT32_MAX,&beep_idx,portMAX_DELAY);

        cycles = beeps[beep_idx].num_cycles;

        while(cycles--)
        {
            BUZZER_EN(buzz_en);

            vTaskDelay(beeps[beep_idx].beep_on_time/portTICK_PERIOD_MS);

            BUZZER_EN(0);

            vTaskDelay(beeps[beep_idx].beep_off_time/portTICK_PERIOD_MS);
        }
    }
}
示例#4
0
static void MidiPlayTask(void *pvParameters) {
  uint32_t flags;
  BaseType_t res;

  FLOPPY_InitDrives(); /* init */
  for(;;) {
    res = xTaskNotifyWait((uint32_t)(-1), (uint32_t)(-1), &flags, portMAX_DELAY); /* check flags */
    if (res==pdPASS && (flags&MIDI_SONG_START)) {
      FLOPPY_InitDrives();
      if (flags&MIDI_SONG_GET_READY) {
        MM_Play(MIDI_SONG_GET_READY);
      } else if (flags&MIDI_SONG_PIRATES_OF_CARIBIAN) {
        MM_Play(MIDI_SONG_PIRATES_OF_CARIBIAN);
      } else if (flags&MIDI_SONG_HADDAWAY_WHAT_IS_LOVE) {
        MM_Play(MIDI_SONG_HADDAWAY_WHAT_IS_LOVE);
      } else if (flags&MIDI_SONG_GAME_OF_THRONES) {
        MM_Play(MIDI_SONG_GAME_OF_THRONES);
      } else if (flags&MIDI_SONG_TETRIS) {
        MM_Play(MIDI_SONG_TETRIS);
      } else if (flags&MIDI_SONG_AXEL_F) {
        MM_Play(MIDI_SONG_AXEL_F);
      } else if (flags&MIDI_SONG_GHOSTBUSTERS) {
        MM_Play(MIDI_SONG_GHOSTBUSTERS);
      } else if (flags&MIDI_SONG_JAMES_BOND) {
        MM_Play(MIDI_SONG_JAMES_BOND);
      }
    }
  }
}
示例#5
0
void vnoticer( void * pvParameters )
 {		 
  uint32_t ulNotifiedValue=0x01;

    while(1)
    {	
	
      if( xTaskNotifyWait( 0x00,0xffff,&ulNotifiedValue,1000 )==pdTRUE)  
 {
        
	
		if( ( ulNotifiedValue | 0x01 ) == 0x01 )	   //checking if the received message is same as the sent
  {  UART0_SendStr("Received   MSG from N1 \n");	}

       else if( ( ulNotifiedValue | 0x02 ) == 0x02 )
  {  UART0_SendStr("Received   MSG from N2\n");		}
	   	 
		else if( ( ulNotifiedValue | 0x03 ) == 0x03 )
  {  UART0_SendStr("Received   MSG from N3\n"); 	}
       
       else if( ( ulNotifiedValue | 0x04 ) == 0x04 )
  {   UART0_SendStr("Received   MSG from N4\n");  }

         else
  {   UART0_SendStr("Learn Programming !\n");}
  		
}
		 
else
{ UART0_SendStr("No Notice\n"); }
   
 }	 
}
示例#6
0
void AudioHandler::_audio_task() {
	std::array<int16_t, 512> audioBuffer;

	while(true) {
		while(currentCassettes.empty())
			xTaskNotifyWait(0, 0, nullptr, portMAX_DELAY);

		audioBuffer.fill(0);
		for(uint16_t i=0; i<audioBuffer.size(); i++) {
			for(auto &c : currentCassettes)
				audioBuffer[i] += c.get_chunk();
		}

		size_t written_samples = 0;
		i2s_write(i2s_port, audioBuffer.data(), 1024, &written_samples, portMAX_DELAY);


		for(auto i=currentCassettes.begin(); i<currentCassettes.end(); i++) {
			if(i->is_done())
				currentCassettes.erase(i);
		}

		if(currentCassettes.empty())
			i2s_zero_dma_buffer(i2s_port);
	}
}
示例#7
0
static void prvBlockingTask( void *pvParameters )
{
TaskHandle_t xControllingTask;
uint32_t ulNotificationValue;
const uint32_t ulMax = 0xffffffffUL;

	/* Just to remove compiler warnings. */
	( void ) pvParameters;

	xControllingTask = xTaskGetHandle( pcControllingTaskName );
	configASSERT( xControllingTask );

	for( ;; )
	{
		/* Wait to be notified of the test that is to be performed next. */
		xTaskNotifyWait( 0, ulMax, &ulNotificationValue, portMAX_DELAY );

		switch( ulNotificationValue )
		{
			case abtNOTIFY_WAIT_ABORTS:
				prvTestAbortingTaskNotifyWait();
				break;

			case abtNOTIFY_TAKE_ABORTS:
				prvTestAbortingTaskNotifyTake();
				break;

			case abtDELAY_ABORTS:
				prvTestAbortingTaskDelay();
				break;

			case abtDELAY_UNTIL_ABORTS:
				prvTestAbortingTaskDelayUntil();
				break;

			case abtSEMAPHORE_TAKE_ABORTS:
				prvTestAbortingSemaphoreTake();
				break;

			case abtEVENT_GROUP_ABORTS:
				prvTestAbortingEventGroupWait();
				break;

			case abtQUEUE_SEND_ABORTS:
				prvTestAbortingQueueSend();
				break;

			default:
				/* Should not get here. */
				break;
		}

		/* Let the primary task know the test is complete. */
		xTaskNotifyGive( xControllingTask );

		/* To indicate this task is still executing. */
		xBlockingCycles++;
	}
}
示例#8
0
	BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )
	{
	BaseType_t xReturn;
	BaseType_t xRunningPrivileged = xPortRaisePrivilege();

		xReturn = xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait );
		vPortResetPrivilege( xRunningPrivileged );
		return xReturn;
	}
示例#9
0
void LittleConsole::callUpdate(void *args) {
	puts("Started updater thread!");

	uint32_t dummy;
	while(true) {
		xTaskNotifyWait(0, 0, &dummy, 2000/portTICK_PERIOD_MS);

		reinterpret_cast<LittleConsole *>(args)->raw_update();

		vTaskDelay(100/portTICK_PERIOD_MS);
	}
}
示例#10
0
//--------------------------------------------------------------------------------------
 void tkAnalogIn(void * pvParameters)
{

( void ) pvParameters;
BaseType_t xResult;
uint32_t ulNotifiedValue;

	while ( !startTask )
		vTaskDelay( ( TickType_t)( 100 / portTICK_RATE_MS ) );

	snprintf_P( aIn_printfBuff,sizeof(aIn_printfBuff),PSTR("starting tkAnalogIn..\r\n\0"));
	FreeRTOS_write( &pdUART1, aIn_printfBuff, sizeof(aIn_printfBuff) );

	tkAIN_state = anST_A00;		// Estado inicial.
	AN_flags.msgReload = FALSE;		// No tengo ningun mensaje de reload pendiente.
	AN_flags.msgPollNow = FALSE;

	// Arranco el timer de poleo.
	// Interrumpe c/1s.
	if ( xTimerStart( pollingTimer, 0 ) != pdPASS )
		u_panic(P_AIN_TIMERSTART);

	//
	for( ;; )
	{

		u_clearWdg(WDG_AIN);

		// Espero hasta 100ms por un mensaje.
		xResult = xTaskNotifyWait( 0x00, ULONG_MAX, &ulNotifiedValue, ((TickType_t) 100 / portTICK_RATE_MS ) );
		// Si llego un mensaje, prendo la flag correspondiente.
		if ( xResult == pdTRUE ) {

			if ( ( ulNotifiedValue & TK_PARAM_RELOAD ) != 0 ) {
				// Mensaje de reload configuration.
				AN_flags.msgReload = TRUE;
			}

			if ( ( ulNotifiedValue & TK_READ_FRAME ) != 0 ) {
				// Mensaje de polear un frame ( estando en modo servicio )
				if ( systemVars.wrkMode == WK_SERVICE )
					AN_flags.msgPollNow = TRUE;
			}
		}

		// Analizo los eventos.
		pv_ANgetNextEvent();
		// Corro la maquina de estados.
		pv_AINfsm();
	}

}
示例#11
0
static void prvTestAbortingTaskNotifyWait( void )
{
TickType_t xTimeAtStart;
BaseType_t xReturn;

	/* Note the time before the delay so the length of the delay is known. */
	xTimeAtStart = xTaskGetTickCount();

	/* This first delay should just time out. */
	xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
	if( xReturn != pdFALSE )
	{
		xErrorOccurred = pdTRUE;
	}
	prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );

	/* Note the time before the delay so the length of the delay is known. */
	xTimeAtStart = xTaskGetTickCount();

	/* This second delay should be aborted by the primary task half way
	through. */
	xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
	if( xReturn != pdFALSE )
	{
		xErrorOccurred = pdTRUE;
	}
	prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );

	/* Note the time before the delay so the length of the delay is known. */
	xTimeAtStart = xTaskGetTickCount();

	/* This third delay should just time out again. */
	xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
	if( xReturn != pdFALSE )
	{
		xErrorOccurred = pdTRUE;
	}
	prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
}
示例#12
0
void frequency_calculator(void* pvParameters){
	uint32_t ulNotificationValue, frequency_previous;
	double frequency_delta, abs_delta;
	struct freq_struct freq;
	static int activate_load_management = 0;

	while(1){
		//printf("Current Frequecny TASK: %d \n", frequency_value);
//		ulNotificationValue = ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
		xTaskNotifyWait(0x00,               /* Don't clear any bits on entry. */
					 ULONG_MAX,          /* Clear all bits on exit. */
					 &ulNotificationValue, /* Receives the notification value. */
					 portMAX_DELAY );    /* Block indefinitely. */
		frequency_previous = frequency_value;
		frequency_value = 16000.0 / ulNotificationValue;
		frequency_delta = (frequency_value - frequency_previous) * 2.0 * frequency_value * frequency_previous / (frequency_value + frequency_previous);
		freq.current = frequency_value;
		freq.delta = frequency_delta;
		abs_delta = frequency_delta < 0 ? frequency_delta * -1 : frequency_delta;
		//printf("activate_load_management %d  \n", activate_load_management);
		//printf("frequency_delta %f  \n", (frequency_delta));
		if (((frequency_value < thres_freq) || (abs_delta > thres_delta) ) && activate_load_management == 0){
			activate_load_management = 1;
			xQueueSendToBack( stability_queue, (void *)&activate_load_management, (TickType_t)0 );
		}else if ((frequency_value >= thres_freq && abs_delta <= thres_delta )  && activate_load_management == 1){
			activate_load_management = 0;
			xQueueSendToBack( stability_queue, (void *)&activate_load_management, (TickType_t)0 );
		}

		//printf("Frequency %.2f Hz \n", frequency_value);
		//printf("dF/dt %.2f \n", frequency_delta);

				xQueueSendToBack( Q_freq_data, (void *)&freq, (TickType_t)0 );


		//if (frequency_previous != frequency_value)
		//	printf("Frequency %.2f Hz \n", frequency_value);
	}

}
示例#13
0
static void Play(MIDI_MusicTrack *tracks, unsigned int nofTracks, uint32_t tempoUS) {
  int itemNo;
  uint8_t channel;
  uint32_t currTimeMs;
  TickType_t startTicks;
  unsigned int nofFinished;
  uint32_t flags;

  /* init defaults */
  for(channel=0;channel<nofTracks;channel++) {
    FLOPPY_MIDI_SetBank(channel, 0);
    FLOPPY_MIDI_SetInstrument(channel, 0);
    FLOPPY_MIDI_SetVolume(channel, 127);
  }
  startTicks = FRTOS1_xTaskGetTickCount();
  itemNo = 0;
  for(;;) { /* breaks */
    (void)xTaskNotifyWait(0UL, MIDI_SONG_STOP, &flags, 0); /* check flags */
    if (flags&MIDI_SONG_STOP) {
      CLS1_SendStr((uint8_t*)"Stopping song!\r\n", CLS1_GetStdio()->stdOut);
      for(channel=0;channel<nofTracks;channel++) {
        FLOPPY_MIDI_AllSoundOff(channel);
      }
      break;
    }
    currTimeMs = (FRTOS1_xTaskGetTickCount()-startTicks)/portTICK_RATE_MS;
    nofFinished = 0;
    for(channel=0;channel<nofTracks;channel++) {
      if (!PlayTrackItem(&tracks[channel], currTimeMs, channel, tempoUS)) {
        nofFinished++;
      }
    }
    if (nofFinished==nofTracks) { /* all finished */
      break;
    }
    FRTOS1_vTaskDelay(1/portTICK_RATE_MS);
    itemNo++;
  }
}
示例#14
0
/**
* @brief  Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
* @param  signals   wait until all specified signal flags set or 0 for any single signal flag.
* @param  millisec  timeout value or 0 in case of no time-out.
* @retval  event flag information or error code.
* @note   MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
*/
osEvent osSignalWait (int32_t signals, uint32_t millisec)
{
  osEvent ret;
  TickType_t ticks;

  ret.value.signals = 0;  
  ticks = 0;
  if (millisec == osWaitForever) {
    ticks = portMAX_DELAY;
  }
  else if (millisec != 0) {
    ticks = millisec / portTICK_PERIOD_MS;
    if (ticks == 0) {
      ticks = 1;
    }
  }  
  
  if (inHandlerMode())
  {
    ret.status = osErrorISR;  /*Not allowed in ISR*/
  }
  else
  {
    if(xTaskNotifyWait( 0,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE)
    {
      if(ticks == 0)  ret.status = osOK;
      else  ret.status = osEventTimeout;
    }
    else if(ret.value.signals >= 0x80000000)
    {
      ret.status =  osErrorValue;     
    }
    else  ret.status =  osEventSignal;
  }  
  return ret;
}
示例#15
0
//-------------------------------------------------------------------------------------
void tkGprsTx(void * pvParameters)
{

( void ) pvParameters;
BaseType_t xResult;
uint32_t ulNotifiedValue;

	while ( !startTask )
		vTaskDelay( ( TickType_t)( 100 / portTICK_RATE_MS ) );

	snprintf_P( gprs_printfBuff,sizeof(gprs_printfBuff),PSTR("starting tkGprsTx..\r\n\0"));
	FreeRTOS_write( &pdUART1, gprs_printfBuff, sizeof(gprs_printfBuff) );

	GPRS_stateVars.flags.msgFlooding = FALSE;

	// Fijo el modo para arrancar
	pv_cambiarEstado(gST_INICIAL,gST_MODEMAPAGADO);
	// Arranco el timer
	if ( xTimerStart( gprsTimer, 0 ) != pdPASS )
		u_panic(P_GPRS_TIMERSTART);

	//
	for( ;; )
	{
		u_clearWdg(WDG_GPRSTX);

		// Espero hasta 100ms por un mensaje.
		xResult = xTaskNotifyWait( 0x00, ULONG_MAX, &ulNotifiedValue, ((TickType_t) 100 / portTICK_RATE_MS ) );
		// Si llego un mensaje, prendo la flag correspondiente.
		if ( xResult == pdTRUE ) {
			if ( ( ulNotifiedValue & TK_PARAM_RELOAD ) != 0 ) {
				GPRS_stateVars.flags.msgReload = TRUE;
			}

			if ( ( ulNotifiedValue & TKC_FLOODING ) != 0 ) {
				GPRS_stateVars.flags.msgFlooding = TRUE;
			}
		}

		// El manejar la FSM con un switch por estado y no por transicion me permite
		// priorizar las transiciones.
		// Luego de c/transicion debe venir un break así solo evaluo de a 1 transicion por loop.
		//
		switch ( GPRS_stateVars.state.state ) {
		case gST_MODEMAPAGADO:
			sm_APAGADO();
			break;
		case gST_MODEMPRENDIENDO:
			sm_MODEMPRENDIENDO();
			break;
		case gST_CONFIGURAR:
			sm_CONFIGURAR();
			break;
		case gST_STANDBY:
			sm_STANDBY();
			break;
		case gST_OPENSOCKET:
			sm_SOCKET();
			break;
		case gST_INITFRAME:
			sm_INITFRAME();
			break;
		case gST_DATAFRAME:
			sm_DATAFRAME();
			break;
		default:
			snprintf_P( gprs_printfBuff,sizeof(gprs_printfBuff),PSTR("tkGprs::ERROR state NOT DEFINED\r\n\0"));
			FreeRTOS_write( &pdUART1, gprs_printfBuff, sizeof(gprs_printfBuff) );
			// Estado inicial.
			pv_cambiarEstado(gST_MODEMAPAGADO,gST_MODEMAPAGADO);
			break;
		}

	}
}
示例#16
0
void tkControl(void * pvParameters)
{

( void ) pvParameters;
BaseType_t xResult;
uint32_t ulNotifiedValue;

	MCP_init();

	// TERMINAL: Debe ser lo primero que incia para poder mandar mensajes de log.
	ac_terminal(INIT_TERM, NULL);

	loadSystemParams();

	// WATCHDOG
	ac_wdg( INIT_WDG );

	// LEDS
	ac_systemLeds( INIT_LED );

	// EXITWRKMODE2NORMAL
	ac_exitWrkMode2Normal(INIT_EWM2N);

	// MEMORIA
	MEM_init();
	snprintf_P( ctl_printfBuff,CHAR256,PSTR("Init memory: pWr=%d,pRd=%d,pDel=%d,free=%d,4rd=%d,4del=%d  \r\n"), MEM_getWrPtr(), MEM_getRdPtr(), MEM_getDELptr(), MEM_getRcdsFree(),MEM_getRcds4rd(),MEM_getRcds4del() );
	TERMrprintfStr( ctl_printfBuff );

	// Habilito arrancar otras tareas
	startToken = STOK_TIMERS;

	// Espero la notificacion para arrancar
	while ( startToken != STOK_CTL ) {
		vTaskDelay( ( TickType_t)( 100 / portTICK_RATE_MS ) );
	}
	TERMrprintfProgStrM("starting tkControl..\r\n");
	startToken++;

	// Loop
	for( ;; )
	{
		clearWdg(WDG_CTL);

		// LED
		ac_systemLeds(TOGGLE_LED);

		// WATCHDOG
		ac_wdg(CHECK_WDG);

		// TERMINAL
		ac_terminal(CHECK_TERM, NULL);

		// EXITWRKMODE2NORMAL
		ac_exitWrkMode2Normal(CHECK_EWM2N);

		// Genero una espera de 100ms por algun mensaje para hacer algo.
		xResult = xTaskNotifyWait( 0x00,          	 				/* Don't clear bits on entry. */
		                           ULONG_MAX,        				/* Clear all bits on exit. */
		                           &ulNotifiedValue, 				/* Stores the notified value. */
								   (100 / portTICK_RATE_MS ) );

		if( xResult == pdTRUE ) {
			// Arrancar el timer y control de modo service/monitor
			if ( ( ulNotifiedValue & CTLMSG_STARTEWM2N ) != 0 ) {
				ac_exitWrkMode2Normal(START_EWM2N);
		    }

		 }
	}
}
示例#17
0
static void prvSingleTaskTests( void )
{
const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL );
BaseType_t xReturned;
uint32_t ulNotifiedValue, ulLoop, ulNotifyingValue, ulPreviousValue, ulExpectedValue;
TickType_t xTimeOnEntering;
const uint32_t ulFirstNotifiedConst = 100001UL, ulSecondNotifiedValueConst = 5555UL, ulMaxLoops = 5UL;
const uint32_t ulBit0 = 0x01UL, ulBit1 = 0x02UL;

	/* -------------------------------------------------------------------------
	Check blocking when there are no notifications. */
	xTimeOnEntering = xTaskGetTickCount();
	xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, xTicksToWait );

	/* Should have blocked for the entire block time. */
	if( ( xTaskGetTickCount() - xTimeOnEntering ) < xTicksToWait )
	{
		xErrorStatus = pdFAIL;
	}
	configASSERT( xReturned == pdFAIL );
	configASSERT( ulNotifiedValue == 0UL );




	/* -------------------------------------------------------------------------
	Check no blocking when notifications are pending.  First notify itself -
	this would not be a normal thing to do and is done here for test purposes
	only. */
	xReturned = xTaskNotifyAndQuery( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite, &ulPreviousValue );

	/* Even through the 'without overwrite' action was used the update should
	have been successful. */
	configASSERT( xReturned == pdPASS );

	/* No bits should have been pending previously. */
	configASSERT( ulPreviousValue == 0 );

	/* The task should now have a notification pending, and so not time out. */
	xTimeOnEntering = xTaskGetTickCount();
	xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, xTicksToWait );

	if( ( xTaskGetTickCount() - xTimeOnEntering ) >= xTicksToWait )
	{
		xErrorStatus = pdFAIL;
	}

	/* The task should have been notified, and the notified value should
	be equal to ulFirstNotifiedConst. */
	configASSERT( xReturned == pdPASS );
	configASSERT( ulNotifiedValue == ulFirstNotifiedConst );

	/* Incremented to show the task is still running. */
	ulNotifyCycleCount++;





	/*--------------------------------------------------------------------------
	Check the non-overwriting functionality.  The notification is done twice
	using two different notification values.  The action says don't overwrite so
	only the first notification should pass and the value read back should also
	be that used with the first notification. */
	xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite );
	configASSERT( xReturned == pdPASS );

	xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithoutOverwrite );
	configASSERT( xReturned == pdFAIL );

	/* Waiting for the notification should now return immediately so a block
	time of zero is used. */
	xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );

	configASSERT( xReturned == pdPASS );
	configASSERT( ulNotifiedValue == ulFirstNotifiedConst );





	/*--------------------------------------------------------------------------
	Do the same again, only this time use the overwriting version.  This time
	both notifications should pass, and the value written the second time should
	overwrite the value written the first time, and so be the value that is read
	back. */
	xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithOverwrite );
	configASSERT( xReturned == pdPASS );
	xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithOverwrite );
	configASSERT( xReturned == pdPASS );
	xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );
	configASSERT( xReturned == pdPASS );
	configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst );




	/*--------------------------------------------------------------------------
	Check notifications with no action pass without updating the value.  Even
	though ulFirstNotifiedConst is used as the value the value read back should
	remain at ulSecondNotifiedConst. */
	xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eNoAction );
	configASSERT( xReturned == pdPASS );
	xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );
	configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst );




	/*--------------------------------------------------------------------------
	Check incrementing values.  Send ulMaxLoop increment notifications, then
	ensure the received value is as expected - which should be
	ulSecondNotificationValueConst plus how ever many times to loop iterated. */
	for( ulLoop = 0; ulLoop < ulMaxLoops; ulLoop++ )
	{
		xReturned = xTaskNotify( xTaskToNotify, 0, eIncrement );
		configASSERT( xReturned == pdPASS );
	}

	xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );
	configASSERT( xReturned == pdPASS );
	configASSERT( ulNotifiedValue == ( ulSecondNotifiedValueConst + ulMaxLoops ) );

	/* Should not be any notifications pending now. */
	xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 );
	configASSERT( xReturned == pdFAIL );




	/*--------------------------------------------------------------------------
	Check all bits can be set by notifying the task with one additional bit	set
	on each notification, and exiting the loop when all the bits are found to be
	set.  As there are 32-bits the loop should execute 32 times before all the
	bits are found to be set. */
	ulNotifyingValue = 0x01;
	ulLoop = 0;

	/* Start with all bits clear. */
	xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );

	do
	{
		/* Set the next bit in the task's notified value. */
		xTaskNotify( xTaskToNotify, ulNotifyingValue, eSetBits );

		/* Wait for the notified value - which of course will already be
		available.  Don't clear the bits on entry or exit as this loop is exited
		when all the bits are set. */
		xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 );
		configASSERT( xReturned == pdPASS );

		ulLoop++;

		/* Use the next bit on the next iteration around this loop. */
		ulNotifyingValue <<= 1UL;

	} while ( ulNotifiedValue != ULONG_MAX );

	/* As a 32-bit value was used the loop should have executed 32 times before
	all the bits were set. */
	configASSERT( ulLoop == 32 );




	/*--------------------------------------------------------------------------
	Check bits are cleared on entry but not on exit when a notification fails
	to arrive before timing out - both with and without a timeout value.  Wait
	for the notification again - but this time it is not given by anything and
	should return pdFAIL.  The parameters are set to clear bit zero on entry and
	bit one on exit.  As no notification was received only the bit cleared on
	entry should actually get cleared. */
	xReturned = xTaskNotifyWait( ulBit0, ulBit1, &ulNotifiedValue, xTicksToWait );
	configASSERT( xReturned == pdFAIL );

	/* Notify the task with no action so as not to update the bits even though
	ULONG_MAX is used as the notification value. */
	xTaskNotify( xTaskToNotify, ULONG_MAX, eNoAction );

	/* Reading back the value should should find bit 0 is clear, as this was
	cleared on entry, but bit 1 is not clear as it will not have been cleared on
	exit as no notification was received. */
	xReturned = xTaskNotifyWait( 0x00UL, 0x00UL, &ulNotifiedValue, 0 );
	configASSERT( xReturned == pdPASS );
	configASSERT( ulNotifiedValue == ( ULONG_MAX & ~ulBit0 ) );





	/*--------------------------------------------------------------------------
	Now try clearing the bit on exit.  For that to happen a notification must be
	received, so the task is notified first. */
	xTaskNotify( xTaskToNotify, 0, eNoAction );
	xTaskNotifyWait( 0x00, ulBit1, &ulNotifiedValue, 0 );

	/* However as the bit is cleared on exit, after the returned notification
	value is set, the returned notification value should not have the bit
	cleared... */
	configASSERT( ulNotifiedValue == ( ULONG_MAX & ~ulBit0 ) );

	/* ...but reading the value back again should find that the bit was indeed
	cleared internally.  The returned value should be pdFAIL however as nothing
	has notified the task in the mean time. */
	xReturned = xTaskNotifyWait( 0x00, 0x00, &ulNotifiedValue, 0 );
	configASSERT( xReturned == pdFAIL );
	configASSERT( ulNotifiedValue == ( ULONG_MAX & ~( ulBit0 | ulBit1 ) ) );




	/*--------------------------------------------------------------------------
	Now try querying the previous value while notifying a task. */
	xTaskNotifyAndQuery( xTaskToNotify, 0x00, eSetBits, &ulPreviousValue );
	configASSERT( ulNotifiedValue == ( ULONG_MAX & ~( ulBit0 | ulBit1 ) ) );

	/* Clear all bits. */
	xTaskNotifyWait( 0x00, ULONG_MAX, &ulNotifiedValue, 0 );
	xTaskNotifyAndQuery( xTaskToNotify, 0x00, eSetBits, &ulPreviousValue );
	configASSERT( ulPreviousValue == 0 );

	ulExpectedValue = 0;
	for( ulLoop = 0x01; ulLoop < 0x80UL; ulLoop <<= 1UL )
	{
		/* Set the next bit up, and expect to receive the last bits set (so
		the previous value will not yet have the bit being set this time
		around). */
		xTaskNotifyAndQuery( xTaskToNotify, ulLoop, eSetBits, &ulPreviousValue );
		configASSERT( ulExpectedValue == ulPreviousValue );
		ulExpectedValue |= ulLoop;
	}



	/* -------------------------------------------------------------------------
	Clear the previous notifications. */
	xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );

	/* The task should not have any notifications pending, so an attempt to clear
	the notification state should fail. */
	configASSERT( xTaskNotifyStateClear( NULL ) == pdFALSE );

	/* Get the task to notify itself.  This is not a normal thing to do, and is
	only done here for test purposes. */
	xTaskNotifyAndQuery( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite, &ulPreviousValue );

	/* Now the notification state should be eNotified, so it should now be
	possible to clear the notification state. */
	configASSERT( xTaskNotifyStateClear( NULL ) == pdTRUE );
	configASSERT( xTaskNotifyStateClear( NULL ) == pdFALSE );




	/* Incremented to show the task is still running. */
	ulNotifyCycleCount++;

	/* Leave all bits cleared. */
	xTaskNotifyWait( ULONG_MAX, 0, NULL, 0 );
}
示例#18
0
void ProgramManager::runManager(){
  uint32_t ulNotifiedValue = 0;
  // TickType_t xMaxBlockTime = pdMS_TO_TICKS( 1000 );
  TickType_t xMaxBlockTime = portMAX_DELAY;  /* Block indefinitely. */
  for(;;){
    /* Block indefinitely (without a timeout, so no need to check the function's
       return value) to wait for a notification.
       Bits in this RTOS task's notification value are set by the notifying
       tasks and interrupts to indicate which events have occurred. */
    xTaskNotifyWait(pdFALSE,          /* Don't clear any notification bits on entry. */
		    UINT32_MAX,       /* Reset the notification value to 0 on exit. */
		    &ulNotifiedValue, /* Notified value pass out in ulNotifiedValue. */
		    xMaxBlockTime ); 
    if(ulNotifiedValue & STOP_PROGRAM_NOTIFICATION){ // stop      
      audioStatus = AUDIO_EXIT_STATUS;
      codec.softMute(true);
      if(xProgramHandle != NULL){
	programVector = &staticVector;
	vTaskDelete(xProgramHandle);
	xProgramHandle = NULL;
      }
    }
    // allow idle task to garbage collect if necessary
    vTaskDelay(20);
    // vTaskDelay(pdMS_TO_TICKS(200));
    if(ulNotifiedValue & START_PROGRAM_NOTIFICATION){ // start
      PatchDefinition* def = getPatchDefinition();
      if(xProgramHandle == NULL && def != NULL){
	BaseType_t ret;
	if(def->getStackBase() != 0 && 
	   def->getStackSize() > configMINIMAL_STACK_SIZE*sizeof(portSTACK_TYPE)){
	  ret = xTaskGenericCreate(runProgramTask, "Program", 
				   def->getStackSize()/sizeof(portSTACK_TYPE), 
				   NULL, PROGRAM_TASK_PRIORITY, &xProgramHandle, 
				   def->getStackBase(), NULL);
	}else{
	  ret = xTaskCreate(runProgramTask, "Program", PROGRAM_TASK_STACK_SIZE, NULL, PROGRAM_TASK_PRIORITY, &xProgramHandle);
	}
	if(ret != pdPASS)
	  setErrorMessage(PROGRAM_ERROR, "Failed to start program task");
      }
#ifdef BUTTON_PROGRAM_CHANGE
    }else if(ulNotifiedValue & PROGRAM_CHANGE_NOTIFICATION){ // program change
      if(xProgramHandle == NULL){
	BaseType_t ret = xTaskCreate(programChangeTask, "Program Change", PC_TASK_STACK_SIZE, NULL, PC_TASK_PRIORITY, &xProgramHandle);
	if(ret != pdPASS)
	  setErrorMessage(PROGRAM_ERROR, "Failed to start Program Change task");
      }
#endif /* BUTTON_PROGRAM_CHANGE */
    }else if(ulNotifiedValue & PROGRAM_FLASH_NOTIFICATION){ // program flash
      BaseType_t ret = xTaskCreate(programFlashTask, "Flash Write", FLASH_TASK_STACK_SIZE, NULL, FLASH_TASK_PRIORITY, &xFlashTaskHandle);
      if(ret != pdPASS){
	setErrorMessage(PROGRAM_ERROR, "Failed to start Flash Write task");
      }
    }else if(ulNotifiedValue & ERASE_FLASH_NOTIFICATION){ // erase flash
      BaseType_t ret = xTaskCreate(eraseFlashTask, "Flash Erase", FLASH_TASK_STACK_SIZE, NULL, FLASH_TASK_PRIORITY, &xFlashTaskHandle);
      if(ret != pdPASS)
	setErrorMessage(PROGRAM_ERROR, "Failed to start Flash Erase task");
    // }else if(ulNotifiedValue & MIDI_SEND_NOTIFICATION){ // erase flash
    //   TaskHandle_t handle = NULL;
    //   BaseType_t ret = xTaskCreate(sendMidiDataTask, "MIDI", PC_TASK_STACK_SIZE, NULL, PC_TASK_PRIORITY, &handle);
    //   if(ret != pdPASS){
    // 	setErrorMessage(PROGRAM_ERROR, "Failed to start MIDI Send task");
    //   }
    }
  }
}