Access Error Exception on instruction fetch with a MCF5235

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

Access Error Exception on instruction fetch with a MCF5235

8,356 Views
AnthonyG_
Contributor I
Hello,
We are using a Coldfire 5235 (with a gdb compiler).
Every time an interrupt occurs (PIT interrupt, Flexcan interrupt...), the code in the interrupt is executed but after that, my code loops in the exception handler in the case "Access Error" and "Error on instruction fetch". And so, the only thing i can do is to reset my board.
Does anyone know what can cause this exception and how to handle it?
Thanks a lot and sorry for my english,
Anthony
Labels (1)
0 Kudos
Reply
9 Replies

1,715 Views
AnthonyG_
Contributor I
I have news, I was on the wrong way.

The exception occurs because my compiler (m68k_gcc) treats my interruption as a function, and that's why the stack is lost.(In assembler when i debug, the last instruction in my interrupt is "rts"! and not "rte")
I've read that's because my compiler ignores the declaration : __attribute__((interrupt)).

So, I don't find a real solution to my problem. The faster one will be to change my compiler but it's imposed. The other one is maybe to wrote a piece of code in assembler but I have no idea about it.
Does someone could help me?
Thanks
0 Kudos
Reply

1,715 Views
AnthonyG_
Contributor I
Thank you Mark

The problem is solved, it came from the compiler as I supposed. By applying a piece of assembler code, all works!

Here is my assembler code(for the one who has this problem)


_asm_timer1_handler:

move.l sp,a1
move.l a1,-(sp)
jsr timer_handler
lea 4(sp),sp
rte

Thanks a lot for your help!
Regards,
Anthony
0 Kudos
Reply

1,715 Views
mjbcswitzerland
Specialist V

Anthony

Are you sure that you are using the attribute correctly? GCC does support interrupts and it should be more or less the same for all targets.

Here is an example. Please check that your syntax is the same.

void Cpu_Interrupt(void) __attribute__((interrupt)); // forward declare the function as interrupt

void Cpu_Interrupt(void)
{
// Empty interrupt routine
}

If you look at the *.psa file generated by using objdump (or with the debugger)
"objdump -S *.elf"
you should find that the routine will have the RTE.
Here's an example from the HCS12 which I use (I haven't used GCC with the ColdFire yet - here it uses RTI and RTS).

void Cpu_Interrupt(void)
{
5e12: 18 01 ae 2c movw 2c1a _.frame>, 2,-SP
5e16: 1a
5e17: 18 01 ae 2c movw 2c14 _edata>, 2,-SP
5e1b: 14
5e1c: 18 01 ae 2c movw 2c16 _.z>, 2,-SP
5e20: 16
5e21: 18 01 ae 2c movw 2c18 _.xy>, 2,-SP
5e25: 18
5e26: 7f 2c 1a sts 2c1a _.frame>

00005e29 .LM42>:
5e29: 18 05 b1 2c movw 2,SP+, 2c18 _.xy>
5e2d: 18
5e2e: 18 05 b1 2c movw 2,SP+, 2c16 _.z>
5e32: 16
5e33: 18 05 b1 2c movw 2,SP+, 2c14 _edata>
5e37: 14
5e38: 18 05 b1 2c movw 2,SP+, 2c1a _.frame>
5e3c: 1a
5e3d: 0b rti

00005e3e :
}

If I leave away the interrupt attribute declaration the normal subroutine return is used:
void Cpu_Interrupt(void)
{
5e17: 18 01 ae 2c movw 2c1a _.frame>, 2,-SP
5e1b: 1a
5e1c: 7f 2c 1a sts 2c1a _.frame>

00005e1f .LM43>:
5e1f: 18 05 b1 2c movw 2,SP+, 2c1a _.frame>
5e23: 1a
5e24: 3d rts

00005e25 :
}

It is normally easiest to find a small reference project since the GNU documentation is only really understandable when you already know how it works (which I admit to not doing). Then copy how such things are done.

Note also that the interrupt routine is very compiler specific. Which registers (and soft registers) need to be saved must be known and therefore, although writing the interrupt routines in assembler (with a normal subroutine call to the C-code to be executed) is very possible it will also require a reference from a compiled interrupt routine. But to get a compiled interrupt routine reference you will probably have to solve the problem anyway....

