This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

a quite stable Abort(data) in some projects on TMS570LS3137 and CCS6.0

  Hello!, I am new to not only ARM but also CCS and Windows.  I had been working on a project and encountered a quite stable Abort(data) in spite of not touching any hardware registers. It occurred after 10 to 20 times of source updates and builds. I realized that this problem can be worked around by copying an older project to create a new one and then copying source files into this project from the project in question.   However I would like to know why this problem occurred and how I can avoid it in the future.

  I clicked the STOP icon in the CCS's debug window and the Link Register was 0x457c. So I looked at the disassembly list.  It seems like

STR             R1, [R0]

is an instruction that caused the exception.  The R0 is pointing at the RAM area.  Why this exception occured?

-- snip from Registers --
Core Registers    Core Registers    
    PC    0x00000010    Program Counter [Core]    
    SP    0x00000000    General Purpose Register 13 [Core]    
    LR    0x0000457C    General Purpose Register 14 [Core]    
    CPSR    0x20000397    Stores the status of interrupt enables and critical processor status signals [Core]    
    R0    0x080083C0    General Purpose Register 0 [Core]    
    R1    0x08008324    General Purpose Register 1 [Core]    
    R2    0x000000A5    General Purpose Register 2 [Core]    
    R3    0x00000000    General Purpose Register 3 [Core]    
    R4    0x00000000    General Purpose Register 4 [Core]    
    R5    0x08000208    General Purpose Register 5 [Core]    
    R6    0x0800022C    General Purpose Register 6 [Core]    
    R7    0xFFFFFFFF    General Purpose Register 7 [Core]    
    R8    0x080018E0    General Purpose Register 8 [Core]    
    R9    0x00000000    General Purpose Register 9 [Core]    
    R10    0x00007500    General Purpose Register 10 [Core]    
    R11    0xFFFFFFB0    General Purpose Register 11 [Core]    
    R12    0x00000001    General Purpose Register 12 [Core]    
    R13    0x00000000    General Purpose Register 13 [Core]    
    R14    0x0000457C    General Purpose Register 14 [Core]    
USER_Registers    
    R8_USER    0x080018E0    General Purpose Register 8 in USER mode [Core]    
    R9_USER    0x00000000    General Purpose Register 9 in USER mode [Core]    
    R10_USER    0x00007500    General Purpose Register 10 in USER mode [Core]    
    R11_USER    0xFFFFFFB0    General Purpose Register 11 in USER mode [Core]    
    R12_USER    0x00000001    General Purpose Register 12 in USER mode [Core]    
    R13_USER    0x080018A8    General Purpose Register 13 in USER mode [Core]    
    R14_USER    0x0000056C    General Purpose Register 14 in USER mode [Core]    
FIQ_Registers    
    SPSR_FIQ    0x44011529    Stores the status of interrupt enables and critical processor status signals [Core]    
    R8_FIQ    0x00000000    General Purpose Register 8 in FIQ mode [Core]    
    R9_FIQ    0x00000000    General Purpose Register 9 in FIQ mode [Core]    
    R10_FIQ    0x00000000    General Purpose Register 10 in FIQ mode [Core]    
    R11_FIQ    0x00000000    General Purpose Register 11 in FIQ mode [Core]    
    R12_FIQ    0x00000000    General Purpose Register 12 in FIQ mode [Core]    
    R13_FIQ    0x00000000    General Purpose Register 13 in FIQ mode [Core]    
    R14_FIQ    0x00005478    General Purpose Register 14 in FIQ mode [Core]    
Supervisor_Registers    
    SPSR_SVC    0x6000031F    Stores the status of interrupt enables and critical processor status signals in supervisor mode [Core]    
    R13_SVC    0x080000B8    General Purpose Register 13 in Supervisor mode [Core]    
    R14_SVC    0x00005264    General Purpose Register 14 in Supervisor mode [Core]    
