Hang on CAN Interrupt

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Hang on CAN Interrupt

1,092 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Mon Nov 14 23:14:16 MST 2011
Hey all,

I'm having a strange problem that I can't seem to figure out. I haven't been able to get the CAN bypass test demo working, unless I disable CAN interrupts. I can receive a message just fine if I poll for it by calling CAN_ReceiveMsg repeatedly, but whenever I use the interrupt handler, my board just hangs. (FWIW, other interrupts are working just fine!) Is there some common mistake I'm making here?
0 Kudos
Reply
16 Replies

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Sat Nov 19 20:41:22 MST 2011
Problem solved.

It is the ISR vector table. Although the bootloader is explicitly relocating the ISR vector table by setting SCB->VTOR to point to the app's provided vector table, this isn't working. Printing out the contents of the VTOR register reveals that it is still set to 0x00!? Manually resetting VTOR to point to the modified tabel (in my case, at 0x2000) fixes the problem; ISRs are called properly without crashing.

Now what remains is to figure out why the VTOR isn't updating correctly! Annoyingly, the SP and PC (which reside at the root of te ISR vector table) are getting reset correctly, as near as I can tell. FWIW, I'm right now using NXP's demo code, unmodifed, and I know other people have been using it too! So weird, but a relief to at least be able to run my code!

Thanks for everyone's suggestions!
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Sat Nov 19 00:37:48 MST 2011
I think I have it figured out, maybe. I think the problem is with the ISR vector table. Specifically, I'm using Code Red's version of the LPC USB secondary bootloader for the RDB1768 dev board, or rather a bootloader derived from it (the only changes I made were to remove any reference to the LCD library). Here's what I've found:

The code you sent runs perfectly fine. Other code that uses other ISRs also works fine.

Code that is compiled for use with the USB bootloader doesn't work fine.

I have a suspicion, although I haven't looked closely enough yet, that the bootloader I'm using is relocating the ISR vector table to one location, and the compiled apps are providing the ISR vector table at a different location. That would explain why jumps into an ISR hang, if they are jumps into the wrong address! Will update as I figure out more.
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Fri Nov 18 18:09:52 MST 2011
Thanks Zero. I'll have a look at the points raised since my last post some time this weekend. I didn't think to post bin/hex and map files for my project, if that would help, I'm happy to provide them too.
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Nov 18 17:39:16 MST 2011
Not as mysterious as your sample, just a crashed version of CAN_LedControl :rolleyes:

It's an uncleaned export, so bin / hex / map files are included. This is a working sample :)

Hardware requirement: LPCXpresso (or LPC1769) and CAN-Transceiver
Function: Repeating every 125kbit 11bit ID message with ID+0x100, also toggling LED (P0.22).

If this bin / hex file isn't working, you have a hardware problem. Otherwise you can compare your map / bin files with this files (especially vector table, CRP, checksum) :rolleyes:
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Nov 18 03:55:23 MST 2011

Quote:

Update: Still a mystery.

And it will remain a mystery if you don't start to read your linker/map file and control them in order to confirm correct function.
Moving code is a nice little experiment but not too meaningful (especially if your optimization is still 2) :eek:

You don't have answered a lot of questions and so I have to assume that you haven't checked your bin /hex file :rolleyes:
Confirming the correct location of CRP / Checksum and ISRs in your flash file (hex or bin) could help you to deprive your mystery :)
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Polux rsv on Fri Nov 18 01:17:59 MST 2011
What about stack size ?

Angelo
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Fri Nov 18 00:25:58 MST 2011
Update: Still a mystery.

Here's what I did:

Disabled the receive interrupt. Called ISR directly from my code. No crash. Inserted dummy function ahead of ISR, and called it repeatedly, no crash. CAN frames are received just fine this way. So it's neither the contents of, nor the location of the ISR that is the issue.

Re-enable receive interrupt. Calling ISR directly = no hang. Calling dummy function = no hang. Receiving a CAN frame, which triggers receive interrupt = immediate hang.

Further inspection reveals that it's nothing special about the receive interrupt. Enabling any CAN interrupt, and then triggering it, causes the hang. Barf.

Even further inspection reveals that previously working code that used the RIT interrupt now hangs; if I disable the RIT interrupt, it runs fine (well, minus the things it needed the RIT for, anyway). So it looks like other interrupts are toasted too, contrary to what I said earlier.

I'm guessing at this point I just have bad hardware, that somewhere along the way handling it must have zapped something. Bah.
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Wed Nov 16 23:30:55 MST 2011

Quote: Zero
Without debugger that's a guessing game :)



Don't I know it!


Quote:

Another option is the location of your interrupt. Are other interrupts (Systick, Timer...) working?

Your CAN-ISR is the first part of your program, so it could be located in a critical region. If your checksum or CRP are placed in your ISR you can get the same effect :eek:.



Ah, this is an interesting thought; certainly hadn't even occurred to me. Other interrupts are working, but in this stripped down demo, there are no other interrupt handlers, and nothing else enabled. I'll try some experiments moving the code around, etc, tomorrow and report back the results. Thanks!
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Nov 16 01:59:09 MST 2011
Without debugger that's a guessing game :)

Another option is the location of your interrupt. Are other interrupts (Systick, Timer...) working?

Your CAN-ISR is the first part of your program, so it could be located in a critical region. If your checksum or CRP are placed in your ISR you can get the same effect :eek:.
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Wed Nov 16 01:22:58 MST 2011
The early return was part of my attempt to rule out that the ISR itself was to blame. I didn't mean to leave that in.

