This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

sd_ble_gatts_hvx() no return

Now i use sd_ble_gatts_hvx() to send data,it can not return anything while call this function. Step by step trace this function,while it run to code address 0x00016432,function compare two data,one data is store in 0x00016478( data value is 0xDEADBEEF),another data is store in 0x2000012c(data value is 0). If compare result is not equal ,function will fetch HardFault_handler entry and goto HardFault_handler. if manual update this data value from 0x00000000 to 0xDEADBEEF that store in 0x2000012c ,made it compare result is equal.then function is ok. What should i do to solve this program ?

Thanks!

Parents Reply Children
  • this is my code to call sd_ble_gatts_hvx().

    uint32_t ble_ccb_ll_cpt_send(ble_ccb_t * p_ccb, ble_ccb_write_t * p_write) { uint32_t err_code;

    if (p_ccb == NULL)
    {
        return NRF_ERROR_NULL;
    }
    // Send value if connected
    if (p_ccb->conn_handle != BLE_CONN_HANDLE_INVALID)
    {
        uint16_t               len;
        uint16_t               hvx_len;
        ble_gatts_hvx_params_t hvx_params;
    
        len     = p_write->len;
        hvx_len = len;
    
        memset(&hvx_params, 0, sizeof(hvx_params));
    
        hvx_params.handle = p_ccb->ccb_ll_cpt_handles.value_handle;
        hvx_params.type   = BLE_GATT_HVX_INDICATION;
        hvx_params.offset = 0;
        hvx_params.p_len  = &hvx_len;
        hvx_params.p_data = p_write->p_data;
    
        err_code = sd_ble_gatts_hvx(p_ccb->conn_handle, &hvx_params);
        if ((err_code == NRF_SUCCESS) && (hvx_len != len))
        {
            err_code = NRF_ERROR_DATA_SIZE;
        }
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
    }
    
    return err_code;
    

    }

    there is disassembly code to call sd_ble_gatts_hvx():

    646: err_code = sd_ble_gatts_hvx(p_ccb->conn_handle, &hvx_params);

    0x0001A8D6 88E0 LDRH r0,[r4,#0x06]

    0x0001A8D8 4669 MOV r1,sp

    0x0001A8DA DFA6 SVC 0xA6

    0x0001A8DC 4605 MOV r5,r0

    then branch to there:

    0x000006B0 4B01 LDR r3,[pc,#4] ; @0x000006B8

    0x000006B2 681B LDR r3,[r3,#0x00]

    0x000006B4 68DB LDR r3,[r3,#0x0C]

    0x000006B6 4718 BX r3

    and ,branch to there.why there need compare two data?0x0001645A start is fetch HardFault_Handler entry and branch to it.

    0x00016432 4A11 LDR r2,[pc,#68] ; @0x00016478

    0x00016434 4B0F LDR r3,[pc,#60] ; @0x00016474

    0x00016436 681B LDR r3,[r3,#0x00]

    0x00016438 429A CMP r2,r3

    0x0001643A D10E BNE 0x0001645A

    0x0001643C 4B0D LDR r3,[pc,#52] ; @0x00016474

    0x0001643E 2000 MOVS r0,#0x00

    0x00016440 6018 STR r0,[r3,#0x00]

    0x00016442 9801 LDR r0,[sp,#0x04]

    0x00016444 4B0D LDR r3,[pc,#52] ; @0x0001647C

    0x00016446 B504 PUSH {r2,lr}

    0x00016448 4798 BLX r3

    0x0001644A BC0C POP {r2-r3}

    0x0001644C 469E MOV lr,r3

    0x0001644E 4602 MOV r2,r0

    0x00016450 9802 LDR r0,[sp,#0x08]

    0x00016452 9900 LDR r1,[sp,#0x00]

    0x00016454 4B0A LDR r3,[pc,#40] ; @0x00016480

    0x00016456 681B LDR r3,[r3,#0x00]

    0x00016458 4718 BX r3

    0x0001645A 9806 LDR r0,[sp,#0x18]

    0x0001645C 9905 LDR r1,[sp,#0x14]

    0x0001645E 4B09 LDR r3,[pc,#36] ; @0x00016484

    0x00016460 681B LDR r3,[r3,#0x00]

    0x00016462 68DB LDR r3,[r3,#0x0C]

    0x00016464 4718 BX r3

    0x00016466 0000 MOVS r0,r0

    0x00016468 0134 LSLS r4,r6,#4

    0x0001646A 2000 MOVS r0,#0x00

    0x0001646C 0138 LSLS r0,r7,#4

    0x0001646E 2000 MOVS r0,#0x00

    0x00016470 013C LSLS r4,r7,#4

    0x00016472 2000 MOVS r0,#0x00

    0x00016474 012C LSLS r4,r5,#4

    0x00016476 2000 MOVS r0,#0x00

    0x00016478 BEEF BKPT 0xEF

    0x0001647A DEAD DCW 0x0000

  • Now ,i confirm sd_ble_gatts_hvx() should not be call in gpiote_event_handler().

  • You can call that from the GPIOTE event handler ... as long as the GPIOTE event handler runs at a ''lower'' priority than the SVC handler. That means GPIOTE handler must run at APP_LOW (priority 3) as the SVC handler runs at priority 2. If your GPIOTE handler is currently running at APP_HIGH (priority 1) then that's why you're getting the hardfault; you can't execute a SVC instruction from a higher priority context.

    If however that's what you were doing, the CPU would have gone directly to hardfault and not run any of that assembler, as soon as the SVC was executed, the CPU jumps directly there.

Related