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.

Parents
  • 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,

Reply
  • 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,

Children
Related