Regards

Mark Butcher
www.mjbc.ch

0 Kudos
Reply

1,715 Views
mjbcswitzerland
Specialist V

Hi Anthony

Put a break point in the exception handler and when the error occurs look at the memory just above the stack pointer address.

When an exception occurs the ColdFire uses a simplified exception stack as follows:

////////8 +----------------+----------------+
//////////| Program Counter |
////////4 +----------------+----------------+
//////////|FS/Fmt/Vector/FS| SR |
SP --> 0 +----------------+----------------+

You can then see the program counter when the exception was caused and also the status register value. You will then know which instruction is causing the error. If this instruction is only called when your interrupt routine is excecuted you will be able to set a break point there and see exactly what it is doing wrong.

If the instruction at the PC is however called without error also when the interrupt is not excecuted it will be a little more difficult but at least you will know which line of code it is in. Look for incorrectly initialised pointer use or accesses to memory or register addresses which doen't exist.

Regards

Mark Butcher
www.mjbc.ch

Message Edited by mjbcswitzerland on 2006-08-23 12:00 PM

0 Kudos
Reply

1,715 Views
AnthonyG_
Contributor I
Hi Mark,
Thank you for your reply.
I try now and come back if i can't resolve it.

Regards,
Anthony
0 Kudos
Reply

1,716 Views
AnthonyG_
Contributor I
Ok I think i've found where my problem is.

With my debugger (gdb debugger), when I look at the stack when my program comes to my breakpoint, I see that:

main
??
??
otcp_netbuf (which is a transmit buffer for TCP protocol)
asm_exception_handler (which is declared in my list of vectors)
exception_handler (where is my breakpoint)

It seems that the problem comes from my otcp_netbuf.

What calls the exception seems to be the line code "movew %a0,%fp@-" (address 0x20003d08)

At this line, the stack pointer gets this value :

address: 0x20003d08
SP-> 0x44082300
SP + 0x04 -> 0x41942000
SP + 0x08 -> 0x30002b44
SP + 0x0C -> 0x00000806

Doesn't the Fault Status tell me that there is an error on instruction fetch (FS=0100)?
Is it normal that I've assembler code in my buffer otcp_netbuf?
Do you know how to solve this problem?
Thanks a lot for your help, I hope you understand my problem
Regards,

Anthony


PS: my buffer is declared like that:

#define NETWORK_TX_BUFFER_SIZE 1600
UINT8 otcp_netbuf[NETWORK_TX_BUFFER_SIZE];

PS2: Please find what i got on my debugger

0x20003c9c : orib #0,%d0
- 0x20003ca0 : orib #0,%d0
0x20003ca4 : eorl %d7,0xffffef69
- 0x20003ca8 : 0145675
- 0x20003caa : 0173655
- 0x20003cac : movel %d0,%d0
- 0x20003cae : movew %d4,%fp@+
- 0x20003cb0 : movew %d0,%d0
- 0x20003cb2 : bgts 0x20003cd0
- 0x20003cb4 : orib #0,%d0
- 0x20003cb8 : orib #0,%d0
- 0x20003cbc : orib #0,%d0
- 0x20003cc0 : bset %d0,%a4@(123)
- 0x20003cc4 : movel %d0,%d0
- 0x20003cc6 : movew %a0@(12288),%fp@+
- 0x20003cca : mvzw %a2@-,%d0
- 0x20003ccc : eorl %d7,0xffffef69
- 0x20003cd0 : 0145675
- 0x20003cd2 : 0173655
- 0x20003cd4 : movel %d0,%d0
- 0x20003cd6 : movew %a0@(00000000,%d3:w),%fp@+
- 0x20003cda : eorb %d6,%fp@(0)
- 0x20003cde : orib #0,%d0
- 0x20003ce2 : orib #0,%d6
- 0x20003ce6 : orib #0,%d1
- 0x20003cea : orib #0,%d0
- 0x20003cee : orib #0,%d3
- 0x20003cf2 : movew %a0,%fp@-
- 0x20003cf4 : movew %d0,%d0
- 0x20003cf6 : bccs 0x20003d74
- 0x20003cf8 : orib #5,%d0
- 0x20003cfc : movel %d0,%d0
- 0x20003cfe : 041544
- 0x20003d00 : movew %d1,%d0
- 0x20003d02 : moveb %a0@+,%a4@+
- 0x20003d04 : movel %d0,%d0
- 0x20003d06 : movew %a0,%fp@-
- 0x20003d08 : negb %a0
- 0x20003d0a : movel %d0,%a1@-
- 0x20003d0c : chkw %a4@,%d0
- 0x20003d0e : movel %d0,%d0
- 0x20003d10 : movew %d0,%d0
- 0x20003d12 : movel %d4,%a5@(0)
- 0x20003d16 : btst #2,%d6
- 0x20003d1a : addw %d5,%a2@-
- 0x20003d1c : orib #0,%d3
- 0x20003d20 : orib #0,%d0
- 0x20003d24 : orib #0,%d0
- 0x20003d28 : orib #0,%d0
- 0x20003d2c : orib #0,%d0
0 Kudos
Reply

