CC2642R: Receiving HAL_ASSERT_SPINLOCK error while adding a new function that sends data via UART

Part Number: CC2642R
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hello, 

I am using CC2642R for utilizing BLE and sending UART data to another controller. I have inserted a user defined function in the read callback of a certain characteristic. The data is successfully being stored in the memory location. However when i try to call another user defined function that sends certain data via UART, the program gets stuck in the HAL_ASSERT_SPINLOCK. What can be the possible reasons for this ?

My code:

--> My write callback function:

bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len,
uint16_t offset, uint8_t method)
{
bStatus_t status = SUCCESS;
uint8 notifyApp = 0xFF;

if ( pAttr->type.len == ATT_BT_UUID_SIZE )
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch ( uuid )
{
case SIMPLEPROFILE_CHAR3_UUID:
// Validate the value
// Make sure it's not a blob operation

if ( offset == 0 )
{
if ( len > 40 )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}

//Write the value
if ( status == SUCCESS )
{

uint8 *pCurValue = (uint8 *)pAttr->pValue;
*pCurValue = pValue[0];
inputSize = len;

for(int i = 0; i < len;i++)
{
completePacket[counter] = pValue[i];
counter = counter + 1;
if(counter == 256)
{
counter = 0;
packetWriteFlag = 1;
break;
}
}

if(packetWriteFlag == 1)
{
cloud_packet_decode_and_decrypt(completePacket);
app_command_parse_and_generate_new(completePacket);
counter = 0;
packetWriteFlag = 0;
}

//value_validator(input);
// app_command_parse_and_generate_new(input,len);
// notifyApp = SIMPLEPROFILE_CHAR3;
}
break;

case SIMPLEPROFILE_CHAR1_UUID:

// Validate the value
// Make sure it's not a blob operation
if ( offset == 0 )
{
if ( len > 40 )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}

else
{
status = ATT_ERR_ATTR_NOT_LONG;
}

//Write the value
if ( status == SUCCESS )
{

uint8 *pCurValue = (uint8 *)pAttr->pValue;
*pCurValue = pValue[0];


inputSize = len;
for(int i = 0; i < len;i++)
{
input[i] = pValue[i];
}

if(splitFlag == 1)
{
// app_command_parse_and_generate_new(decryptedCloudInput);
commandImplementFlag = 1;
splitFlag = 0;
}

// else if(commandImplementFlag == 1)
// {
// //uart_and_RS485("probe");
// //uart_and_RS485("probe");
//
// // sem_post(&sem1);
// //commandImplementFlag = 0;
// }

else
{
check_other_command(input,1);
}

if(input[0] == '0')
{
memset(completePacket,0,260);
counter = 0;
}
}
break;

case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY );
break;

default:
// Should never get here! (characteristics 2 and 4 do not have write permissions)
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
else
{
// 128-bit UUID
status = ATT_ERR_INVALID_HANDLE;
}

// // If a characteristic value changed then callback function to notify application of change
// if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
// {
// simpleProfile_AppCBs->pfnSimpleProfileChange(2);
// }

return ( status );
}



cloud_packet_decode_and_decrypt(completePacket);
app_command_parse_and_generate_new(completePacket);

These are the 2 functions which i am inserting in the write callback function of BLE. Now by only keeping the first function, the device works perfectly but after adding the second function issues occur...

