nrf_modem_at_cmd_async callback passes bad pointer

In my application (built with NCS v1.7.0) I use a nonblocking TCP socket for communication. The main modem thread handles sending data and a separate thread handles receiving. The pseudocode for the receive thread looks like this:

loop while socket is open
{
    num_bytes = recv(...)
    if num_bytes > 0
    {
        put received bytes in ring buffer
        notify application
    }
    sleep 10 msec
}

The main modem thread sends the AT%CONEVAL command every 500 msec to monitor the connection and collect data. The command is sent asynchronously using nrf_modem_at_cmd_async, and sometimes the pointer argument in the callback is invalid, which causes an exception (specifically it's a precise data bus error) if I attempt to use it. Here is an example of the callback function:

static void coneval_cb(const char *p_response)
{
    LOG_INF("p_response: %p", p_response);

    if (!_coneval_rxed)
    {
        LOG_INF("CONEVAL: %s", p_response);
        strncpy(_coneval_string, p_response, sizeof(_coneval_string));
        _coneval_rxed = true;
        k_wakeup(modem_tid);
    }
}

Most of the time it results in a log like this:

[00:14:01.144,927] <inf> modem: p_response: 0x200126b8
[00:14:01.144,958] <inf> modem: CONEVAL: %CONEVAL: 0,1,6,21,7,22,"005E8202","311480",109,5230,13,0,0,21,4,4,142
OK

But every once in a while it results in a log like this:
[00:14:01.481,170] <inf> modem: p_response: 0x7bd82863
[00:14:01.481,201] <err> os: ***** HARD FAULT *****
[00:14:01.481,201] <err> os:   Fault escalation (see below)
[00:14:01.481,201] <err> os: ***** BUS FAULT *****
[00:14:01.481,231] <err> os:   Precise data bus error
[00:14:01.481,231] <err> os:   BFAR Address: 0x7bd82863
[00:14:01.481,231] <err> os: r0/a1:  0x7bd82863  r1/a2:  0x00000004  r2/a3:  0x00051a5d
[00:14:01.481,262] <err> os: r3/a4:  0x7bd82863 r12/ip:  0x00035440 r14/lr:  0x000356c5
[00:14:01.481,262] <err> os:  xpsr:  0x2100002c
[00:14:01.481,262] <err> os: Faulting instruction address (r15/pc): 0x00021376
[00:14:01.481,292] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
[00:14:01.481,323] <err> os: Fault during interrupt handling
[00:14:01.481,323] <err> os: Current thread: 0x20018f00 (unknown)
So the callback function is being called with an invalid pointer. As a workaround I changed the callback function to look like this:
static void coneval_cb(const char *p_response)
{
    if (((uint32_t)p_response >> 28) != 0x2)
    {
        LOG_WRN("Bad coneval callback pointer: %p", p_response);
        return;
    }

    if (!_coneval_rxed)
    {
        strncpy(_coneval_string, p_response, sizeof(_coneval_string));
        _coneval_rxed = true;
        k_wakeup(modem_tid);
    }
}
This merely ensures the pointer address falls within the SRAM block of the nRF9160 memory map (0x20000000). It is not a proper solution because there's no guarantee a pointer with a correct most significant nibble is a valid pointer. But this workaround at least prevents most of the exceptions. I did notice however that when an invalid pointer is passed to the callback function it happens within a few milliseconds of the socket receiving data:
[02:27:11.729,309] <wrn> modem: Bad coneval callback pointer: 0x3d772a63
[02:27:11.732,482] <inf> modem: Modem received 46 bytes
Why would my call to nrf_modem_at_cmd_async be causing a callback with an invalid pointer when data is received on my nonblocking socket? Is there an actual solution to ensure the validity of the pointer using NCS v1.7.0?
Parents Reply Children
No Data
Related