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.

Exception Analysis on CC2650

Other Parts Discussed in Thread: SYSBIOS, CC2650

Hi,


I'm new to TI-RTOS. I'm using version tirtos_simplelink_2_13_00_06 on a CC2650DK. My code used to work fine, however since a few days exceptions occur. In a large project, that uses a lot of memory, this error occurred every time I ran the code:

"Cortex_M3_0: JTAG Communication Error: (Error -1170 @ 0x0) Unable to access the DAP. Reset the device, and retry the operation. If error persists, confirm configuration, power-cycle the board, and/or try more reliable JTAG settings (e.g. lower TCLK). (Emulation package 6.0.222.0)

Cortex_M3_0: Failed to remove the debug state from the target before disconnecting. There may still be breakpoint op-codes embedded in program memory. It is recommended that you reset the emulator before you connect and reload your program before you continue debugging"

I copied the code to a smaller project, where at the same positions in code, an exception was thrown instead of the error above. It is always caused by sin / cos function calls but sinf / cosf seem to work. It is also caused when calling the SPI transfer function, sometimes even at an if statement.

I used ROV to get a closer look at the exception, but it didn't really help. Here is the information I got from there:

Decoded exception,

Decoded,Hard Fault: FORCED: BUSFAULT: PRECISERR.Data Access Error. Address = 0xcc007f65

Exception context,

$addr,0x20001ae4

$type,ti.sysbios.family.arm.m3.Hwi.ExcContext

threadType,ti.sysbios.BIOS.ThreadType_Task

threadHandle,0x20002838

threadStack,0x20001520

threadStackSize,2048

r0,0xc008001

r1,0xffffffa1

r2,0x0

r3,0xdd008001

r4,0xffffff54

r5,0xe147ae15

r6,0xcc008001

r7,0xffffff64

r8,0xffffffff

r9,0xffffffff

r10,0xffffffff

r11,0xffffffff

r12,0x2

sp,0x20001bb0

lr,0x3445

pc,0x8d90

psr,0x21000000

ICSR,0x400803

MMFSR,0x0

BFSR,0x82

UFSR,0x0

HFSR,0x40000000

DFSR,0x1

MMAR,0xcc007f65

BFAR,0xcc007f65

AFSR,0x0

Exception call stack,

0         <symbol is not available>,PC = 0x00008D90 FP = 0x20001BB0

 

No matter where the exception is caused, the Data Access Error address stays the same. PC points into $Tramp$TT$L$PI$$ti_sysbios_family_arm_m3_Hwi_construct(). $addr seems to change depending on where the error was caused, but I can't really make sense of where it points to.

The exception also occurs when the code runs without debugging. I already tried increasing stack and heap for both the BIOS and the task, but that didn't help.
 I can't remember changing anything besides implementing a new function, which currently isn't in use, since the code worked.

I could replace all sin / cos with sinf / cosf, but I need to use SPI. So how can this problem be solved?  Is there a way I can find the exact cause of the exception?

 

Thanks in advance and best regards,