Abort_Registers    
    SPSR_ABT    0x20000392    Stores the status of interrupt enables and critical processor status signals in abort mode [Core]    
    R13_ABT    0x00000000    General Purpose Register 13 in Abort mode [Core]    
    R14_ABT    0x0000457C    General Purpose Register 14 in Abort mode [Core]    
IRQ_Registers    
-- pins --


-- snip from disassembly --
00004564:   E59F00FC LDR             R0, pxCurrentTCBConst
00004568:   E5900000 LDR             R0, [R0]
0000456c:   E590E000 LDR             R14, [R0]
00004570:   E59F00F4 LDR             R0, ulFPUContextConst
00004574:   E8BE0002 LDMFD           R14!, {R1}
00004578:   E5801000 STR             R1, [R0]
0000457c:   E3510000 CMP             R1, #0
00004580:   0A000002 BEQ             0x4590
00004584:   E8BE0001 LDMFD           R14!, {R0}
00004588:   ECBE0B20 VLDMIA          R14!, {D0-D15}
-- pins --

-- snip from link map --

MEMORY CONFIGURATION

         name            origin    length      used     unused   attr    fill
----------------------  --------  ---------  --------  --------  ----  --------
  VECTORS               00000000   00000020  00000020  00000000     X
  FLASH0                00000020   0017ffe0  00005948  0017a698  R  X
  FLASH1                00180000   00180000  00000000  00180000  R  X
  STACKS                08000000   00000200  00000000  00000200  RW  
  RAM                   08000200   0003fe00  000081dc  00037c24  RW 

-- pins --

   

Other info:

   CPU clock is 180MHz,

  Tried Clean the project, tried restarting the CCS, but not yet tried rebooting the Win box which uptime is 80 days.

 

Thank you  very much in advance.

