Author Topic: Thumb strange behaviour  (Read 10244 times)

Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Thumb strange behaviour
« on: November 17, 2010, 03:32:00 PM »
Hello Mark,

My code is running for a while but sometime there's a strange behaviour :
From time to time, when going through the code uDisable_Interrupt();, the Thumb mode is cancelled, and then I got an exception.
Do you have any idea about this ?
Code: [Select]
extern QUEUE_TRANSFER entry_que(QUEUE_HANDLE channel, unsigned char *ptBuffer, QUEUE_TRANSFER Counter, unsigned char ucCallType, QUEUE_HANDLE DriverID)
{
    QUEQUE *ptQUEQue;
    QUEUE_TRANSFER rtn_val = 0;
    uDisable_Interrupt();                                                // disable all interrupts
    switch ( ucCallType ) {


T= 1 before uDisable_Interrupt();
T= 0 after uDisable_Interrupt();


Using Keil µVison in step by step debug mode.


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3232
    • View Profile
    • uTasker
Re: Thumb strange behaviour
« Reply #1 on: November 17, 2010, 03:52:48 PM »
Hi Hervé

I would expect ARM mode only when an interrupt is in operation (when the code is generally compiled for Thumb).
I think that you are seeing an interrupt being called, which is also calling the same routine that you are stepping (it probably took place just before you stepped into the uDisable_Interrupt() call, and then called fnWrite() which calls entry_que(). Then the debugger stopped due to the interrupt hitting this location rather than your code hitting it. [The only thing is that I would expect the interrupt to switch back to thumb mode here too so it may not be exactly this sequence].

Another thing that makes me think that it is an interrupt is the fact that your stack pointer has also jumped from 0x4000ed18 (user stack) to 0x4000fecc (looks like interrupt stack space).

Does this help in some way?

Regards

Mark



Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: Thumb strange behaviour
« Reply #2 on: November 17, 2010, 04:42:52 PM »
Hello Mark,

I think your may be right.

If the thumb mode is cancelled during the interrupt and if I call a function compiled for thumb during this interrupt , what will happen ?
With the debbuger I skip a line on two.

How can I make it works ? Is there a pragma to force the compilation of a function in ARM mode ?

Thanks for your help .



Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3232
    • View Profile
    • uTasker
Re: Thumb strange behaviour
« Reply #3 on: November 17, 2010, 04:49:22 PM »
Hi Hervé

Each function can be individually declared to be a Thumb or ARM function. Check the pragmas for your compiler and also check the settings for files in the IDE.

As long as "inter-working" is used (a compiler setting) you can mix ARM and Thumb. the processor automatically changes mode - ARM functions are on even addresses and thumb functions are on odd addresses. There should usually be no problem miying them and interrupt (always in ARM) can call thumb compiled subroutines.

Regards

Mark


Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: Thumb strange behaviour
« Reply #4 on: November 17, 2010, 05:39:04 PM »
Hi Mark,

I already enabled ARM/Thumb Interworking for C/C++ and ASM, of course (If I don't I can't compile without error...)

If the processor automatically changes mode, I don't understand how I can have the Thumb bit cleared in entry_que() function.
When I step through this function (with ARM Mode set), the processor always finish to reach a PAbt exception.

Quite annoying.

Regards.

Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Interrupt strange behaviour
« Reply #5 on: November 18, 2010, 09:22:24 AM »
Hi Mark,

I compiled my code for ARM but got the same problem...
It happens when the interrupt occurs : As you note before, the stack pointer had also jumped to 0x4000fecc.
What is strange is that it is the start address of the stack. As the code is running through different calls to get there it would had change normally...



Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: Thumb strange behaviour
« Reply #6 on: November 18, 2010, 02:37:43 PM »
Hi Mark,

Finally it looks like the problem was because I placed a fnDebugDec() call inside fnI2CInt().
As long as I removed this debug there was no more problem......

Yours.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3232
    • View Profile
    • uTasker
Re: Thumb strange behaviour
« Reply #7 on: November 18, 2010, 08:15:02 PM »
Hi Hervé

It should be possible to use such debug calls from interrupt routines. However this is only advised for special cases (eg. temporarily debugging a particular problem) since such routines do increase the interrupt time, which could have an impact on other events.

However, the reason for problems could be due to the size of the interrupt stack (this can be configured in the linker script). The interrupts stack is usually a few hundred bytes and should be adequate for use by the interrupt routine itself and its typical driver calls. But if you are calling additional routines which again require more stack space there is a risk of the interrupt stack overflowing and this can cause a serious error later on once the interrupt has completed (stack corruption).

Possibly, if you increase the interrupt stack size it will also stop the error occurring, that you have previously seen (?)

Regards

Mark

Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: Thumb strange behaviour
« Reply #8 on: November 19, 2010, 10:47:52 AM »
Hi Mark,

I do this only to debug some problem (even if it induces new one ;)
Unfortunately my IRQ stack is already at 0x1000 which is large enough for my use....


Thanks for help.


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3232
    • View Profile
    • uTasker
Re: Thumb strange behaviour
« Reply #9 on: November 19, 2010, 03:50:08 PM »
Hi Hervé

Make sure that any calls like this in interrupts are protected as follows:

            iInterruptLevel = 1;                                         // ensure interrupts remain blocked when putting message to queue
            fnWrite(INTERNAL_ROUTE, (unsigned char*)EMAC_RX_int_message, HEADER_LENGTH); // inform the Ethernet task
            iInterruptLevel = 0;


In the case of the I2C interrupt there are usually no calls to OS routines and so there is no such inherent protection. This is a very possible cause of the problem since the call to a debug output routine will cause interrupts to be enabled before the ISR has completed (when not protected as shown in the example above), which has a risk of internal queue being manipulated by a routine and an ISR at the same time, resulting in corruption which can lead to more serious problems.

Regards

Mark

Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: Thumb strange behaviour
« Reply #10 on: November 24, 2010, 10:02:19 AM »
Hi Mark,

Thanks for your comments which help a lot.

Best Regards.