I know it's not the ISR, because the problem persists when I comment out the entire contents. The problem also persists in the case, as the early return that Polux observed, with ISR that consists only of commands to clear the interrupt bits. And disabling CAN interrupts entirely gets rid of the problem. So I know the ISR is itself not to blame, but I know that something in the interrupt generating mechanism is to blame.


So, if it's not the ISR, what else could it be? Is there something that I must have misconfigured, either in hardware or software, that could cause this problem? This is what I want to know. I'm dead certain the ISR is not to blame; it is a red herring. (Note: The only hardware attached is an MCP2551 attached to RD1 and TD1 at the points indicated in the code, plus pullups on the ISP pin and the reset pin.)
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Polux rsv on Tue Nov 15 07:00:24 MST 2011
There is a strange[I] return[/I] in the code :confused:  what would append in a ISR????



     //IntStatus = CAN_IntGetStatus(LPC_CAN2);
     CANIntStatus = CAN_IntGetStatus(LPC_CAN1);
     //DBG("IntStatus: %032B\n", CANIntStatus);
    [SIZE=4][COLOR=Red][B]return;[/B][/COLOR][/SIZE] 





Angelo
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Nov 15 06:38:28 MST 2011

Quote:

Don't blame me, that's NXP's ISR.

Can't believe that :rolleyes: But if you tell me from which sample you have started (and from where you have downloaded it), I'll blame them :)

Quote:

Basically, the ISR is never called, the system hangs before that.

How do you know that?

Quote:

Have you tried loading the code up, and seeing if it runs?

Since this is no LPCXpresso project, I can't do that within a few minutes of my coffee break :mad:
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Tue Nov 15 06:09:36 MST 2011
Don't blame me, that's NXP's ISR. Even so, I had the same thought. As it happens, the problem persists with an empty ISR, or an ISR that only clears the interrupt flag. Basically, the ISR is never called, the system hangs before that. But if the ISR is never enabled, the system doesn't hang at all. So, the problem is somewhere between the interrupt being generated, and the ISR being called.

Have you tried loading the code up, and seeing if it runs?
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Nov 15 04:23:25 MST 2011

Quote:

I'm having a strange problem that I can't seem to figure out...

What's that :eek:

void CAN_IRQHandler()
//void foobar()
{
    //DBG("In IRQ Handler!\n");
    uint8_t CANIntStatus;
    uint32_t data1;
    /* get interrupt status
     * Note that: Interrupt register CANICR will be reset after read.
     * So function "CAN_IntGetStatus" should be called only one time
     */
    //IntStatus = CAN_IntGetStatus(LPC_CAN2);
    CANIntStatus = CAN_IntGetStatus(LPC_CAN1);
    //DBG("IntStatus: %032B\n", CANIntStatus);
    return;

    //check receive interrupt
    if((CANIntStatus>>0)&0x01)
    {
        //CAN_ReceiveMsg(LPC_CAN2,&RXMsg);
        CAN_ReceiveMsg(LPC_CAN1,&RXMsg);
        PrintMessage(&RXMsg);
        CANRxCount++; //count success received message
        //increase data for next TX Message
        TXMsg.id ++;
        data1 = (TXMsg.dataA[0])|(((TXMsg.dataA[1]))<<8)|((TXMsg.dataA[2])<<16)|((TXMsg.dataA[3])<<24);
        if(data1 == 0xFFFFFFFF) data1 = 0;
        else data1++;
        *((uint8_t *) &TXMsg.dataA[0])= *((uint8_t *) &TXMsg.dataB[0])= data1 & 0x000000FF;
        *((uint8_t *) &TXMsg.dataA[1])= *((uint8_t *) &TXMsg.dataB[1])=(data1 & 0x0000FF00)>>8;;
        *((uint8_t *) &TXMsg.dataA[2])= *((uint8_t *) &TXMsg.dataB[2])=(data1 & 0x00FF0000)>>16;
        *((uint8_t *) &TXMsg.dataA[3])= *((uint8_t *) &TXMsg.dataB[3])=(data1 & 0xFF000000)>>24;

        CAN_SendMsg(LPC_CAN1, &TXMsg);
    }
}

Please don't put every available slow function in your ISR. What else could your MCU do in this ISR?

Making coffee and washing the car? Throw that out, store your received data and do the everything else outside this ISR


Quote:

...but whenever I use the interrupt handler, my board just hangs...

What did you try already? Could be useful if you step through your code to see when it 'hangs' :rolleyes:
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DEGoodmanWilson on Tue Nov 15 03:32:38 MST 2011

Quote: Zero
The first mistake is to conceal what board you are using and which example you have started :eek:



Fair enough. As mentioned somewhat obliquely in the previous post, I'm working from the "CAN_test_bypass_mode" demo from NXP's CMSIS library examples. I can post the actual code I'm using in the morning. It's a makefile-based project using Code Sourcery's gcc port on the Mac, FWIW. The board is the LPCXpresso 1769. I am not using the LPCXpresso IDE, since I'm on a Mac, but I imagine it wouldn't be hard to get the code working on other platforms too.


Update: My code is attached.
0 Kudos
Reply

1,036 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Nov 15 00:59:19 MST 2011
The first mistake is to conceal what board you are using and which example you have started :eek:
0 Kudos
Reply