Could you please add a new API into esb.c to replace 'esb_write_payload'?

 As we know, currently we can only pass a totally struct of esb_payload to this function and then it will be copied to payload queue internally. Normally, this process would take 2 times memory copy at least.
Maybe you can add an new interface similar as esb_write_data(uint8_t pipe, const uint8_t * data, uint8_t length, uint8_t noack)? You can then pick an instance from the payload queue and fill the struct items directly. I think it will be more efficient.

  • Hi,

     

    Thank you for the feedback. If I understand your suggestion; you want to expose the internal FIFO, and write to it directly.

    I will relay this back to our ESB developers.

     

    I wish you a wonderful day!

     

    Kind regards,

    Håkon

  • Dear Sir,

    Thank you for your response.

    I believe that exposing the internal FIFO directly is not appropriate. Instead, I would like to propose a small refinement to the current API, as illustrated below:

    int esb_write_data(uint8_t pipe, const uint8_t *data, uint8_t length, uint8_t noack) {
        /* Perform operations similar to esb_write_payload */
        ...

        /* Replace the original memcpy(tx_fifo.payload[tx_fifo.back], payload, sizeof(struct esb_payload)) with the following: */
        tx_fifo.payload[tx_fifo.back]->pipe = pipe;
        tx_fifo.payload[tx_fifo.back]->noack = noack;
        tx_fifo.payload[tx_fifo.back]->length = length;
        memcpy(tx_fifo.payload[tx_fifo.back]->data, data, length);

        ...
    }

    As you can see, this modified version copies user data into the FIFO only once. In the original function, the user is required to first copy data into a struct esb_payload, and then pass that structure to esb_write_payload, which performs a second copy into the FIFO.

    With the proposed change, we eliminate one redundant copy operation, which I believe is worth careful consideration.

    Thank you again, and kind regards.

  • Hi,

     

    I am sorry, but I do not understand your current suggestion, or how that will compile down to faster executing code.

    Your suggestion, by changing function esb_write_payload, currently includes manual population/translation of FIFO struct members, and a memcpy of the payload content. Can you please expand on how this is different to the current solution, which copies the full payload, including meta-data that the protocol requires?

    You also mention two memcpy operations, where is the second one?

     

    Kind regards,

    Håkon

  • Hi Håkon,

    You mentioned that the current 
    esb_write_payload function performs one memory copy internally, but you seem to have overlooked the fact that the user must pass an esb_payload object when calling this function. A typical user call might look like this:

    void esb_send_data(const uint8_t * user_data, size_t len)
    {
        struct esb_payload payload = {
            .pipe = 1,
            .noack = true,
            .length = len,
        };
        memcpy(payload.data, user_data, len);
        esb_write_payload(&payload);
    }

    As you can see, isn’t it necessary to call memcpy once to copy the user data into the esb_payload structure before passing it to esb_write_payload?

    Kind regards,

  • Hi,

     

    You could pipe your data directly into the payload.data member to avoid this scenario.

    Another option is that you manually change the esb library to better fit your application.

     

    Kind regards,

    Håkon

Related