Unknown function 0xA60: seems to happen while calling a particular application API only

OK I'm seeing this weird behavior that I'm trying to understand

I have a sensor task that reads sensor data continuously every 4 seconds. The value is then notified to the subscriber (NotificationManager) which then sends the data to UART, (and later to BLE custom service. 

Until I connect the BLE service from nRF Connect app, it all works ok (I see the UART print fine)

But when I attempt to connect to the BLE service via nRF Connect App, the program halts at 0xA60. (I have previously dealt with issues around logging and I wonder if it's related to it). Note that when I comment out the Notify call, the BLE connects OK. What does that tell us?

void MCP9808::Run()
{
    Write(Register::AMBIENT, 1);
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    while(true)
    {
        Read();
        
        uint32_t taskNotify = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

        ParseTempInC();
        //Notify();  // uncommenting out results in A60 error upon BLE connection

        vTaskDelay(pdMS_TO_TICKS(DELAY_MS_PER_READ));
    }
}

void NotificationManager::Update(Publisher* publisher) 
{
    // retrieve the publisher's category
    auto category = publisher->GetCategory();

    switch (category)
    {
      case Publisher::Category::TEMPERATURE:
      {
	    MCP9808* mcp9808 = dynamic_cast<MCP9808*>(publisher);
	    if (!mcp9808) return;
	    
	    uint16_t value = mcp9808->GetTempInC();

	    char msg[100] = {0};
	    snprintf (msg, sizeof(msg) - 1, "Temp = %uC", value);
	    PushNotification(MakeNotification(msg), 
      }
    }
}  

Notification NotificationManager::MakeNotification(char* msg)
{
    Notification notification = {0};
    strncpy(notification.msg, msg, sizeof(notification.msg));
    notification.category = category;
    return notification; 
}

void NotificationManager::PushNotification(Notification notification)
{
    // write data to UART
    mUART.Write(notification.msg);
    
    // updating the custom value in the BLE characteristic table
    // mBLENotifierSrv.UpdateValue(reinterpret_cast<uint8_t*>(notification.msg));
}

  • morpho said:
    Commenting out the contents of OnSubscribeChange doesn't lead to any crash but curious as to why

    Is the scheduler started when you call vTaskREsume or vTaskSuspend? 
    I have seen that sometimes trying to do these things before the scheduler started causes hardfault.

    What is the context in which OnSubscribeChange is called? Is it running in ISR context or the RTOS thread context? Since you know exactly where it crashes, you can step into the code in the debugger mode and see if it is crashing everytime it runs OnSubscribeChange  or it happens once over many calls to OnSubscribeChange ?

  • That was it seemingly - the scheduler wasn't started while OnSubscribeChange was called.

    The caller is now calling it like

    	  if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING)
    	  {
    	      OnSubscribeChange(true);
    	  }


    Though how's it even failing before main starts? 

  • morpho said:
    Though how's it even failing before main starts? 

    You will be able to set a breakpoint at the  OnSubscribeChange(true); in the above code you showed and start the program in debugger. When the program runs and the breakpoint hits, you will be able to see the function call history on how you reached here before the scheduler has started. Seems like there is some logical error in the state machine of your application.

Related