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.

printf generates a data abort

Other Parts Discussed in Thread: RM48L952, HALCOGEN

Hello,

I have a rather peculiar problem. Whenever I try to use the printf it causes a data abort in my RM48L952.

Maybe it could be a problem in the bootloader? Maybe I'm not initiating the compiler requirements properly?

PS: I wrote my own bootloader.

  • Pablo,

    Where is your printf function coming from?  Compiler library or did you implement your own.  Which compiler if it's a compiler.

    Also are you sure it's a data abort and not an UNDEF instruction abort.  And what instruction caused the abort / what data area was it trying to access when the abort occurred?

    -Anthony

  • I included stdio.h and included the full printf in the project properties.

    I'm using CCS 5.4, compiler TI v5.0.4

    This is my init vectors:

    	b	bootAfterReset
    undefEntry
            b   undefEntry
    svcEntry
            b   svcEntry
    prefetchEntry
            b   prefetchEntry
    dataAbortion
            b   _asm_dataEntry
    reservedEntry
            b   reservedEntry
            ldr pc,[pc,#-0x1b0]
            ldr pc,[pc,#-0x1b0]

    It jumps to _asm_dataEntry.

    It comes from 0x1FA8, instruction: LDR R0, [R0, #0x4]

              mremove:
    00001f82:   4961     LDR             R1, $C$CON2
    00001f84:   1D09     ADD             R1, R1, #0x4
    00001f86:   680A     LDR             R2, [R1]
    00001f88:   2300     MOV             R3, #0x0
    00001f8a:   E00A     B               $C$L3
              $C$L1:
    00001f8c:   4290     CMP             R0, R2
    00001f8e:   D106     BNE             $C$L2
    00001f90:   2B00     CMP             R3, #0x0
    00001f92:   BF08     IT              EQ
    00001f94:   6840     LDR             R0, [R0, #0x4]
    00001f96:   D007     BEQ             $C$L4
    00001f98:   6840     LDR             R0, [R0, #0x4]
    00001f9a:   6058     STR             R0, [R3, #0x4]
    00001f9c:   4770     BX              R14

    This happens every single time I do the printf

  • Pablo,

    So you're in a memory management routine (file memory.c from the runtime library) when this abort occurs.
    Probably this means there is an issue with the heap (like you don't have a big enough heap in your linker file).

    But, I'd like to see the call stack when you are stopped at the instruction causing the problem so that I can better understand how you got there.   Just skimmed through printf.c and _printfi.c and don't see the path to memory.c but it's hard to see if you are unfamiliar with the implementation like I am.  Call stack would be better.

    Also I'm assuming that you are not explicitly calling any of the malloc() type functions and that this is being done from the inclusion of printf() ... is that accurate?  And you're not using C++'s 'new' either ?

  • Pablo,

    When using the STDIO routines, it is necessary to have the following entry in your linker command file. (in RED)

    /*----------------------------------------------------------------------------*/
    /* Memory Map */

    MEMORY
    {
    VECTORS (X) : origin=0x00000000 length=0x00000020
    FLASH0 (RX) : origin=0x00000020 length=0x0017FFE0
    FLASH1 (RX) : origin=0x00180000 length=0x00180000
    STACKS (RW) : origin=0x08000000 length=0x00001500
    RAM (RW) : origin=0x08001500 length=0x0003eaff

    /* USER CODE BEGIN (2) */
    /* USER CODE END */
    }

    /* USER CODE BEGIN (3) */
    /* USER CODE END */


    /*----------------------------------------------------------------------------*/
    /* Section Configuration */

    SECTIONS
    {
    .intvecs : {} > VECTORS
    .text : {} > FLASH0 | FLASH1
    .const : {} > FLASH0 | FLASH1
    .cinit : {} > FLASH0 | FLASH1
    .pinit : {} > FLASH0 | FLASH1
    .bss   : {} > RAM
    .data  : {} > RAM
    .sysmem : {} > RAM

    /* USER CODE BEGIN (4) */
    /* USER CODE END */
    }

     

    Please have a try and let me know.

  • my heap_size=0x800 .. I changed it to 0x8000 just in case but the same thing happened. My call stack? I got the picture above, and you're right to assume that I'm not calling malloc() explicitly, it's the printf function that's doing it, neither am I using C++, nor C++'s 'new

     '

  • The moment it said it didn't have a .sysmem SECTION I realized what that meant and immediately added the .sysmem SECTIOn to my linker

  • Pablo,

    On the LDR R0, [R0, #0x4], what is the value of R0?

     

  • Before I answer your question let me walk you through what I saw today.

    First: i did an assemby step into on printf, and noticed that instruction that was causing a data abort was a POP {R3, PC} @0x1F80, where R3=0x100 and PC = 0x1F80, but it still was saying that the other address caused the error.

    While stepping throuh the error treatment I noticed that it wasn't catching the flash error flag, which made me go through all my code again (I only used HALcogen at a few points where I was missing 1 bit to configure, but all the code was made entirely by me following the SPNA106D to the letter).

    This can only mean one thing, somewhere I forgot to set a register to  enable this exact function, which is strange because I can see and treat RAM errors without a problem, and 1 bit errors are caught by the code in the ESM module. It just doesn't catch 2 bit errors, and I suppose that any other errors might be causing the same problem here.

    At some point I must have changed a subs pc, lr, 8 with a subs pc, lr, 4, which is why just now I changed my data abort treatment to the one made by HALcogen just to verify what could be wrong and was able to catch that error.

    I think that if I'm able to solve this problem I'll have a better idea of what migh be wrong.

    Sorry to lay all of this on you all, but this is the best way I can learn, by talking the problem out with someone that knows what's going on, because I get lost sometimes.

    PS:

    Flash related operations:

    --- /** -Enable the flash interface module's response to an ECC error indicated by the CPU on accesses to flash*/
        FLASHReg->FEDACTRL1 |= 0xA060AU;

    --- /** -Enable the CPU's Event Bus export mechanism*/
        _asm_enableCPUeventBus();

    --- /** -Enable the CPU's Single-Error-Correction Double-Error-Detection (SECDED) logic for accesses to Flash memory (CPU's ATCM interface)*/
        _asm_enableECClogic();

    ---

    /** -Configure Flash Access*/
        FLASHReg->FRDCNTL = ( 0x1U          /* -Enables Pipeline mode (0x1U)*/
                            | 0x10U         /* -Address Setup Wait State Enable (0x10U)*/
                            | 0x300U);       /* -Random/data Read Wait State (0x300). According to the Datasheet, at this speed it requires 3 wait states */
        
        FLASHReg->FSM_WR_ENA = 0x5U;    /*Flash State Machine Write Enable. 0x5U enables*/            
        FLASHReg->EEPROM_CONFIG =   ( 0x2U /*Auto-suspend Startup Grace Period
                                                The FMC will wait 16 HCLK periods for each count in the AUTOSTART_GRACE field. A
                                                value of 2 will wait for 32 periods after the last access. Each access will reset the counter to
                                                the AUTOSTART_GRACE value * 16.*/
                                    | 0x30000U); /*EEPROM Wait state Counter*/
    
        FLASHReg->FSM_WR_ENA = 0xA;
    
        /*step 15*/
        /** -Set up Flash bank and pump power modes*/
        FLASHReg->FBFALLBACK =  (  0x0U
                                | (3U << 14)
                                | (3U << 2U)
                                | 3U);
    
        FLASHReg->FPAC1 =   ( 0x0
                            | (1U << 16U)
                            | (0xFFU));
    

    --- /*step 17*/
        /** -Run the self-test on the SECDED logic embedded inside the Flash module*/
        flashSECDED();

    --- /*step 30*/
        /** -Run the self-test on the CPU's SECDED logic for accesses to the main Flash memory*/
        checkFlashECC();

    This step 30 is where it gets stuck when it checks for a 2 bit error

  • Hello,

    The problem I stated earlier doesn't happen anymore. But still the printf functiomn doesn't work properly. It still generates a data abort.

    Doing assembly stepping I found out that the POP instruction (in grey) is the one generating the abort. After I do another assembly stepping it just goes into a data abort and puts the wrong address in the LDR register.

    Here's an image at the moment before the data abort occurrs.

    Here's an image when t gets to the abortion, one step after the pop instruction

  • Pablo,

    By looking to the registers dump before the pop instruction, the stack pointer (SP/R13) seems to be corrupted or overflowed.
    The CPU decrement SP on each push or store to the stack.
    SP=0x07FFFE08 this is not pointing to RAM anymore.
    Can you set a breakpoint on the printf call to see at that point where is the SP?

  • Sorry it took me so long to answer. I was in a meeting all afternoon.

    The value of SP = 0x080000D8. It goes to an incorrect area in printfi in the pointer line.

                  _printfi:
       00000b3e:   E92D4FF0 STMDB.W         R13!, {R4, R5, R6, R7, R8, R9, R10, R11, R14}
    ->00000b42:   F5AD7DFE SUB.W           R13, R13, #508
       00000b46:   F1AD0D30 SUB.W           R13, R13, #48

  • Pablo,

    What I will suggest it to increase the size of the stack to overcome this problem.
    If you are using HalCoGen, this can be done in the RAM Tab.

    Please let me know if this will fix the problem.

  • Hi,

    I did what you suggested and the exception stopped happening. But I don't see anything comming out the console. I think I should  change the console view to CIO, but I don't see the option (OBS: none of the views show anything and I'm printing the string "testing").

  • Pablo,


    Here is a test program for RM46 (I don't have right now an RM48)

    The Halcogen project is also included.

    8015.Printf.zip

    Here is also a screen capture:

  • Here's my print screen:

    As you can see I have everything enabled. But I found somerhing in Enable CIO function use it says that a break point is required. I am doing the entire boot process, meaning that I do an STC check, which causes a reset. After all breakpoints stop working.

    Is there a chance that this could be the reason?

  • Or maybe my initialization code is wrong? could it be that I'm not initializng the copy table, global variables and  constructors correctly? It's step 43 in the spna106d document (rev may 2013). I copy pasted the code related to this and added the folowing to an asm file:

        .def    __TI_PINIT_Base, __TI_PINIT_Limit
        .weak   SHT$$INIT_ARRAY$$Base, SHT$$INIT_ARRAY$$Limit
    
    __TI_PINIT_Base  .long SHT$$INIT_ARRAY$$Base
    __TI_PINIT_Limit .long SHT$$INIT_ARRAY$$Limit

    All according to the init code generated by HALcogen. And doing the search in the code you gave me, I can see that I did that as I was supposed to.

    Sorry to keep bugging you about all this, but it seems that I made a little mistake along the way and I'm unable to find it.

  • Pablo,

    Yes running STC will completely restart the debug unit (part of the CPU). So after STC, all breakpoint (Hardware breakpoint because you are running out of Flash) will be disable.
    It should be possible to save the debug context before running the STC and than to restore everything when it is done.

    To verify if this is your problem, I will suggest just for a test to disable STC and see ig your printf are working.
    Another option is to try a printf before the call to the STC routine.

  • Sorry it took me so long to answer. I was out sick for a day and a half.

    It worked. It was because of the STC check after all. The second I jumped to afterSTC it worked like a charm.

    Thank you so much for your help.