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.

Number of Data Pointers (DPTR) for CC2540

Other Parts Discussed in Thread: CC2540

The CC2540 spec. says there are 2 DPTR. When I setup the sample code project "Simple BLE Peripheral - CC2540 Slave" for 2 data pointers I get the following error message from IAR IDE:

Error[e117]: Incompatible runtime models. Module att_server specifies that '__number_of_dptrs' must be '1', but module OSAL has the value '2'

When setting up for 1 DPTR, the compiler/linkers runs ok. What is meant by "att_server module"?

Also, the IAR file "CC2540F256.i51" states only 1 DPTR:

[PROCESSOR]

name=plain

bank_nr_of=0x07

bank_reg_addr=0x9F

bank_reg_mask=0xFF

bank_start=0x8000

[DPTR]

nr_of=1

size=16

switch_method=INC

switch_mask=0xFF

addr_DPS=0x92*)

addr_DPL1=0x84*)

addr_DPH1=0x85*)

pdata_bank_reg_addr=0x93

*) These statements make no sense (greyed out in the IAR options menue) when there is just 1 DPTR.

  • There are two data pointers on the CC2540, but the BLE library is built with the one data pointer setting, and this must then also be used for the application. The reason for this is that IAR does not do a good job of utilizing extra data pointers, and when testing, we have found it to perform worse that the one data pointer setting.

    You should not need to modify the project settings of the sample code projects.

  • Thanks for the info. But I couldn't believe that a second pointer can make things slower. Dow you have code samples (assembly listings) that show how IAR is unable to benefit from the second pointer? Or has it to do with the BLE stack itself, e. g. if there are no xdata-to-xdata moves and saving/restoring an (unused) pointer produces big overhead?

    2nd question: Why can different code not be mixed up (e. g. library with 1 ptr, application with 2 ptrs)? Is it a matter of calling convention or interrupt handling (what to save on the stack)?

  • These questions are really questions for IAR, and you should direct them there. I am not sure if anyone from IAR follows this forum.

    The observation that specifying two data pointers reduces performance is a general observation, and all our software products and examples for 8051 therefore use the 1 dptr setting. I don't think this was re-evaluated for the BLE stack. While there do exist cases where performance is improved specifying two data pointers, an example as simple as the one below demonstrates the opposite. I built this example with maximum optimizations, balanced between speed and size. Selecting two data pointers makes both speed and size worse.

    unsigned char buffer1[100] = {
        140, 67, 152, 12, 146, 179, 246, 192, 189, 110, 162, 205, 21, 242, 234,
        154, 64, 223, 131, 187, 108, 246, 18, 141, 74, 219, 85, 174, 13, 91, 127,
        111, 143, 157, 29, 229, 193, 202, 208, 171, 51, 69, 160, 137, 15, 22, 69,
        104, 121, 232, 152, 84, 122, 152, 41, 212, 244, 152, 7, 207, 156, 179, 23,
        108, 96, 42, 213, 214, 115, 244, 37, 222, 196, 113, 158, 243, 163, 63, 90,
        48, 125, 104, 118, 156, 18, 80, 155, 44, 158, 62, 150, 129, 118, 138, 241,
        87, 102, 78, 105, 73};
    unsigned char buffer2[100] = {
        100, 128, 184, 78, 28, 113, 119, 3, 169, 185, 72, 67, 181, 200, 252, 121,
        231, 115, 205, 212, 42, 100, 133, 183, 145, 117, 113, 22, 113, 93, 77, 218,
        194, 243, 142, 3, 152, 208, 250, 56, 180, 133, 238, 182, 58, 115, 44, 248,
        91, 12, 193, 229, 73, 64, 238, 33, 240, 179, 217, 53, 116, 20, 217, 143,
        81, 95, 222, 95, 18, 51, 12, 145, 31, 133, 29, 197, 96, 210, 11, 153, 242,
        73, 227, 26, 16, 59, 238, 16, 67, 255, 54, 127, 74, 172, 245, 196, 170, 33,
        24, 3};
    unsigned char buffer3[100];

    int main(void)
    {
        unsigned char i;
        for (i=0; i<100; i++) {
            buffer3[i] = buffer2[i]+buffer1[i];
        }
        return 0;
    }

     

  • Hi.

    That's a funny demo. When having 3 DPTR, try "buffer4[i] = buffer3[i] + ..."

    The produced code using N-1 DPTR (i. e. 2 DPTR here) seems to be 2 bytes longer (70 instead of 68 bytes in the inner loop). Optimization mode balanced/size/speed doesn't change it though. But what you call "worse" is in fact an epsilon only.

    Having 2 DPTR available for e. g. just "buffer1[i] = buffer0[i];" gains a bit more than it looses in above example. IAR is far away from having a good optimizing compiler. Hand-made assembly code could be faster by at least a factor of 2. (For this example, if you would align all three buffers on modulo-256 addresses, speed-up could reach 6~8.)

    However, the main question is why 1-DPTR code cannot be mixed up with 2-DPTR code. I would like to make use of 2 DPTR for my application, even if the library is compiled for 1. Does anyone know why this is not allowed?

  • It's a long shot replying to a long-dead post, but 6 years later the same problem exists using BLE STACK 1.4.0. I tried setting up 2 datapointers because I thought it might make the generated code more efficient, but I still get:

    Error[e117]: Incompatible runtime models. Module ADSCallback specifies that '__number_of_dptrs' must be '2', but module att_server has the value '1'