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.

Help! the input param of one function was changed when running TIMAC-CC2530-1.3.0!

Other Parts Discussed in Thread: TIMAC

Hi,


 when I running my own application  program  together with TIMAC-CC2530-1.3.0, a very strange error confused me, the input parameter of one function can be changed!
 
 Let's start  at in line 149 of mac_backoff_timer.c:
 
 void macBackoffTimerInit(void)
 {
   ...
   MAC_RADIO_BACKOFF_SET_COUNT(0);
  ...
 }

where micro MAC_RADIO_BACKOFF_SET_COUNT was defined as this:
#define MAC_RADIO_BACKOFF_SET_COUNT(x)                macMcuOverflowSetCount(x)

and the defination of macMcuOverflowSetCount():
void macMcuOverflowSetCount(uint32 count)
{
  halIntState_t  s;

  MAC_ASSERT(! (count >> 24) );   /* illegal count value */
  ...
}

As you see, the TIMAC  passed a const value of 0 into function macMcuOverflowSetCount() , but when I debuged into it, the input value "count" looked like this:
Expression  Value       Location      Type
count       0x560412E9  XData:0x04E3  uint32

and the program really hanged int the next line  MAC_ASSERT!

I only added my own application, did not changed anything inside TIMAC and link files.

  • I have run into the exact same problem.  I am implementing an application with TIMAC-1.4.0 on a CC2533F96 using the banked code model, banked library (macLib_cc2530-Banked.lib), and linker script based on the banked example project (ti_51ew_cc2533b.xcl).

    The root cause is the following.

    In addition to the configuration described above, the constant placement is set as "ROM mapped as data" (--place_constants=data_rom) only because the stack library (macLib_cc2530-Banked.lib) is built this way (it depends on the symbol mac_cfg.c::macCfg which is an external declared with __xdata_rom).  We manage our string constants using explicit CODE declarations and would rather use the "RAM memory" constant option, for reasons outlined at the end of the post.

    To implement "ROM mapped as data", one has to understand what that means.  In the context of the 2533F96 (i.e. a device with 2 banks+root bank), it means that one of these 3 banks is mapped into XDATA starting at 0x8000.  The IAR toolchain requires that the segment "XDATA_ROM_C" is defined in the user's linker script.  The 2533 TIMAC banked example attempts to do this as follows:

    // Define segments for const data in flash.
    // First the segment with addresses as used by the program (flash mapped as XDATA)
    -P(CONST)XDATA_ROM_C=0x8000-0xFFFF
    //
    // Then the segment with addresses as put in the hex file (flash bank 1)
    -P(CODE)XDATA_ROM_C_FLASH=0x18000-0x1FFFF
    //
    // Finally link these segments (XDATA_ROM_C_FLASH is the initializer segment for XDATA_ROM_C,
    // we map the flash in the XDATA address range instead of copying the data to RAM)
    -QXDATA_ROM_C=XDATA_ROM_C_FLASH

    What this says is that the constants are located in XDATA starting at 0x8000 (check), a new segment is assigned into bank 1to contain the actual constants (check), and that the bank 1 segment is used to initialize XDATA_ROM_C (check - although the hardware does the mapping).  The problem is, the device starts up with the root bank mapped into XDATA at 0x8000 (Register MEMCTR 2:0 = [000]), which puts garbage into XDATA_ROM_C!

    I have found no indication that the IAR toolchain has any knowledge of this register, nor the example application (e.g. through a board config register setting).  There may be a number of users with dubious applications based on the TIMAC banked example.

    To set this up correctly, the user's board config could set register MEMCTR 2:0 = 001 (In my opinion not particularly desirable).  One might think that setting XDATA_ROM_C_FLASH=0x0000-0x7FFF would locate the constants into the desired root bank (it does), but this is not correct because the constants segment is placed after many other segments (on my platform they get placed at around 0x3900) but are still placed in XDATA right at 0x8000 (which means they are mapped into XDATA 0xB900 and not at the expected 0x8000).  I got this working by fixing the range similarly for both XDATA_ROM_C and XDATA_ROM_C_FLASH, that is, at 0xC000-0xFFFF and 0x4000-0x7FFF.  This is fragile and will blow up if the prior segments move beyond 0x4000 in the root bank.  If there's a better way to do this, I'd like to know.

    Now, about the constants in code memory.  To identify the root cause of this problem, I had to do some instruction tracing.  Doing so was an eye-opener as I discovered the inefficiency of the 8051 architecture when dealing with the banked code model and in particular the XDATA stack (vs. the IDATA stack).  A constant, e.g. the '0' in macMcuOverflowSetCount(0), is obtained as follows using the "ROM mapped as code" option:


    macBackoffTimerInit:
     02924D  C0 82           PUSH  DPL
     02924F  C0 83           PUSH  DPH
     029251  90 C0 82        MOV   DPTR,#0xC082
     029254  12 10 57        LCALL ?XLOAD_R2345
     029257  12 15 05        LCALL macMcuOverflowSetCount::?relay

    Where XLOAD_R2345 is: 


    ?XLOAD_R2345:
     001057  E0              MOVX  A,@DPTR
     001058  FA              MOV   R2,A
     001059  A3              INC   DPTR
     00105A  E0              MOVX  A,@DPTR
     00105B  FB              MOV   R3,A
     00105C  A3              INC   DPTR
     00105D  E0              MOVX  A,@DPTR
     00105E  FC              MOV   R4,A
     00105F  A3              INC   DPTR
     001060  E0              MOVX  A,@DPTR
     001061  FD              MOV   R5,A
     001062  22              RET

    All this for a 0?  And this is just to get into the function.  The function goes absolutely nuts trying to process the equivalent MAC_ASSERT(count >> 24) for the MAC_ASSERT:

    macMcuOverflowSetCount:
     003ADD  74 F4           MOV   A,#0xF4
     003ADF  12 09 4D        LCALL ?BANKED_ENTER_XDATA
     003AE2  74 FC           MOV   A,#0xFC
     003AE4  12 0E 96        LCALL ?ALLOC_XSTACK8
     003AE7  12 3C 33        LCALL 0x3C33
     003AEA  85 10 82        MOV   DPL,XSP(L)
     003AED  85 11 83        MOV   DPH,XSP(H)
     003AF0  78 08           MOV   R0,#0x08
     003AF2  12 10 20        LCALL ?L_MOV_X
     003AF5  90 C0 9E        MOV   DPTR,#0xC09E
     003AF8  78 08           MOV   R0,#0x08
     003AFA  12 0F 4C        LCALL ?L_AND_X
     003AFD  12 3B C1        LCALL 0x3BC1
     003B00  60 03           JZ    0x3B05
     003B02  12 12 A7        LCALL halAssertHandler::?relay
     ....

    The '?...' LCALLs are in turn large instruction sequences themselves.