FreeRTOS and the XMega == Bad Juju!

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We have found a serious architectural problem with the AVR implementation of FreeRTOS when running on an XMega (a 128A1, in our case) and using preemption.

As you may know, the XMega allows each interrupt to be assigned a priority of low, medium, or high. The problem is that the FreeRTOS task switcher does not take the interrupt level into account when it switches context. If the system is in the middle of, let's say, a medium-level interrupt, the current implementation will bestow that interrupt level on to whatever task it may decide to switch to. That implies that the task is now running at medium interrupt level, and will stay that way until it yields or is preempted out. :shock:

Also, the ISR that was running doesn't complete until the original task comes around.

We found this out when the real time clock task mysteriously died after turning on a particular ISR.

We're thinking of ways around the problem, but for the moment the workaround is to turn off preemption.

Be careful with these new interrupt levels. There be dragons here!

Just wanted to let folks know.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

There be dragons here!

On an Xmega project?!? I didn't think that the Dragon had ANY Xmega support.

[tongue-in-cheek, people. I recognize the "dragon" reference, but don't remember how to find the maps.]

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you set the task switching timer interrupt to the lowest priority so it cannot pre-empt while another interrupt is being handled then does that not "fix" things?

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lee wrote:
Stu wrote:
There be dragons here!

On an Xmega project?!? I didn't think that the Dragon had ANY Xmega support.
:lol: Nyuk nyuk nyuk!

Cliff wrote:
If you set the task switching timer interrupt to the lowest priority so it cannot preempt while another interrupt is being handled then does that not "fix" things?
We thought of that and tried it. Didn't work. I'm not completely up on the problem since I'm not the one working on it.

As we work through the problems we'll build up an Xmega version that works and release it back to the community.

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is there any development on this (an Xmega version)?

Jeff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you used your version of FreeRtos with anything besides the 128A1? I have a version that a coworker cobbled (based on 5.0.3)together and is working fine on the xmega128a1 but not so much on the xmega32a4.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

http://www.atmel.com/dyn/resourc...
page 123
The PMIC status register contains state information that ensures that the PMIC returns to the
correct interrupt level when the RETI (interrupt return) instruction is executed at the end of an
interrupt handler. Returning from an interrupt will return the PMIC to the state it had before entering
the interrupt.
The Status Register (SREG) is not saved automatically upon an interrupt request. The RET (subroutine return) instruction cannot be used when returning from the interrupt
handler routine, as this will not return the PMIC to its right state.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have had a little luck getting freertos working on my xmega128a1 and xmega32a4 attached is my current working copy of freertos.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TBlake wrote:
I have had a little luck getting freertos working on my xmega128a1 and xmega32a4 attached is my current working copy of freertos.

I look your PORT.
In port.c,I don't find any code section to ISR.
such as

ISR(SYS_TIMER_VECT, ISR_NAKED)
{
    vPortYieldFromTick();
    reti();
}

I think it should add

ISR(SYS_TIMER_VECT, ISR_NAKED) __attribute__ ((section (".ISR")));

and in context restore
you have not restore 0x3d 0x3e register
at all,the idea come form atmega2560 freertos PORT is good.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello
I would like to use the "project" you gave in freertos.gz.
I don't have some header like "timerdriver.h" or "leddriver.h".
Is that custom header, or header that come from atmel?

well
It seems that these header are not crucial to make work the os. Yet I've got some problem with the setting of timer1.
I'm using the following part of code in port.c for prvSetupTimerInterrupt()

static void prvSetupTimerInterrupt( void )
{
    uint16_t pd;

    pd = (uint16_t) (configCPU_CLOCK_HZ / (configTICK_RATE_HZ * 64UL));

    /* ------------------------------------------------------------------- */
    /* Set up the system tick. */
 
 
//    timer1SetPeriod(&SYS_TIMER, pd);       
   TC_SetCount(&TCC1,pd);
     
//    timer1SetCca(&SYS_TIMER, pd);
   TC_SetCompareA(&TCC1,pd);

// timer1SetClk(&SYS_TIMER, TC_CLKSEL_DIV64_gc);
   TC1_ConfigClockSource(&TCC1,TC_CLKSEL_DIV64_gc);

//    timer1SetWgm(&SYS_TIMER, TC_WGMODE_NORMAL_gc);
   TC1_ConfigWGM(&TCC1,TC_WGMODE_NORMAL_gc);

//    timer1SetEvact(&SYS_TIMER, TC_EVACT_OFF_gc);

//    timer1SetCcaEn(&SYS_TIMER, 1);
   TC1_EnableCCChannels( &TCC1, TC1_CCAEN_bm);

//    timer1SetCcaIntLev(&SYS_TIMER, TC_CCAINTLVL_HI_gc);
   TC1_SetCCAIntLevel(&TCC1,TC_CCAINTLVL_HI_gc);

}

the functions I've used are provided by atmel (function like TC1_something).

Do you think those settings are correct?
Also, I would like to know why we don't use the timer1 as a simple timer and thus use the timeroverflow instead of comparing value.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After a few changes in my code and after having read many post of avrFreaks,I understand that my problem comes from the 3 bytes PC issue (at least I guess). Now I try to fix this using the solutions provided on avrfreaks...Sorry to post for quite nothing :p
by the way, I'm using ATxMEGA256A3