1

My project has a Atmega328p microcontroller (same as the Arduino Uno) So I implemented a Arduino Uno ported FreeRTOS v10 project.

Some specs: - F_CPU = 1 MHz - Running on timer 0 - Preemptive mode - Time slicing = on

My two simple tasks behave weird. Task 1 is a led toggle, Task 2 is a three tone ladder

My initial alarm implementation was an alarm_on() function that had three tones produced with _delay_ms() functions in between. But that didn't work as expected, so I tried with the vTaskDelayUntil() functions.

I made a video of the behavior running the code snippet below https://www.youtube.com/watch?v=XnYaELsW1d0

So the led blink works, but that is a very easy and short task. The Sound task only produces 2 tones or sometimes only one.

My task schedule:

xTaskCreate( TaskBlinkLED,  
             (const portCHAR *)"LED", 
             256, 
             NULL, 
             1,  
             NULL );

xTaskCreate( TaskSoundAlarm,  
             (const portCHAR *)"SOUND", 
             512, 
             NULL, 
             4,  
             NULL );

vTaskStartScheduler();

The actual task code

static void TaskBlinkLED(void *pvParameters) // Main Green LED Flash
{
    (void) pvParameters;
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = 800;
    /* The xLastWakeTime variable needs to be initialized with the current tick
    count.  Note that this is the only time we access this variable.  From this
    point on xLastWakeTime is managed automatically by the vTaskDelayUntil()
    API function. */
    xLastWakeTime = xTaskGetTickCount();

    for(;;)
    {
        led_toggle();
        vTaskDelayUntil( &xLastWakeTime, ( xFrequency / portTICK_PERIOD_MS ) );
    }
}

static void TaskSoundAlarm(void *pvParameters) 
{
    (void) pvParameters;
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = 3000;
    xLastWakeTime = xTaskGetTickCount();

    for(;;)
    {
        alarm_on(300);
        vTaskDelayUntil( &xLastWakeTime, ( 200 / portTICK_PERIOD_MS )  );
        alarm_on(400);
        vTaskDelayUntil( &xLastWakeTime, ( 200 / portTICK_PERIOD_MS )  );
        alarm_on(500);
        vTaskDelayUntil( &xLastWakeTime, ( 200 / portTICK_PERIOD_MS )  );
        alarm_off();

        vTaskDelayUntil( &xLastWakeTime, ( xFrequency / portTICK_PERIOD_MS ) );
    }
}

My Alarm function

void alarm_on(unsigned long hz)
{
    ALARM_PORT_DDR |= (1<<ALARM_PIN);
    t1_set_ctc_a(hz, timer_freq);
}

Why doesn't it finish the complete sound task here by producing 3 tones?

Rafael
  • 7,605
  • 13
  • 31
  • 46
user3411864
  • 624
  • 2
  • 12
  • 27
  • 1
    How does your alarm_on function look now? Does it still attempt to wait/delay? – user786653 Nov 01 '18 at 17:01
  • No wait loops in alarm_on() anymore. I'm adjusting a timer toggle value and DDR that pin as an output. – user3411864 Nov 01 '18 at 17:09
  • Probably not the answer, but is there a reason why you are using `vTaskDelayUntil()` instead of the `vTaskDelay()` ? It seems to me that would be a simpler function to use in your case. – Roel Balink Nov 02 '18 at 10:55
  • I tried both, but resulted in a different behavior. I think they have a different reference point where they count from. Can it be possible that switching Timer CTC value causes an unstable timer for a while? In that case this issue isn't FreeRTOS related. – user3411864 Nov 02 '18 at 11:03
  • Make sure you're not using the same timer as the FreeRTOS tick interrupt. If you can output debug information try to print timestamps of when various events occur. – user786653 Nov 05 '18 at 17:52

0 Answers0