Page 1 of 1

timer is getting delayed due to some reason

Posted: Tue Sep 05, 2023 9:30 am
by kesha.modhia
During one exercise of blinking the led for 2 minutes
I used timer and created timer for 2 minutes and I set the led to blink for 120 seconds

after expiration it should stop the led, some how i noticed timer is getting delayed due to some events which i am not able to figure out
here I have attached some code
-----------------------------------------
timer created
-----------------------------------------

#define PAIR_LED_TIME_PERIOD pdMS_TO_TICKS( 120000 )


if ((xPairLedTimerHandle = xTimerCreate((const char *)"Pair Led Timer",PAIR_LED_TIME_PERIOD,
pdFALSE, NULL, PairLedTimerExpiredCallback)) == NULL ) {
DEBUG_LOGE(UART, TAG, "xPairLedTimerHandle creation failed");
}

-----------------------------------------
timer started
-----------------------------------------


if (xTimerStart(xPairLedTimerHandle,0) == pdPASS)
{
DEBUG_LOGI(UART, TAG, "*xPairLedTimerHandle* TIMER STARTED");
PairingWindowLedStatus(APP_STATUS_LED3);
DEBUG_LOGD(UART, TAG, "back");
}
-----------------------------------------
Led blinking api
-----------------------------------------

void PairingWindowLedStatus(uint8_t gpiono)
{
bool ON = 1, OFF = 0;
uint16_t counter,ticks = 600;
for(counter = 0; counter <= ticks ; counter++)
{
gw_gpio_level_set(gpiono,ON); //LED is turn ON
nlg_task_delay_ms(100);
gw_gpio_level_set(gpiono,OFF); //LED is turn OFF
nlg_task_delay_ms(100);
}
DEBUG_LOGD(UART, TAG, "out of for");
}

======================

Timer is taking more 20 sec to expire, I came to know form the callback invoked late

how do I debug the time taken by which process


Thanks in advance

Re: timer is getting delayed due to some reason

Posted: Wed Sep 06, 2023 10:18 pm
by tpbedford
  1. uint16_t counter,ticks = 600;
  2. for(counter = 0; counter <= ticks ; counter++)
  3. {
  4.     gw_gpio_level_set(gpiono,ON); //LED is turn ON
  5.     nlg_task_delay_ms(100);
  6.     gw_gpio_level_set(gpiono,OFF); //LED is turn OFF
  7.     nlg_task_delay_ms(100);
  8. }
