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

otPlatSettingsWipe undefined reference error

Hello All, 

I am developing thread base system. 

I am using SDK - nRF5_SDK_for_Thread_and_Zigbee_v4.1.0_32ce5f8

Dev-kit - nrf52840

I am using mtd code for development of my product. For requirement I need to follow these 4 steps to join network 

1 factory reset

2. ifconfig

3. Joiner start XXXX

4. thread start. 

So, I have modified the mtd code as per my requirement to auto configure the above commands using API. 

I am able execute "ifconfig", "Joiner Start XXX" and "thread Start" using respective APIs in main file. (Without entering CLI).

But If I use "otPlatSettingsWipe" API to factory reset I am getting "undefined reference to `otPlatSettingsWipe'"  error. 

Can anyone help how to resolve this issue ? or for Factory reset is there any other function?

I am following CLI command flow to execute using API's 

Thanks in advance 

Regards,

Rohit R

Parents Reply Children
  • Hi, 

    For the issue with LED1 signaling that the device is connected to a Thread network:
    In you code, you call otJoinerStart(). I think this function will initiate joining, which result in a thread connection => The LED1 will blink.

    - yes, that's what I want this sequence, "factoryreset" first then "ifconfig up" then "joiner start xxxx" and last "thread start". 

    - So if I reset or repower my device should execute above sequence. 

    - If I erase board and dump the code again then I am able to perform above sequence and able join network. But if reset or re power it then it directly entering into Connecting state. 

    - Network info not getting erased. 

    Thanks and Regards

    Rohit R

  • Hi

    I think I understand the problem better now, and will try to replicate your issue tomorrow.
    Sorry for this delay, but I need to get some more hardware to work with first.

    In the meantime, could you check if otInstanceErasePersistentInfo() returns an error?

    Regards,
    Sigurd Hellesvik

  • Hi

    otInstanceErasePersistentInfo() will erase the data. However, the data is already loaded. I managed to erase and reload the data by loading thread before erasing and then reinilizing(deinit+init) thread after:

    thread_init(&thread_configuration);
    err_code = otInstanceErasePersistentInfo(thread_ot_instance_get());
    APP_ERROR_CHECK(err_code);
    thread_soft_deinit();

    Add this before the first thread_init() in your code.

    I will ask our openthread experts if there are any cleaner way to do this, and post it as a respond here if there is.

    Does this workaround solve your problem?

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd, 

    Thank you for the response. 

    But it didn't work me. Here is my attached main file. Let me know declaration is correct. 

    After connecting to leader board, when I tried to re-power my cli_mtd child code it is not connecting. 

    I can not see LED1 turning ON. After re power it stays OFF only.  

    And I am able to connect to leader or router device only when I flash the code again with erase and other steps. But not with this API. 

    /**
     * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     *
     * @defgroup cli_example_main main.c
     * @{
     * @ingroup cli_example
     * @brief An example presenting OpenThread CLI.
     *
     */
    
    #include "app_scheduler.h"
    #include "app_timer.h"
    #include "bsp_thread.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log.h"
    #include "nrf_log_default_backends.h"
    #include "nrf_delay.h"
    
    #include "thread_utils.h"
    
    #include <openthread/thread.h>
    #include <openthread/joiner.h>
    #include <openthread/instance.h>
    
    
    #define SCHED_QUEUE_SIZE      32                              /**< Maximum number of events in the scheduler queue. */
    #define SCHED_EVENT_DATA_SIZE APP_TIMER_SCHED_EVENT_DATA_SIZE /**< Maximum app_scheduler event size. */
    
    otExtAddress ieeeEUI64; //Edit by Rohit August 17,2021
    
    /***************************************************************************************************
     * @section State
     **************************************************************************************************/
    
    static void thread_state_changed_callback(uint32_t flags, void * p_context)
    {
        NRF_LOG_INFO("State changed! Flags: 0x%08x Current role: %d\r\n",
                     flags, otThreadGetDeviceRole(p_context));
    }
    
    /***************************************************************************************************
     * @section Initialization
     **************************************************************************************************/
    
    /**@brief Function for initializing the Application Timer Module.
     */
    static void timer_init(void)
    {
        uint32_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the LEDs.
     */
    static void leds_init(void)
    {
        LEDS_CONFIGURE(LEDS_MASK);
        LEDS_OFF(LEDS_MASK);
    }
    
    
    /**@brief Function for initializing the nrf log module.
     */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    //Edit by Rohit August 17,2021****************************
    //********************************************************
    static void Read_EUi64Address (void)
    {     
        
        otInstance * p_instance = thread_ot_instance_get();
    
        otLinkGetFactoryAssignedIeeeEui64(p_instance, &ieeeEUI64);
        NRF_LOG_INFO("IeeeEUi64 Id     : %x",ieeeEUI64.m8); 
    }
    
    //Edit by Rohit Rajapure 25 August, 2021
    // This function deletes all settings from the settings
    //store, resetting it to its initial factory state
    static void FactoryReset(void)
    {
       otError error;
       otInstance * p_instance = thread_ot_instance_get();
    
    //   otPlatSettingsWipe(p_instance);
    //   otInstanceFactoryReset(p_instance);
         error = otInstanceErasePersistentInfo(p_instance);
         APP_ERROR_CHECK(error);
         thread_soft_deinit();
    }
    
    //Edit by Rohit Rajapure 25 August, 2021
    //function to execute thread start command
    static void ThreadStart (void)
    {
      otError error;
      otInstance * p_instance = thread_ot_instance_get();
    
      error = otThreadSetEnabled(p_instance, true);
      ASSERT(error == OT_ERROR_NONE);
    }
    
    
    //Edit by Rohit Rajapure 25 August, 2021
    //function to execute joiner start callback handler 
    static void Joinercallback(otError aError, void * p_context)
    {
     NRF_LOG_INFO("joiner state: 0x%08x \r\n",aError);
         //thread start
        ThreadStart();
    }
    //Edit by Rohit Rajapure 25 August, 2021
    //function to execute joiner start command
    static void joinerStartInit(otJoinerCallback handler)
    {
      otError error;
      otInstance * p_instance = thread_ot_instance_get();
    
      error = otJoinerStart(p_instance,"SEMENS",NULL,NULL,NULL,NULL,NULL,handler,p_instance);
      ASSERT(error == OT_ERROR_NONE);
    }
    
    
    
    /**@brief Function for initializing the Thread Stack.
     */
    static void thread_instance_init(void)
    {
        thread_configuration_t thread_configuration =
        {
            .radio_mode        = THREAD_RADIO_MODE_RX_ON_WHEN_IDLE,
            .autocommissioning = false,
            .autostart_disable = false,//Edit by Rohit Rajapure 25 August, 2021 ifconfig command 
        };
    
        thread_init(&thread_configuration); //
        FactoryReset();
    
        thread_init(&thread_configuration); //
        //joiner start
        joinerStartInit(Joinercallback);
    
    //    thread_cli_init();
        thread_state_changed_callback_set(thread_state_changed_callback);
    
        uint32_t err_code = bsp_thread_init(thread_ot_instance_get());
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for deinitializing the Thread Stack.
     *
     */
    static void thread_instance_finalize(void)
    {
        bsp_thread_deinit(thread_ot_instance_get());
        thread_soft_deinit();
    }
    
    
    /**@brief Function for initializing scheduler module.
     */
    static void scheduler_init(void)
    {
        APP_SCHED_INIT(SCHED_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    }
    
    /***************************************************************************************************
     * @section Main
     **************************************************************************************************/
    
    int main(int argc, char *argv[])
    {
        log_init();
        scheduler_init();
        timer_init();
        leds_init();
    
        uint32_t err_code = bsp_init(BSP_INIT_LEDS, NULL);
        APP_ERROR_CHECK(err_code);
        
        Read_EUi64Address();
        
        while (true)
        {
           
            thread_instance_init();
            while (!thread_soft_reset_was_requested())
            {
                thread_process();
                app_sched_execute();
    
                if (NRF_LOG_PROCESS() == false)
                {
                    thread_sleep();
                }
            }
    
            thread_instance_finalize();
        }
    }
    
    /**
     *@}
     **/
    

    Thanks and Regards

    Rohit R

  • Hi

    Erase can only run if thread before start. Initializing thread with autostart before calling erasePersistentStorage() will therefore not work.
    To fix this, use an separate initialization configuration without autostart for the temporary initialization.

    static void FactoryReset(void)
    {
       otError error;
       thread_configuration_t thread_configuration_for_erase =
        {
            .radio_mode        = THREAD_RADIO_MODE_RX_ON_WHEN_IDLE,
            .autocommissioning = false,
            .autostart_disable = true,
        };
       
         thread_init(&thread_configuration_for_erase);
         error = otInstanceErasePersistentInfo( thread_ot_instance_get());
         APP_ERROR_CHECK(error);
         thread_soft_deinit();
    }

    Regards,
    Sigurd Hellesvik

Related