1,716 Views
mjbcswitzerland
Specialist V

Anthony

I would say that you have a problem with your memory since it is certainly not normal that the code is running in the buffer which you have declared.

The MCF5235 has 64k of internal SRAM and I assume that you are loading your program to the SRAM so that you can debug it there using your debugger. Check the size of the program and the amount of memory it is using and verify that it does indeed have adequate place to allow debugging from SRAM. It may be that the code fits but there is too little spacefor the stack and this then overwrites parts of the program.

It may be best to reduce the program space to a minimum until you know that everything is basically working properly and then at some point you will have to then move over to loading yout code into FLASH and debugging it from there (with some restrictions due to limited breakpoints and slower download times).

Check this first before continuing with exception stack details.

[If you are already running in FLASH then try to find when it jumps from FLASH into the SRAM address space.]

Regards

Mark Butcher
www.mjbc.ch

0 Kudos
Reply

1,716 Views
AnthonyG_
Contributor I
Thanks a lot for your reply, it makes me understand a lot on the 5235.

Indeed, my code is surely bigger than 64kB (I use a TCPopen stack which is big), so it's "normal" that code overwrites datas.
But this problem is still here when I flash my code(with CFFlasher).

But as you told me, I think it will be better to reduce my program space to verify that everything is OK.(Back to basics, just one timer interrupt which makes blink LEDs and gradually import my real code)

If my problem still remains, I'll come back.

Thanks again for your help!
Regards,
Anthony
0 Kudos
Reply

1,716 Views
AnthonyG_
Contributor I
Hi,

I've tried to build a new project with only one timer interrupt(PIT1, 5 seconds interrupt), and my problem remains. I still get my exception "access error on instruction fetch".

This exception appears when i load in RAM, and when I load in Flash.

I assume that maybe it's my link file that is in cause, unless I'ven't configured well my interrupts.

Does anyone see a solution?
Thanks a lot for your implication,
Regards,
Anthony


I join my link file (for Flash) and my main, I attach my Interrupts handler, interrupt vectors and my HW init.

