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

mqttsn with openthread and freertos

I am trying to hook openthread with freeRTOS.

Short story: the current state of my implementation is that I get a hardfault after succesfully calling mqttsn_client_search_gateway, but before receiving any data on the other end on the mqtt-sn gateway. The stack at this point starts in

> strace
warning: Couldn't determine the static tracepoint marker to probe
Static tracepoint 16 at 0x7d8a: file nRF5_SDK\external\freertos\portable\GCC\nrf52\port.c, line 104.

Long story:

From freeRTOS, I am mostly interested in tasks and message queues.

My skeleton implementation has 2 tasks:

1. the openthread processing thread:

static SemaphoreHandle_t threadMutex = nullptr;

static void thread_stack_task(void*)
{
    while (1)
    {
        xSemaphoreTake(threadMutexportMAX_DELAY);
        thread_process();
        xSemaphoreGive(threadMutex);
        UNUSED_RETURN_VALUE(ulTaskNotifyTake(pdTRUEportMAX_DELAY));
    }
}

and starting it like in one of the examples:

threadMutex = xSemaphoreCreateMutex();
// Start thread stack execution.
    if (pdPASS != xTaskCreate(thread_stack_task"THR"THREAD_STACK_TASK_STACK_SIZENULLTHREAD_STACK_TASK_PRIORITY, &thread_stack_task_handle))
    {
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }

The other task is a state machine to handle different states in the connection process:

- initializing the thread structures

- joining a thread network: role changes to CHILD or ROUTER

- searching for a mqtt-sn gateway

- connecting the mqtt client, etc.

Here's how I start the state machine task (ConnectionStateMachine is a singleton for some other reasons later on) :

    csm = ConnectionStateMachine::GetInstance();
    csm->SetThreadMutex(threadMutex);
    if (pdPASS != xTaskCreate(
        [](void* stateMachine)->void
        { 
            ((ConnectionStateMachine *)stateMachine)->StateMachine();
        }, 
        "CSM"THREAD_STACK_TASK_STACK_SIZEcsmTHREAD_STACK_TASK_PRIORITY, &thread_stack_task_handle))
    {
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }

and the StateMachine method:

void ConnectionStateMachine::StateMachine()
{
    while (true)
    {
        Event event;
        if(pdTRUE == xQueueReceive(messasgeQueue, &eventportMAX_DELAY))
        {
            xSemaphoreTake(m_threadMutexportMAX_DELAY);
            switch (state)
            {
            case StateUnitialized:
            {
                if(event == EventInitialized)
                {
                    //auto transition to an initialized state
                    ThreadInstanceInit();
                    m_client.Init();

                    state = StateInitialized;
                }
                break;
            }

where state is the state, and event is the transition.

To transition from a state, one needs to call:

bool ConnectionStateMachine::Transition(Event desiredTransition)
{
    bool retValue;
    //return false if the queue is full (in the middle of processing a state transition)
    retValue = (xQueueSend(messasgeQueue, &desiredTransition, (TickType_t)0) == pdTRUE ? true : false);
    return retValue;
}

The idea is that the callback in openthread and mqtt are on the context of the Thread task, and I can quickly wake up my StateMachine by adding a message to the queue:

static void state_changed_callback(uint32_t flagsvoid * p_context)
{
    if (flags & OT_CHANGED_THREAD_ROLE)
    {
        otDeviceRole role = otThreadGetDeviceRole((otInstance *)p_context);
        if (role == OT_DEVICE_ROLE_CHILD || role == OT_DEVICE_ROLE_ROUTER)
        {
            ConnectionStateMachine::GetInstance()->Transition(ConnectionStateMachine::EventConnected);
        }
    }
}

I can reach this part, and even transtion to the next state, where I call mqttsn_client_init and then call mqttsn_client_search_gateway successfully, with a return code NRF_SUCCESS. After this, I do not see any data transmitted to the gateway, not reaching the event handler callback set in the init function, and quickly (a few seconds) crashing in a hardfault originating from nRF5_SDK\external\freertos\portable\GCC\nrf52\port.c:104 in 

void xPortPendSVHandlervoid )

At this point I have no ideas what to try to debug anymore. Any help is highly appreciated.

Thanks,

Edgar

Parents Reply Children
No Data
Related