Problems with the blackfin port ( Andr? Keller Abadie )
allanh-rtems2 at kallisti.com
Tue Apr 1 03:30:58 UTC 2008
> The problem happens when thread_dispatch is scheduled within an isr to
> be executed after its return. This scheduling procedure has a flaw and
> RTEMS keeps crashing every time a few conditions are met.
> Blackfin is an architecture that saves the return pointer of a call in
> a register - called RETS - instead of saving in the stack. However you
> can use the instruction 'link' to create a stack frame and this
> automatically pushes the RETS' value. All C code has this call+link
> pair so technically we do save the return pointer in the stack.
> This routine that schedules the execution of thread_dispatch after the
> return of an interruption does so by changing the RETI's ('return from
> interrupt' register) value to point to thread_dispatch and then
> changes RETS's value to the old RETI's. Because of this operation, the
> old RETS is lost if not previously saved by 'link'. All this procedure
> goes perfectly well if the call+link pair is executed, but there are a
> few functions that doesn't use 'link' (gcc code written in assembly).
> I guess there are other architectures that, as blackfin, don't save
> the return pointers in the stack. If so, how did you solve this
> Any suggestions?
> I do have a working solution but it uses a separate software
> interruption to handle the threaddispatch function.
I ran into the same problem with the Blackfin port.
There's another problem you didn't mention with the existing method;
to work, it has to disable threaddispatch when an interrupt occurs
between a call and link, or between an unlink and rts. This means
the system is not a preemptive real time system.
My suggestion is to do exactly what you have done, using a software
interrupt to do the threaddispatch. That is what I have done. While
what I've done seems to be working, I haven't had the time to do enough
testing to become completely convinced it's ready to include in RTEMS.
Doing this requires interrupt self-nesting to be enabled. The maximum
nesting depth will be the number of tasks in the system. It seems
to me that with the Blackfin interrupt architecture, there must be some
type of counter tracking the nest depth, and so there is some limit
to that depth based on the size of the counter. Alternatively, it
might be able to get away with just using the LSB of the RETI register
since instructions are always 16 bit aligned, which could avoid having
any limit. However, it is not documented if they do that, or if there's
a counter, and I was unable to get Analog Devices to answer that
question. I could of course write some test to see if the LSB of RETI
is being used, but have not yet had the time to do that.
If you'd like to see what I implemented I'd be happy to send it along.
Allan N. Hessenflow allanh at kallisti.com
More information about the users