Manuel

  • Hi Manuel,
    Can you use ROV to verify that the Task stacks have not overrun?
    Thanks,
    Janet
  • Hi Janet,

    this is what ROV shows for the task when the exception occurred:

    I increased the stack size before to see if it solves the issue (that's why it's that large), but it still remains.

    Best regards,


    Manuel

  • Hi Manuel,
    It looks like the task with the large stack is preempted, so I wonder what was actually running. From the exception dump, it appears that the bus fault is caused by an access to the address 0xcc007f65, which doesn't look like a valid address. Can you look at the addresses LR to see what was calling the code that caused the exception? And PC is always pointing to an address related to Hwi_construct? You could try looking at the disassembly code near where the exception occurred and set a breakpoint.
    Best regards,
    Janet
  • Hi,

    I checked the address in LR after the exception, I'm not exactly sure where it leads to, the function is labelled with $C$L607. Is there a way to see all the commands that call this function?

    Using another CC2650 and SmartRF06 doesn't solve the problem.

    I went through the code in disassembly to find the functions that cause the interrupt. I had a closer look at the sin() function as this is where I always get the exception. This is the code:

    106         float x = sin(28);

    000053e2:   A032               adr       r0, #0xc8

    000053e4:   C803               ldm       r0, {r0, r1}

    000053e6:   F002FE0F           bl         #0x8008

    000053ea:   F001FA20           bl         #0x682e

    000053ee:   9044               str       r0, [sp, #0x110]

    The first bl leads to:

             $Tramp$TT$L$PI$$ti_sysbios_family_arm_m3_Hwi_construct():

    00008000:   F8DFF000           ldr.w     pc, [pc, #0]

    00008004:   AF29               add       r7, sp, #0xa4

    ...

    But it doesn't lead to the start of the function, is it intended to be this way?

    Is the HWI used for function calls or is this already the position where the exception is caused?

    The other sin() functions in my code also have this bl command to the same position.

    Going further from this point somehow leads to this without returning to the sin() function:

    ...

    1001bbd4:   6812               ldr       r2, [r2]

    1001bbd6:   2A00               cmp       r2, #0

    1001bbd8:   D0FD               beq       #0x1001bbd6

    1001bbda:   4790               blx       r2

    R2 at that point:

    R2           0x000062E1        General Purpose Register 2 [Core]         …

     Which leads to the exception handler:

             ti_sysbios_family_arm_m3_Hwi_excHandlerMin__I():

    000062e0:   B530               push       {r4, r5, lr}

    If the sin() is replaced with sinf(), there is no call of the  HWI constructor:

    float x = sinf(28);

    0000642e:   4830               ldr       r0, [pc, #0xc0]

    00006430:   F7FAFFB6            bl         #0x13a0

    00006434:   9044               str       r0, [sp, #0x110]

    ...

     Here bl leads to:

             sinf():

    000013a0:   49C3               ldr       r1, [pc, #0x30c]

    000013a2:   E92D4FF0           push.w     {r4, r5, r6, r7, r8, r9, r10, r11, lr}

    ...


    Should the sin() functions contain a call of the HWI constructor function? If no, how can they be removed? And if yes, what's their purpose? Do they cause the exception?

    Edit: Some more information: I made some changes to the .cfg file (mostly stack/heap sizes) and the project properties (compiler optimization, there could be some more changes that I don't remember) before the problem occurred. Could any of this have caused this problem? Is creating a new project resetting the .cfg file completely? When doing this, some of the stack/heap values still remain.

    Best regards and thanks for your help,

    Manuel

  • Hi Manuel,
    The sin() function should not branch to the Hwi constructor. Do you have a simple test case project you could send so we can try to debug this?
    Thanks,
    Janet
  • Hi Janet,

    I observed that the error only occurs when most of my software components are copied to the project directory. If there is only the component in which the exception is caused is in the project folder, it works fine, no exception. However, if I copy more components at some point it will start to crash. The files don't even have to be included in the code for this to happen, they just need to be in the project folder in the workspace. I can't make sense of this.

    I'm not allowed to upload most parts of the code so sadly I can't provide a test case project. Is there any other way we can find the cause?

    Best regards,

    Manuel

  • Hi Manuel,
    Can you tell us what compiler/linker your are using (TI, GCC, or IAR), and what version? Also, what are the compiler and linker options you are using?
    Thanks,
    Janet
  • Hi Janet,

    I'm using the TI v15.12.1.LTS compiler.

    Compiler options are:

    -mv7M3 --code_state=16 -me -Ooff --opt_for_speed=0 --include_path="C:/ti/tirtos_simplelink_2_13_00_06/products/cc26xxware_2_21_01_15600" --include_path="C:/Users/<username>/workspace_v6_1_3/<project name>" --include_path="C:/ti/ccsv6/tools/compiler/ti-cgt-arm_15.12.1.LTS/include" -g --gcc --diag_wrap=off --diag_warning=225 --diag_warning=255 --display_error_number --gen_func_subsections=on --abi=eabi

    Linker options:

    -mv7M3 --code_state=16 -me -Ooff --opt_for_speed=0 -g --gcc --diag_wrap=off --diag_warning=225 --diag_warning=255 --display_error_number --gen_func_subsections=on --abi=eabi -z -m"<project name>.map" --stack_size=256 --heap_size=0 -i"C:/ti/ccsv6/tools/compiler/ti-cgt-arm_15.12.1.LTS/lib" -i"C:/ti/ccsv6/tools/compiler/ti-cgt-arm_15.12.1.LTS/include" --reread_libs --display_error_number --warn_sections --diag_wrap=off --xml_link_info="<project name>_linkInfo.xml" --rom_model


    Thanks and best regards,

    Manuel

  • Hi Manuel,

    We need to verify that a trampoline is being used in your call to sin().  Can you check that there is something similar to the following in your .map file:

    FAR CALL TRAMPOLINES

     

    callee name               trampoline name

       callee addr  tramp addr   call addr  call info

    --------------  -----------  ---------  ----------------

    sin                       $Tramp$TT$L$PI$$sin

       00000725     f0000018     f0000002   try1.obj (.text)

    Thanks,

    Janet

  • Hi Janet,


    I checked the map files of several projects, some with sin(), some only with sinf(), but none of those contain any entries for sin() or sinf() in the trampoline section (not even the working ones with sin() functions).

    Best regards,

    Manuel

  • Hi Manuel,

    Can you post a screen shot of the disassembly window in CCS showing the address in the first branch (0x8000, if 0x8008 is still the address)?  If this is a trampoline, you should be able to figure out where it's supposed to go by piecing together the two following words.  For example, if you look at the trampoline for Task_sleep() below, combine the two highlighted words to get 1001A96C, which in my program is the address of Task_sleep().

    Also, what is at the address of the the second branch (0x682e).  I'm guessing it is something like __eabi_d2f.

    So far, I haven't been able to reproduce your failure with calls to sin() and sinf().  Are these functions from rtsv7M3_T_le_eabi.lib, or do you have your own?

    Thanks,

    Janet

  • Hi Janet,


    thanks for asking about which sin() functions I'm using, I guess I found the cause. It was a pretty stupid mistake I totally forgot about: before the error occurred,  I tried implementing my own sine function, and for that I created a lookup table called sin[ ] (without thinking about the function sin()). Now that I went back to trying to access the sin() function in math.h, the array caused an interference as soon as the containing file was copied into the project folder. Now that I renamed the array, the code works fine.


    Sorry for making work, and thank you very much for helping me find the cause of the problem!

    Best regards,

    Manuel

  • Hi Maunel,

    I'm so glad to hear you found the problem!

    Best regards,

    Janet