Main.c:
Code:
/** File: main.c* Purpose: Main process**/#include "standard.h"#include "m523xevb.h"#include "bits.h"#include "io.h"#include "mcf523x_intc0.h"#include "Led.h"#include "wdi.h"/********************************************************************//********************************************************************/int main (void){int16 i;ULMOT temps;/* Enable interrupts */mcf5xxx_wr_sr(0x2000);led_init();asm_set_ipl(0);MCF_PIT_PCSR1 = MCF_PIT_PCSR_PRE(0x0F); /* Divse fsys/2 par 32 768*/ /* Divide fsys/2 by 512 --> 16.8 us/tic */MCF_PIT_PCSR1 |= MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_PIE |MCF_PIT_PCSR_PIF | MCF_PIT_PCSR_RLD |MCF_PIT_PCSR_EN;MCF_PIT_PMR1 = 11443; /* Interrupt every 5s */MCF_INTC0_ICR37 = MCF_INTC0_ICR37 = MCF_INTC0_ICRn_IL(0x07) |MCF_INTC0_ICRn_IP(0x07);MCF_INTC0_IMRH &= ~(MCF_INTC0_IMRH_INT_MASK37);wdi_init();while(1){for (i=0;i6;i++){bit_sets(MCF_GPIO_PODR_TIMER, MCF_GPIO_PODR_TIMER_PODR_TIMER4);for(temps=0; temps!=500000; temps++);bit_clrs(MCF_GPIO_PODR_TIMER, MCF_GPIO_PODR_TIMER_PODR_TIMER4);for(temps=0; temps!=500000; temps++);}}}/********************************************************************/Link File:# ## DESCRIPTION ## Linker command file for rom target. ## #MEMORY{ext_nvsram (RWX) : ORIGIN = 0x10000000, LENGTH = 0x00080000vector_ram (RWX) : ORIGIN = 0x20000000, LENGTH = 0x500sram (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00010000user (RWX) : ORIGIN = 0x20000500, LENGTH = 0x0000FB00ext_sram (RWX) : ORIGIN = 0x30000000, LENGTH = 0x00080000ipsbar (RWX) : ORIGIN = 0x40000000, LENGTH = 0x01ext_flash (RWX) : ORIGIN = 0xFFE00000, LENGTH = 0x00200000}SECTIONS{.vector_ram : {} > vector_ram.ipsbar : {} > ipsbar.sram : {} > sram.ext_sram : {} > ext_sram.ext_nvsram : {} > ext_nvsram.ext_flash : {} > ext_flash.user : {} > user.boot_flash :{obj-CPU_A/vectors.o (.text)*(.text)*(.rodata)*(.rodata.str1.1)} > ext_flash__DATA_EXTSRAM_ROM = .;__DATA_EXTSRAM_RAM = ADDR(.ext_sram);.sys_extsram : AT(__DATA_EXTSRAM_ROM){__START_DATA_EXTSRAM = .;__END_DATA_EXTSRAM = .;__START_SDATA_EXTSRAM = .;__END_SDATA_EXTSRAM = .;__DATA_EXTSRAM_END = .;. = ALIGN (0x4);} > ext_sram__DATA_ROM = __DATA_EXTSRAM_ROM + SIZEOF(.sys_extsram);__DATA_RAM = ADDR(.user);.sys_sram : AT(__DATA_ROM){__START_DATA = .;*(.data)__END_DATA = .;__START_SDATA = .;*(.sdata)__END_SDATA = .;__DATA_END = .;__SDA_BASE = .;. = ALIGN (0x4);} > user.sect_nvsram :{/*# nvsram.c (.bss) */} > ext_nvsram.uninitialized_data_extsram :{__BSS_EXTSRAM_START = .;__END_SBSS_EXTSRAM = .;__START_BSS_EXTSRAM = .;__BSS_EXTSRAM_END = .;. = ALIGN (0x4);} > ext_sram.uninitialized_data :{__BSS_START = .;*(.sbss)*(SCOMMON)__END_SBSS = .;__START_BSS = .;*(.bss)*(COMMON)__BSS_END = .;. = ALIGN (0x4);___HEAP_START = .;. = . + 0x000;___HEAP_END = .;___SP_END = .;. = . + 0x200;___SP_INIT = .;} > user__IPSBAR = ADDR(.ipsbar);___IPSBAR = __IPSBAR;__VECTOR_RAM = ADDR(.vector_ram);__SDRAM = 0;__SDRAM_SIZE = 0x00000000;__SRAM = ADDR(.sram);__SRAM_SIZE = 0x00010000;___SRAM = __SRAM;__EXT_SRAM = ADDR(.ext_sram);__EXT_SRAM_SIZE = 0x00080000;__EXT_NVSRAM = ADDR(.ext_nvsram);__EXT_NVSRAM_SIZE = 0x00000001;__EXT_FLASH = ADDR(.ext_flash);__EXT_FLASH_SIZE = 0x00200000;___EXT_FLASH = __EXT_FLASH;__SP_INIT = ___SP_INIT;}

 

Message Edited by Alban on 2006-08-25 08:31 PM

0 Kudos
Reply