This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Exception Handling on ARM

Hi,

Im working on a data-abort handler for the LPC2194 and I've found the Roger Lynx article's here:
www.eetimes.com/.../How-to-use-ARM-s-data-abort-exception

I've found the article good and I want to adapt the example he give in a C code (with inlines directives).
The problem is that I don't understand how to get all registers of the processor in a C table?

Here is the code I've already wrote (working with the line commented in the Handler):

#include <LPC21xx.h>
#include <stdio.h>
#include <stdlib.h>


#define varerror   (*((volatile unsigned long *) 0xEF05006C))
// Définition d'une fonction en dehors de la zone programme
#define Fonction_err() asm volatile ( " B 0x00050000")

#define ENTRER_ISR_Dabt()       asm volatile (" sub   lr, lr,#4\n" \ 
                                                                                  " STMFD sp!,{r0-r12,lr}")

#define SORTIR_ISR_Dabt()       asm volatile (" LDMFD sp!, {r0-r12,pc}^")



void C_Abort_handler() __attribute__((interrupt("Abort")));

// Initialisation de l'UART0 sans interruptions void initUART0(void)

void initUART0(void)
{

        PINSEL0 = 0x0005;       // P0.0 -> transmission/Reception UART0
        U0LCR = 0x83;           // Config + DLAB 1
        U0DLM = 0x00;           // Baud Rate
        U0DLL = 16;             // PLL x1 - 9600 bauds - 10Mhz
        U0LCR = 0x03;           // DLAB 0

}

void send_RS(unsigned char caractere)
{

        while ((U0LSR & 0x20) == 0x00) ;    // Tant que le buffer d'émission contient des données

        U0THR = caractere;
}

// Fonction d'envoi chaine de caractere sur UART0

void send_uart(unsigned char *tabcarac)
{

        int i = -1;

        do {
                i++;
                send_RS(*(tabcarac + i));

        } while (*(tabcarac + i) != 0x00);

}

int main(void)
{

        //Init P1.16
        IODIR1=0X00010000;      //p1.16  en sortie

        initUART0();

        send_uart("                C_DATA_ABORT HANDLER\r\n\0");
        send_uart("                  BOUHARA Kamel\r\n\0");
        // Ecriture interdite
        varerror = 0x1;

        // Erreur de fonction
        Fonction_err();
        while(1);
}

void C_Abort_handler()
{

        long dabort_dump[256];          //tableau des 15 regs + cpsr (= 72 octets)
        volatile unsigned long *lnk_ptr;
        volatile unsigned long cpsr, spsr;
        char adr[20], cur_mode[20], exc_mode[20],stack[75];

        ENTRER_ISR_Dabt();

//      asm volatile ("stmfd sp!, {r0-r12,lr}");
//      asm volatile ("ldr sp, =(dabort_dump+5*4)");
//      asm volatile ("stmia sp, {r0-r15}");  //sauv. des regs
        asm volatile ("sub lr, lr, #8");      //récupère l'adresse de l'instruction d'exception
        asm volatile ("mov %0, lr":"=r" (lnk_ptr)); //adresse récupérer dans variable en C
        asm volatile ("mrs %0, cpsr":"=r" (cpsr));  //cpsr = r5
        asm volatile ("mrs %0, spsr":"=r" (spsr));  //spsr= r6
        //asm volatile ("mov r2, r6");        //r2 = cpsr (de l'exception)

        send_uart("Handling data abort exception...\r\n\0");
        sprintf(adr,"Data abort exception at %p value 0x%lX\r\n", lnk_ptr,*(lnk_ptr));
        send_uart(adr);

        sprintf(cur_mode,"Current CPU MODE (cpsr): 0x%lX\r\n",&cpsr);
        send_uart(cur_mode);

        sprintf(exc_mode,"Exception CPU MODE (spsr): 0x%lX\r\n",&spsr);
        send_uart(exc_mode);

        sprintf(stack,"sp : 0x%lX\r\n",&dabort_dump);
        send_uart(stack);

        for(;;);

}</prev>


Regards.


Parents
  • Hi,

    You are right, but the problem is'nt really the need of the C but the C stack needed...
    If I want to use C and ensure safety on my system I have to ensure that my memory can be used to my C stack.
    So I need first in my boot program to test the memory in assembler, you are right !! ^^
    Sorry for my mistakes, Im learning slowly but Im learning !

    Thanks again !
    Regards

Reply
  • Hi,

    You are right, but the problem is'nt really the need of the C but the C stack needed...
    If I want to use C and ensure safety on my system I have to ensure that my memory can be used to my C stack.
    So I need first in my boot program to test the memory in assembler, you are right !! ^^
    Sorry for my mistakes, Im learning slowly but Im learning !

    Thanks again !
    Regards

Children
  • NNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOO

    "You are calling a number of C functions.
    You are relying on the processor having a valid stack for the processor mode it currently is in.
    You are assuming that the UART is in a good state.
    You are assuming that the baudrate generator is in a good state.
    You may (we haven't seen all code) be relying on the C RTL being in a good state."

    etc. etc. etc. !!!!

  • Note that the assembler code can always force itself to some stack space somewhere (as long as the hardware is working) if it is allowed to potentially overwrite the evidence of an error somewhere.

    Some people may have a debug build where the abort handler stays in a loop, while kicking the watchdog (at least for a limited amount of time), to allow a debugger to be connected and retrieve whatever evidence there may be about the problem.

    For a live system (especially a safety-critical system), you may possibly stay in the abort handler, after having tried everything to cut external power etc to whatever machinery that is controlled. Probably not a good alternative for an ABS system, but not all safety-critical systems have identical requirements or ways to reduce the risk.