This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

IEEE802.15.4 in zephyr

Hello,

we started using zephyr OS for our firmware projects. To implement a propriety protocol on top of IEEE802.15.4 I use the radio with CONFIG_IEEE802154_RAW_MODE=y in the prj.conf. For a first test I use this function to send a frame.

void send_frame()
{
    struct net_pkt *pkt;
    struct net_buf *buf;
    uint8_t         data[14];
    static uint8_t  seq_num = 0;

    pkt = net_pkt_alloc(K_NO_WAIT);
    if (!pkt) {
        LOG_INF("No pkt available");
        return;
    }
    net_pkt_alloc_buffer(pkt, 14, 0, K_NO_WAIT);
    buf = net_buf_frag_last(pkt->buffer);

    /* FCF */
    data[0] = 0x23;
    data[1] = 0xd0;
    /* Sequence Number */
    data[2] = seq_num++;
    /* PAN ID */
    data[3] = 0xcd;
    data[4] = 0xab;
    /* MAC Address */
    memcpy(&data[5], mac_addr, 8);
    /* Command Identifier */
    data[13] = 0x00;

    buf->data = data;
    buf->len  = 14;

    int ret = radio_api->tx(ieee802154_dev, IEEE802154_TX_MODE_DIRECT, pkt, buf);
    switch (ret) {
    case -ENOMSG:
        LOG_INF("TX - no ACK received - stoping radio");
        radio_api->stop(ieee802154_dev);
        break;
    case -EIO:
        LOG_INF("TX - aborted or timeslot denied/ended");
        break;
    case -ENOBUFS:
        LOG_INF("TX - no free buffers");
        break;
    case 0:
        LOG_INF("TX - OK");
        break;
    default:
        LOG_INF("TX - unknown error %d", ret);
    }

    net_pkt_unref(pkt);
}

If I got it right, the radio_api->tx() call takes a semaphore and doesn't return until on of the tramsit callbacks is called by the radio irq. In reality tx() returns immediately with the tx_result of the previous package and the call of radio_api->stop() kills the radio before the actual frame could be transmitted. I digged into the code and found that k_sem_take() in nrf5_tx() returns -EAGAIN, signaling a timeout what is strange as K_FOREVER should be pretty long ;).

Registering an event handler with  radio_api->configure(ieee802154_dev, IEEE802154_CONFIG_EVENT_HANDLER, ...) doesn't lead to a solution as there is no event for TX_FINISHED or TX_FAILED.

Is there anything I need to do to make tx() wait for the actual package to get transfered or is this caused by a bug in the ieee driver or semaphore handling?

Parents Reply Children
No Data
Related