This loop takes 0.2s to execute, and you execute it 600x - actually 601 times - so this block runs for 120.2s regardless of your timer value. (I don't know how accurate nlg_task_delay_ms() is, so perhaps it takes longer than 120.2s if this delay is not very accurate.)

What does PairLedTimerExpiredCallback() do? Does it kill the task that starts the timer and runs the LED loop?

Re: timer is getting delayed due to some reason

Posted: Thu Sep 07, 2023 5:48 am
by kesha.modhia
Yes, PairLedTimerExpiredCallback() will OFF the blinking

so what shall I do for syncing the led and the timer for exact 120 seconds

Re: timer is getting delayed due to some reason

Posted: Thu Sep 07, 2023 5:52 am
by tpbedford
kesha.modhia wrote:
Thu Sep 07, 2023 5:48 am
Yes, PairLedTimerExpiredCallback() will OFF the blinking
How? Post the code for this.

One method is that your loop continues indefinitely (instead of 600 iterations) and also tests for a semaphore set by PairLedTimerExpiredCallback(). Once it detects the semaphore, it exits.

Re: timer is getting delayed due to some reason

Posted: Thu Sep 07, 2023 7:12 am
by kesha.modhia
Here I have attached the code
static unsigned char Pair_Led;

void PairLedTimerExpiredCallback(void *p_arg){
DEBUG_LOGI(UART, TAG, "********************in PairLedTimerExpiredCallback");
Pair_Led = 1;
led_event(LED_DEVICE_PAIR);
}


void led_event (event_led event)
{
case LED_DEVICE_PAIR:
DEBUG_LOGI(UART, TAG, "LED_DEVICE_PAIR");
if(Pair_Led == 0){
APPSendingMessage(APP_E_HIGH_FREQUENCY, APP_STATUS_LED3,
APP_E_CONTINUOUSLY_BLINK);
}else{
APPSendingMessage(APP_E_SOLID_OFF,APP_STATUS_LED3,
APP_E_CONTINUOUSLY_BLINK);
Pair_Led = 0;
}
break;
}

Re: timer is getting delayed due to some reason

Posted: Thu Sep 07, 2023 7:54 am
by ok-home
Hi
use xTaskDelayUntil
to form a delay
https://www.freertos.org/vtaskdelayuntil.html

Re: timer is getting delayed due to some reason

Posted: Thu Sep 07, 2023 7:58 am
by tpbedford
Where does APPSendingMessage event go? Who is listening?

There's so much code you're not posting here it's impossible to work out how you actually intend this to work.

The LED loop runs in some task (the same one that starts the timer). The loop needs to check some condition so it knows when to stop. If you sending some message, the loop needs to poll for it, and when it receives the message it breaks the loop.

Re: timer is getting delayed due to some reason

Posted: Thu Sep 07, 2023 9:15 am
by kesha.modhia
APPSendingMessage(APP_E_HIGH_FREQUENCY, APP_STATUS_LED3,APP_E_CONTINUOUSLY_BLINK);

Is the api to post the message in the led queue, which is one task ,is continously running in background to collect the led queue msg and run accordingly

PUBLIC void APPSendingMessage(unsigned char led_type, unsigned char led_number, unsigned char blink_number) {
APP_LedEvent sButtonEvent;
sButtonEvent.eLEDType = led_type;
sButtonEvent.BlinkNumber = blink_number;
sButtonEvent.u8LEDNumber = led_number;

if(nlg_queue_send(APP_LedmsgEvents, (void * )&sButtonEvent, 0)!= nlg_pass){
DEBUG_LOGE(UART, TAG, "APP_LedMsgEvent_queque send failed");
}
}

and runs according the event

Re: timer is getting delayed due to some reason

Posted: Thu Sep 07, 2023 9:22 am
by vanBassum
Why not like this?
Its a bit speudo but you get the idea.

Code: Select all


enum LedModes
{
	Off,
	Blink,
	On,
}
LedModes mode;

void Main()
{
	Timer.SetInterval(blinkSpeed);
	Timer.Start();
}

void TimerCallback
{
	if(mode == Off && GetLed() == 1)
	{
		SetLed(0);
	}

	if(mode == Blink)
	{
		if(GetLed() == 1)
			SetLed(0);
		else
			SetLed(1);
	}

	if(mode == On && GetLed() == 0)
	{
		SetLed(1);
	}
}

Or, this is probably more along the lines of what you want. (Didn't test)
It seems a bit overkill to run a task just to blink a LED.

Code: Select all


typedef enum {
    LED_STATE_OFF,
    LED_STATE_ON,
    LED_STATE_BLINKING
} led_state_t;


void task_function(void *pvParameter) {
	led_state_t current_led_state = LED_STATE_BLINKING;
	bool pinState = false;
	
    while (1) {
		
		// Wait for a notification from the timer
		led_state_t requestedState;
        ulTaskNotifyTake(&requestedState, pdMS_TO_TICKS(500));	//blinking 1Hz
		
		//Change led mode if requested by notification
		if(requestedState != current_led_state)
			current_led_state = requestedState;
		
		if(current_led_state == LED_STATE_BLINKING)
		{
			// Toggle the LED state
			pinState = !pinState;	
			gpio_set_level(LED_GPIO_PIN, ledState);
		}

		if(current_led_state == LED_STATE_ON)
		{
			// Toggle the LED state
			if(pinState == false)
			{
				pinState = true;
				gpio_set_level(LED_GPIO_PIN, pinState);
			}
		}
		
		if(current_led_state == LED_STATE_OFF)
		{
			// Toggle the LED state
			if(pinState == true)
			{
				pinState = false;
				gpio_set_level(LED_GPIO_PIN, pinState);
			}
		}
    }
}

// Function to be executed when the timer expires
void timer_callback(TimerHandle_t xTimer) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    // Notify the task
    xTaskNotifyFromISR(xTimerGetTimerDaemonTaskHandle(), 0, LED_STATE_OFF, &xHigherPriorityTaskWoken);

    // If xHigherPriorityTaskWoken is pdTRUE, a context switch should be requested
    if (xHigherPriorityTaskWoken == pdTRUE) {
        portYIELD_FROM_ISR();
    }
}

void app_main() {
    // Configure the LED GPIO pin
    gpio_config_t io_conf;
    io_conf.pin_bit_mask = (1ULL << LED_GPIO_PIN);
    io_conf.mode = GPIO_MODE_OUTPUT;
    gpio_config(&io_conf);

    // Create a task
    xTaskCreate(task_function, "task", 2048, NULL, 5, NULL);

    // Create a timer, expire after 20sec
    TimerHandle_t timer = xTimerCreate("timer", pdMS_TO_TICKS(20000), pdFALSE, (void *)0, timer_callback);

    if (timer != NULL) {
        // Start the timer
        xTimerStart(timer, 0);


    }
	
	
	
	while (1) {
		vTaskDelay(pdMS_TO_TICKS(1000));
	}
}