RTOS stack overflow

Dear all,

I am testing my own kernel for MSP430. I am measuring highest frequency for square signal that MSP430 with my kernel can repeat on its output. Square signal is connected to one of the interrupt pins, so on every high to low or low to high signal edge port interrupt is generated. In port ISR I am releasing semaphore on which my task is blocked. After task is unblocked its job is to toggle one pin declared as output. So i want to found out what is the highest frequency when no pulsed is missed to be repeated on the output pin.

While i was doing my test I found out that there are frequencies where stack overflow appears(everz task has its stack where context is saved). The thing is that when my Scheduler switches context back to idle task, because interrupt rate is so high, it never have a chance to pop PC.

That part of code looks like this

Reply to
brOS
Loading thread data ...

Well, there's your problem......

;)

Reply to
WangoTango

Some kernel operations need to be done with interrupts disabled. After your task suspends itself on the semaphore, the kernel should not be interruptable until the next (idle) task is running. Generally, interrupts are reenabled by executing a RETI, which restores the status register, including the GIE interrupt enable bit. At that point your PC has been popped.

--
Thad
Reply to
Thad Smith

for

high

ISR

saved).

your

interruptable

reenabled by

But, is the RETI instruction atomic? I think it s not?

--------------------------------------- Posted through

formatting link

Reply to
brOS

That is what RETI is intended for, so it should be atomic "enough".

Some quotes from the MSP430 description in the "MSP430x4xx Family" (TI document SLAU056D):

Page 2-9:

"The ACCVIE, NMIIE, and OFIE enable bits should not be set inside of an NMI interrupt service routine, unless they are set by the last instruction of the routine before the RETI instruction. Otherwise, nested NMI interrupts may occur, causing stack overflow and unpredictable operation"

Page 3-40:

"The instruction following the enable interrupt instruction (EINT) is always executed, even if an interrupt service request is pending when the interrupts are enable."

It thus seems to me that the EINT/RETI pair work as is common: after an interrupt is enabled, the response to a new or pending interrupt request is delayed until the RETI has completed.

--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .
Reply to
Niklas Holsti

I never really thought about it, but I would think it would HAVE to be. Since there would be no PC counter change until any popping of registers (like the PC) how could you interrupt it? Maybe I am missing something here, but if you in the middle of servicing the RETI how would you know where to return to if 'it' were interrupted?

Reply to
WangoTango

Of course it is.

-- Grant Edwards grante Yow! I just had my entire at INTESTINAL TRACT coated visi.com with TEFLON!

Reply to
Grant Edwards

ncy

tput.

rt

to

be

re

sk,

ter

E

In the context of a single bus master - the processor core - any instruction is atomic on all processors I know. Things are quite different when there are multiple bus masters, typically there is one or 2 (or 3, as on the 68020...) "atomic" opcodes, the rest are not.

Dimiter

------------------------------------------------------ Dimiter Popoff Transgalactic Instruments

formatting link

------------------------------------------------------

formatting link

Reply to
Didi

Not necessarily.

  • The instructions that take long time to execute could be interrupted in the middle. Such as chain operations or integer division.

  • Reads and writes of the operands that are wider then the CPU bus (such as 64-bit reads and writes) could be interrupted in between the bus cycles.

  • Read/write bursts can be interrupted.

  • Bus interface unit can shuffle the order of bus operations. In some cases this could be not transparent to the CPU.

I never count on implicit atomicity of any operation.

Vladimir Vassilevsky DSP and Mixed Signal Design Consultant

formatting link

Reply to
Vladimir Vassilevsky

On a processor that supports virtual memory, each memory (byte) reference might be interrupted.

For this reason, the hardware will often require that the interlocked data is 32/64 bit aligned, in order to be atomic.

Reply to
Paul Keinanen

Indeed - at least on Power it will take crossing a page boundary to cause a DSI or sort of exception. Handling it may cause a task switch (at least in DPS it can), and the accessed data of the page which succeeded can be accessed by another task prior to the interrupted one gains access to the second half of the access so you are right.

I was thinking small cores for once as the original question was in the context of such one IIRC and I completely forgot of what I was actually doing all day (I currently live in Power :-) ).

Dimiter

Reply to
Didi

Division? I have not seen that being interruptible. Where do they do that?

s.

Only in the context Paul reminded me - crossing a page boundary. Other than that, I don't know what could interrupt it. Not on the architectures I know, that is - power, 68k, 68xx, TI 54xx.

Well neither do I, but things are not that bad. I have developed an almost subconscious feeling when and what I need of that, so much so I even forgot the obvious case of crossing page boundary in my earlier post :-). On power, using lwarx/stwcx. does the job nicely for me wherever needed; too bad they messed the e600 core up so it can be hung by some case of these opcodes (which are user level, mind you). Hope the newer QorIQ (who made this name up?...) are cleaner, I am eyeing one of these.

Dimiter

Reply to
Didi

Of course it depends on the architecture. One of the original design reasons for the RISC architectures was the unpredictability and complex behavior of long CISC instructions. VAX instruction set for instance allowed a single instruction that touched up to 52 (!!!) pages, with that many page faults being the worst case:

formatting link

Reply to
Przemek Klosowski

RETI is atomic. It is executed to completion before an interrupt can occur.

...

There is no need for the EINT since the maskable interrupts are enabled by restoring the status register, which is part of the RETI.

--
Thad
Reply to
Thad Smith

On some of the larger 68k cores, long microcoded operations could be interrupted. That included division, multiple register moves, and a few others. I haven't used these myself (only the CPU32, then ColdFire), so I don't remember the details. But the exception stack frame had many variants, depending on which internal cpu registers needed to be saved and restored so that the instruction could be continued on a return from exception.

Such messy complications were dropped in the later 68k cores, and of course avoided altogether in the ColdFire.

Reply to
David Brown

Just wondering, how they have arrived at this figure. The character string instructions can touch far more pages than that and those instructions are definitely intended to be interruptible, by polluting registers R0..R5, even if these registers are not referenced in the instruction, in order to saving pointers and remaining counts at the interrupt.

I tried to count the maximum number of page faults during operand evaluation, before any character string or packed decimal access starts and reached 20 pages on a six operand instruction (three address+count pairs). This assumes indirect addressing on all operands, in which each pointer is on a page boundary and the three byte counts are on page boundaries too and of course the instruction on a page boundary too (2+3x(2+4)) pages. Of course, more page faults may occur, when the actual byte or packed decimal processing starts.

Reply to
Paul Keinanen

As I recall on the ST10/C167 both division ans multiplication operations are interruptable. If you wish to use those operations withing an interrupt you must store extra context.

Robert

Reply to
Robert Adsett

d

What a nightmare stack frame to handle... :-). On the TI 54xx division not adding latency is solved in a very elegant way - it is done in a loop by a "subtract conditionally" opcode (don't remember the exact name, I wrote an assembler for it but that was almost 10 years ago). Anyway, it uses the loop mode execution so in effect the division is really fast - 16 cycles for 32/16 IIRC (or was it for 16/16) - but interruptible with no horror stack frames.

Dimiter

Reply to
Didi

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.