masaki

 
   

  • Hello,
    I wrote ". I realized that this problem can be worked around by copying an older project to create a new one and then copying source files into this project from the project in question. ". But it was not a precise description. I copied the .c files but, I did not copy .h files. I copied the .h files and saw the problem occurs.
    By the aforementioned experience, I turned out to be able to describe the problem more accurately. The Abort(data) occurs if the union declaration contains an identifier.

    The following declaration causes the Abort(data).

    -- union with identifier --
    typedef struct _Message {
    char typeU;
    char typeL;
    unsigned short id;
    union {
    char c[64];
    signed short si[32];
    int i[16];
    float f[8];
    double df[4];
    } body;
    } Message; /* 64 bytes total */
    --

    The following declaration does not cause the Abort(data) but causes " ... warning #41-D: expected an identifier".

    -- union withou identifier --
    typedef struct _Message {
    char typeU;
    char typeL;
    unsigned short id;
    union {
    char c[64];
    signed short si[32];
    int i[16];
    float f[8];
    double df[4];
    } ;
    } Message; /* 64 bytes total */
    --

    I made a TI E2E web search using "Abort" and "union" and learned many guys experienced the phenomenon. I have not yet went through those cases. Anyway, is this a compiler bug?

    masaki
  • Hi Masaki,

    I'm not certain about your analysis using LR; because we have imprecise aborts on the CortexR4. These occur when the access is in the switch fabric and the CPU moves on to execute instructions past the one that causes the abort. The abort is returned sometime later (asynchronously) and that's why it's called imprecise.

    The system control coprocessor has some registers to help in this case. They are recommended over the LR. The registers to look at are the Data Fault Status, Data Fault Auxiliary Status, and Data Fault Address registers.
    The status will tell us if it's precise or imprecise and the address reg. will tell us where.

    It looks like the abort hit inside an ISR because the SPRS_abt has IRQ mode in it. So could be that it's a peripheral access causing the abort w. a delayed response. But the system control coprocessor registers will tell us for sure.

    I looked at one of the other posts on abort & struct/union but it seemed to be an issue of unaligned accesses. I don't *think* that's what's going on here based on the register dump but can't tell 100% because I don't know if you dumped the registers immediately at the abort vector or if you executed some additional code then dumped.
  • Hello Anthony,
    Thank you very much for the immediate answer. Here is my interim report:

    The register dump was made while the PC was pointing at the Abort(data) vector. So, I believe the LR and the R14_abt were holding a correct address. I do not know how to know whether the SPRS_abt is showing the abort was precise or imprecise one. But, both the LR and the R14_abt were holding the same address 0x457c.

    I suspected sizeof() function in CCS6.0 does not work correctly when the union declaration is lacking the union id. Tried the following test program.

    -- sizeofTest0.c --
    #include <stdio.h>

    typedef struct _MessageA {
    char typeU;
    char typeL;
    unsigned short id;
    union {
    char c[64];
    signed short si[32];
    int i[16];
    float f[8];
    double df[4];
    };
    } MessageA; /* 64 bytes total */

    typedef struct _MessageB {
    char typeU;
    char typeL;
    unsigned short id;
    union {
    char c[64];
    signed short si[32];
    int i[16];
    float f[8];
    double df[4];
    }body;
    } MessageB; /* 64 bytes total */

    main() {
    printf("sizeof(A) %d, sizeof(B) %d \n", sizeof(MessageA), sizeof(MessageB));
    }
    -- --

    Data structure MessageA does not contain union, while the other one, MessageB, does.

    Compiled the source code on CCS6.0 and then ran on R4. The result was:

    [CortexR4] sizeof(A) 4, sizeof(B) 72

    Compiled it by gcc4.8.2 and then ran on Win7. The result was:

    $ ./a.exe
    sizeof(A) 72, sizeof(B) 72

    In my project, the sizeof() function is called when creating queues by, such as:

    -- snip from main.c --

    helloQueue = xQueueCreate( 5, sizeof( Message)); -- multiple calls for total dozen queues

    xTaskCreate( (TaskFunction_t)prvHelloTask, "Ciao!", configMINIMAL_STACK_SIZE, NULL, 4, NULL ); -- multiple calls for total dozen tasks

    vTaskStartScheduler();

    -- pins --

    Best regards,
    masaki
  • Hi Masaki,

    Just to clarify, the way to tell exactly what is going on here is to check the registers in the system control coprocessor.
    You can view these through CCS's register window. The Data Fault Status register will tell us whether or not it's precise or imprecise and the address register will tell us what access caused the abort.

    If you are using FreeRTOS, recent updates (I think since the last year) default to putting tasks in USER mode unless otherwise specified - there is a different way to create tasks that run with privilege. For a USER mode task, it is very easy to trip a data abort if the MPU isn't setup properly.
  • Anthony,

      I created a Abort(data) handler as shown below:

    _dataAbort:

           MRC p15, #0, r0, c5, c0, #0  ;data fault status register

           MRC p15, #0, r1, c5, c0, #1  ;instruction fault status register

    _dA    b      _dA

      made the problem occur. Result is:

    R0 = 0x00000001   -- R/W = read, Status = Alignment

    R1 = 0x00000000

       I am wondering if the data fault status register was read correctly into the R0 by the handler. What do you think?

      Yes, I am using freeRTOS.

     

  • Hi Masaki,

    This looks like a good start for debug anyway, and it indicates an alignment fault.
    So that does point to a problem w. the structure access and probably is due to the 'short' member.

    But, instead of reading the 'instruction fault status register' - please capture the 'c6, Data Fault Address Register'.
    Then please check the address against that data structure and we should be able to see what was being accessed when
    the fault occurred.
  • Anthony,
    It has been ten days since I realized that the cause of the problem is QueueCreate() call with inappropriate queue item size. The problem was occurring in QueueReceive() while more number of bytes are being copied from the queue to the caller's memory space.
    Thank you very much for the support anyway. I enjoyed hacking.

    Masaki