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

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

Children
Related