Can anyone point me in the direction in which to move while  approaching the problem ??

  • Hi, 

    Thank you for reaching out. 

    For information, I have edited your message to use a code block as it was very difficult to read the code. For next time, please use the code insert function of the forum. 

    To your question, I believe you may be trying to execute too much code in a callback context. I have no access to your implementation of cloud_packet_decode_and_decrypt() and app_command_parse_and_generate_new() but if they should probably be executed in a task context rather than in an interrupt context.

    I hope this will help,

    Best regards, 

  • Hello,

    Sorry for causing the trouble will definitely use the code insert function.

    Can you please explain this last point in more detail:

     "probably be executed in a task context rather than in an interrupt context."

    Because i have also tried to implement in a task context

    int main()
    {
      /* Register Application callback to trap asserts raised in the Stack */
      halAssertCback = AssertHandler;
    
      Board_initGeneral();
    
      // Enable iCache prefetching
      VIMSConfigure(VIMS_BASE, TRUE, TRUE);
      // Enable cache
      VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);
    
      /* Register Application callback to trap asserts raised in the Stack */
      RegisterAssertCback(AssertHandler);
    
    #if !defined( POWER_SAVING ) || defined( USE_FPGA )
      /* Set constraints for Standby, powerdown and idle mode */
      // PowerCC26XX_SB_DISALLOW may be redundant
      Power_setConstraint(PowerCC26XX_SB_DISALLOW);
      Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
    #endif // POWER_SAVING | USE_FPGA
    
      /* Update User Configuration of the stack */
      user0Cfg.appServiceInfo->timerTickPeriod = Clock_tickPeriod;
      user0Cfg.appServiceInfo->timerMaxMillisecond  = ICall_getMaxMSecs();
    
      //SET RTC FOR TIMESTAMP AND OTHER RELATED PARAMETERS
      UTC_init();
      UTC_setClock(1735809775);
    
      //NVS CHECK FOR NUMBER OF CONTROLLERS WHICH ARE CURRENTLY BEING CONNECTED
      //controllers_connected_counter();
    
      //Now enabling The required GPIO as trigger
      /* Install Button callback */
      //  GPIO_setCallback(INPUT_A, gpioInputFxnA);
      //  GPIO_enableInt(INPUT_A);
    
      //Now starting the low power clock based circuitry
    
    
    
      /* Initialize ICall module */
      ICall_init();
    
      /* Start tasks of external images - Priority 5 */
      ICall_createRemoteTasks();
    
      pthread_t thread;
      pthread_attr_t attrs;
      struct sched_param priParam;
      int retc;
    
      pthread_attr_init(&attrs);
    
      /* Set priority, detach state, and stack size attributes */
      priParam.sched_priority = 1;
      retc                    = pthread_attr_setschedparam(&attrs, &priParam);
      retc |= pthread_attr_setdetachstate(&attrs, 1);
      retc |= pthread_attr_setstacksize(&attrs, 4096);
      if (retc != 0)
      {
          /* failed to set attributes */
          while (1) {}
      }
    
      retc = pthread_create(&thread, &attrs, mainThread, NULL);
      if (retc != 0)
      {
          /* pthread_create() failed */
          while (1) {}
      }
    
      /* Kick off application - Priority 1 */
      multi_role_createTask();
    
      /* enable interrupts and start SYS/BIOS */
      BIOS_start();
    
      return 0;
    }

    So i have created another task in which i try to call these functions. However i get the same error of HAL_ASSERT_SPINLOCK more specifically the HAL_ASSERT_CAUSE_HARDWARE_ERROR

  • Hi, 

    Thank you for sharing this code snippet. The way you create the new thread and the priority you assigned to it seem correct.

    Could you also share the content of the new thread? Among others, I would like to ensure the task newly created is ICALL enabled - https://software-dl.ti.com/simplelink/esd/simplelink_cc13xx_cc26xx_sdk/7.40.00.77/exports/docs/ble5stack/ble_user_guide/html/ble-stack-5.x/the-application.html#creating-additional-icall-enabled-tasks 

    Best regards, 

  • void *mainThread(void *arg0)
    {
    	while(1)
        {
            Task_sleep(1000000);
    
            if(commandImplementFlag == 1)
            {
                cloud_packet_decode_and_decrypt(completePacket);
                app_command_parse_and_generate_new(decryptedCloudInput);
                uart_and_RS485("probe");
                commandImplementFlag = 0;
    
            }
        }
    
    }
    

    Hello,

    Also, in the read callback function of BLE, i am filling my array up to 256 bytes and then setting a Boolean variable high. This task checks that variable and then implements the function which are left to be performed.

    I had already gone through the ICall enabled tasks document but i want to understand how exactly the initialization of the task has to be done to make the task an ICall enabled task. More specifically 

    // ******************************************************************
    // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
    // ******************************************************************
    // Register the current thread as an ICall dispatcher application
    // so that the application can send and receive messages.
    ICall_registerApp(&selfEntity, &syncEvent);

    What will be the parameters to input to the ICall register app function considering my thread..

    Sorry for taking your time but I am trying to understand the working of ICall.....

    Thanks 

  • Hi, 

    The sample applications provided in the SDK create thread ICall enabled, you can reference these. 

    Code snippet below shows how to define selfEntity and syncEvent. Note that these symbols should be renamed to avoid conflicting with the one declared by the sample application. 

    static ICall_EntityID selfEntity;
    static ICall_SyncHandle syncEvent;

    Please also make sure to follow the step "Open SysConfig -> BLE -> Advanced Settings -> ICALL and add one to the “Max Number of Icall Enabled Tasks” entry." defined in the guide I have pointed you to in the previous message. 

    Best regards,