Let an interrupt trigger a task

Hi Sprucify,

I would recommend that you use the latest port, so 10.4.0, as Jefftenney mentioned. We created that port to fix an issue in the port we distribute in START, and to add support for a couple of new AVR microcontrollers (AVR DA and AVR DB). We will get the START version fixed (or alternatively remove it…).

-Jacob,
Microchip Techology

Hi Jacob,

I’m a bit confused here.
Yesterday I updated Atmel Studio and all the packages.
I used Atmel Start to create a new project, but without selecting the FreeRTOS example Atmega4809.
I downloaded FreeRTOS 10.4.0 from git repo and started to implement it myself with the AVR_Mega0 port.

Am I right that the only files that differ between ports/demos are?:

  • port.c
  • porthardware.h
  • portmacro.h
  • heap_1.c
  • FreeRTOSConfig.h

Or are there other things to configure, fuses, clocks, hardware timers, etc?

So the Atmel Start example Atmega4809 is not a working demo yet?
You advice to use this demo right?:

Commenting on many of the posts above:

  • If you block on ulTaskNotifyTake() with a timeout then you can have the periodic update when the timeout expires, and have the interrupt give a notification to have the update on each interrupt. Not sure there is a need for a software timer.

  • Remove the call to printf(). It may use lots of stack space, take along time to run, unexpectedly call malloc(), and not be thread safe.

  • You will probably be better off using xTaskNotifyGiveFromISR() and ulTaskNotifyTake() without clearing the count to zero, so all interrupts get latched in the notification count and processed one by one (in place of TaskNotifyFromISR() and xTaskNotifyWait()).

  • Is the function that generates the buzzer/beep executed in the interrupt handler? How long does it take to execute? It might be too long for the interrupt handler.

  • _delay_ms(10); would not seem to be the right function to call when using FreeRTOS - use vTaskDelay() instead. vTaskDelay() will allow all lower priority tasks to run during the delay period, whereas _delay_ms() may hog all processing cycles in whichever task calls it - starving any lower priority tasks of processing time.

  • Do you have stack overflow protection on, and configASSERT() defined - I saw these questions asked but I’m not sure I saw an answer.

  • Is your interrupt still executing? Put a break point in it to find out. Or simply have it increment a variable each time then break on the debugger to see the variable.

  • Check the tick interrupt continues to increment after your system gets into the state where it appears not to be functioning as expected any more. You can do that by inspecting xTaskTickCount in the debugger.

OK and if you want to stop the periodic update I can just stop the Task right?

My printf() was hooked to an UART stream, but it is very instable. I’m going to try the serial example inside the atmega4809 demo. The 4808 has not a UART3, but I can easily change the code a bit.

Is sprintf() also not thread safe? What is normally used inside FreeRTOS to output data strings over UART?

The buzzer is a multitone sound by changing PWM frequency en have _delay_ms() in between:

void alarm_short(void)
 {
   int per = 0;

   for (int i=0; i<6; i++)
   {
	//10000000/(16*3000)=0xD0
	per = 10000000/256/tone[i];
	
	TCA0_SPLIT_LPER = per;
	TCA0_SPLIT_LCMP2 = per/2; //3kHZ
	
	alarm_on();
	_delay_ms(200);
	alarm_off();
 }
}

Would you suggest to use taskdelay() here instead of _delay_ms(200)?

Is this being done inside the interrupt? If so, then you can’t use vTaskDelay() (because the ISR is not a task), and I would guess it is too long to be done in the interrupt anway as it will prevent all code other than that interrupt running for 200ms. That could in itself be the issue. If it is done in the task (rather than the interrupt) then vTaskDelay() would be better.

Will my printf be thread safe if I make use of a FILE stream?

The Atmega4809 USART example creates two thread safe queues, but I can only send one character at a time.

So I did:

static int USART0_printChar(char c, FILE *stream)
{
    xSerialPutChar( NULL, c, 0 );
    return 0;
}

static FILE USART_stream = FDEV_SETUP_STREAM(USART0_printChar, NULL, 
_FDEV_SETUP_WRITE);  

Does this break the thread safety?

My first project got stuck on interrupt handling.
This was a project created from the atmel start GUI tool.

My second project was created from the atmega4809 demo.
It was working fine, I got multiple tasks, queues, notifications end timers running without a problem.

Then I copied the I2C_master.c file from the first project.
This was auto generated component by atmel start.

I2C_master.c started to ask for several dependencies.
driver.h, driver_isr.c, compiler.h etc.

Most of them where placed inside util folder, so i also copied all the other dependencies over.

FreeRTOS complained about atomic.h which is part of FreeRTOS but I also copied it over from the other project.

After a while I managed it to compile without errors, got some implicit warnings though

In the end a atmel start project without freertos can run the I2C without a problem.
But a project with FreeRTOS not:

I2C_0_read2ByteRegister(0x4CU, 0);

I put above in een while loop, and it gets stuck, it keeps the I2C bus busy and never triggers the following interrupt:

ISR(TWI0_TWIM_vect)
{
  I2C_0_master_isr();
}

During implementation I’ve seen warning like __VECTOR(15) converted to int
But also ISR(TWI0_TWIM_vect) is returning non-void

There is something weird going on in the handling of interrupt vectors as soon as freetos gets in touch with components from atmel start project.