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

Reading flashlog using nrf_log_backend_flash_next_entry_get does not work unless a CLI is initiated

Hello,

This subject is partly a conclusion and partly a question I would like confirmed.

Our scenario is that we would like to fetch flash logs over BLE, but not really by enabling CLI support. The way I've been trying to implement this is by using the nrf_log_backend_flash_next_entry_get and push each message over a BLE characteristic. For some reason, I had a lot of trouble getting it to work in my project, which was based on one of the basic BLE peripheral examples. But when pasting my code into the experimental BLE CLI example (15.3.0_59ac345/examples/ble_peripheral/experimental/ble_app_cli), it worked like a charm. I've been trying to copy code from the example one line at the time, and now I can make it work if I include the code for initializing an UART CLI. If I remove that, and use NRF_LOG_DEFAULT_BACKENDS_INIT() instead, I get random or no data from nrf_log_backend_flash_next_entry_get.

If this is the case, I think it should be better documented, and if it's a bug it would be nice to get it fixed. I'm including the code snipped I've been using to test the flashlog call below, I can provide more of my code if needed. I was able to paste this into the example project mentioned above without issue (I wrote a single warning on each reboot and ran the code to read it back). Some of it is adapted from where I found it used in the SDK as the documentation for the call itself (specifically on how to use the header and data correctly) was a bit lacking.

static void log_entry_process(nrf_log_header_t * p_header, uint8_t * p_data)
{
    switch (p_header->base.generic.type)
    {
        case HEADER_TYPE_STD:
        {
            const char * p_str = (const char *)((uint32_t)p_header->base.std.addr);
            uint32_t * p_args = (uint32_t *)p_data;
            switch(p_header->base.std.nargs)
            {
                case 0:
                    NRF_LOG_INFO(p_str);
                    break;
                case 1:
                    NRF_LOG_INFO(p_str, p_args[0]);
                    break;
                case 2:
                    NRF_LOG_INFO(p_str, p_args[0], p_args[1]);
                    break;
                case 3:
                    NRF_LOG_INFO(p_str, p_args[0], p_args[1], p_args[2]);
                    break;
                case 4:
                    NRF_LOG_INFO(p_str, p_args[0], p_args[1], p_args[2], p_args[3]);
                    break;
                case 5:
                    NRF_LOG_INFO(p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4]);
                    break;
                case 6:
                    NRF_LOG_INFO(p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5]);
                    break;

                default:
                    break;
            }
            break;
        }
        case HEADER_TYPE_HEXDUMP:
        {
            NRF_LOG_INFO("Hex data");
            break;
        }
        default:
            NRF_LOG_INFO("Unknown type %d", p_header->base.generic.type);
            break;
    }

}

static void test_flashlog()
{

    // Test log reader
    ret_code_t error_code;
    uint32_t token = 0;
    nrf_log_header_t * p_header = NULL;
    uint8_t * p_data = NULL;
    NRF_LOG_INFO("Reading flash");

    while(true)
    {
        error_code = nrf_log_backend_flash_next_entry_get(&token, &p_header, &p_data);
        if(error_code != NRF_SUCCESS)
        {
            if(error_code == NRF_ERROR_NOT_FOUND)
            {
                NRF_LOG_INFO("Flash end reached");
            }
            else
            {
                NRF_LOG_WARNING("Read flash error code %d", error_code);
        }
        break;
        }
        else
        {
            // NRF_LOG_INFO("Location %d", token);
            log_entry_process(p_header, p_data);
        }
    }
}

Parents
  • Hello,

    Sorry for the late answer, I've been away on holiday and occupied with some other projects. I've uploaded a working and a non working example (links at the end). They both include the SDK with required external deps, so they are about 720 mb when extracted. I can provide them without the SDK if you want, but I've put all the folders so that it should comile without issue. My project is located under nrfbtworking/project/app. Running make && make flash from here should set it all up.The app will log a test warning during start-up, so rebooting a few times fills the flash with some messages. This was all done on a PCA10040.


    In the working example you can use the cli to check out the flashlog, or use my BT interface as follows:

    1. Connect to the device (named "SF")
    2. Write to char 0e2b2903-0db9-4dd2-ac3d-3c792034c859 - This initializes my log reader
    3. Write to char 0e2b2904-0db9-4dd2-ac3d-3c792034c859 - This makes my reader read the next log entry into the char below
    4. Read from char 0e2b2901-0db9-4dd2-ac3d-3c792034c859 - This should now be filled with the log entry
    5. Repeat step 3 and 4 until step 4 gives only 0's. This means the end of the log was reached.

    Both using the cli and my BT interface works fine when running the logworking.zip example, but not in lognotworking.zip. The only things I've made different in lognotworking.zip are:

    • Commented out lines 101, 102, 568-572 and 584. Those are the ones related to the CLI initialization.
    • Added NRF_LOG_DEFAULT_BACKENDS_INIT() in line 622. (This doesn't affect wether my BT interface is working)

    The sdk_config.h is identical in the two projects, and I think I copied it from the "examples/ble_peripheral/experimental/ble_app_cli" example with some minor adjustments.

    It seems to me the flash backend is never filled with any data if I don't initialize the CLI (I've tried to log what my BT interface reads from flash as INFO messages over UART/RTT, and this works in the first example). Is there something related to flash initialization I am missing here (maybe the CLI code does this for me bedind the scenes)? The flash and crash log backends are initialized in the function at line 605.

    Working example: https://drive.google.com/open?id=1GHFimdJ6LPQrkNWD9RrldZcBCuzv8GCs


    Non working example: https://drive.google.com/open?id=1c9nQBJecgK1JIMolSm_X1rr5EifyxAe8

    Kind regards

    Martin

  • I tested lognotworking.zip, and I'm able to connect and write/read the characteristics. Did this not work when you tested it?

  • I can read and write to the characteristics, but the read characteristic is never filled with any log data.

  • This is very strange, I tried to modify my lognotworking example to NRF_LOG_INFO whatever it wrote to the read char, and suddenly it started working!

    That is, I added:

    NRF_LOG_INFO("Read Data: %s", logentry_buffer);

    on line 254 right before the call to:

    error_code = ble_logservice_set_value(p_logservice, logentry_buffer, data_length);

    Another weird thing, if I comment out the line again and reflash, the device will start up, but if I reset it once or twice it stops responding completely. No data over UART, and it's not discoverable in nRF Connect. I'm starting to wonder if this could be some kind of hardware issue on my card, maybe in the flash? If I add the log line back in it works without issue.

Reply
  • This is very strange, I tried to modify my lognotworking example to NRF_LOG_INFO whatever it wrote to the read char, and suddenly it started working!

    That is, I added:

    NRF_LOG_INFO("Read Data: %s", logentry_buffer);

    on line 254 right before the call to:

    error_code = ble_logservice_set_value(p_logservice, logentry_buffer, data_length);

    Another weird thing, if I comment out the line again and reflash, the device will start up, but if I reset it once or twice it stops responding completely. No data over UART, and it's not discoverable in nRF Connect. I'm starting to wonder if this could be some kind of hardware issue on my card, maybe in the flash? If I add the log line back in it works without issue.

Children
No Data
Related