This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2564MODA: CC256XSTBTBLESW v4.0.2.2 with FreeRTOS Close Stack problems

Part Number: CC2564MODA
Other Parts Discussed in Thread: CC256XSTBTBLESW,

Good morning

I am using a CC2564Moda module with a STM32F4DISCOVERY board, to run an A3DP Sink Demo firmware, with CC256XSTBTBLESW Stack and FreeRTOS.

The system works very well, but if I try to close the stack with the CloseStack () routine and then try to reopen it with the InitializeApplication () routine, I get an error -4.

I think the problem is that the CloseStack () routine fails to close two threads that create the stack namely: TimerThread () and HCICallbackThread ().

RxThread, on the other hand, is closed correctly.

I can't see the contents of these two Routines, can you tell me how I can close them correctly or how can I manage the closing and reopening of the Stack?

Thanks in advance for your support

Michele

  • Hi Michele,

    Do you see these commands when you begin the demo?

    Can you try running CloseSink()?

    Thanks,
    Jacob

  • Good morning Jacob
    Thank you for your answer.
    I am making a battery-powered audio device, so I would need Bluetooth to be turned off when not needed.
    I don't see the command screen, because I changed the firmware, but I can give those commands.
    When I turn on bluetooth, I run the InitializeApplication () routine and my device works fine.
    I also tried running the CloseSink () and OpenSink () commands, as you told me and everything works fine.
    But I don't want to close an Endpoint, I want to turn off the device and close the Stack and then reactivate them when needed.
    Apparently the CloseStack () routine does not close everything properly and does not clear the memory to do a reboot.
    If TimerThread () and HCICallbackTread () are Thread wrapper routines, there must be some way to make them terminate naturally.
    The variables of the various compartments of the library must also be reinitialized.
    Is there any way to do this?
    I currently if I launch CloseStack (), I can't reopen the stack properly.
    If you can, try to shoutdown the device, close the stack and then reactivate everything.
    Thanks again for your support.
    Michele
  • Hi Michele,

    As you probably saw, CloseStack() calls BSC_Shutdown(), which closes the Bluetooth protocol stack. The stack can be re-opened with a BSC_Initialize() call. 

    I'll look to see if there are other options and get back to you next week. 

    Thanks,
    Jacob

  • Good morning Jacob

    what you write is exactly what I do, the problem is that CloseStack () / BSC_Shutdown () / BTPS_DeInit () don't work correctly:

    1_ Does not close all the tasks that the Stack opens, such as TimerThread () and HCICallbackTread ()

    2_ It does not close other FreeRTOS objects that are opened, such as KernelMutex

    3_ It does not correctly re-initialize the memory of the various parts of the library, so even calling BSC_Initialize () the Stack does not reopen correctly

    I managed to reopen the Stack by closing Task and other parts through my code and cleaning up by hand in debug parts of memory that I do not know what they correspond to because of the library, but this is not the way to operate, CloseStack () must do this.

    I believe that if your firmware developer tries to do CloseStack () and then BSC_Initialize () it can verify this.

    I am currently using FreeRTOS Kernel V10.3.1 in my project.

    Thanks

  • Hi Michele,

    I'll follow up with more suggestions here by Friday.

    Thanks,
    Jacob

  • Good morning Jacob

    In these days I continued to do Bluetooth tests and today I saw something that could help us, in solving the problems I wrote to you in the previous messages.

    I saw this:

    1_ If I open the Bluetooth Stack and close it without doing anything, the Stack does not close correctly and it is not possible to reopen it.

    2_ If I open the Bluetooth Stack, I pair the device with my mobile phone, then I unpair it and close the Stack, the Stack does not close correctly and it is not possible to reopen it.

    3_ If I open the Bluetooth Stack, I pair the device with my mobile phone and then I close the Stack with the paired device, the Stack closes correctly and it is possible to reopen it.

    It seems that the Stack program needs the device to be paired to close properly.

    I hope this information will be of help to you

    Bye

    Michele

  • Hey Michele,

    Thanks for the follow up. My plan to test this is to modify the A3DP Sink Demo and try closing (CloseStack) and reopening the stack (BSC_Initialize). I'll also see if I can replicate your steps above with device pairing. I'll try to follow up tomorrow, but it may be Friday before I respond.

    Thanks,
    Jacob 

  • Hi Michele,

    1_ If I open the Bluetooth Stack and close it without doing anything, the Stack does not close correctly and it is not possible to reopen it.

    2_ If I open the Bluetooth Stack, I pair the device with my mobile phone, then I unpair it and close the Stack, the Stack does not close correctly and it is not possible to reopen it.

    3_ If I open the Bluetooth Stack, I pair the device with my mobile phone and then I close the Stack with the paired device, the Stack closes correctly and it is possible to reopen it.

    When working through these steps, I encounter similar results. Every time I call CloseStack(), the demo program does not close correctly and seems to hang. However, you mentioned you successfully closed the stack after pairing with your mobile phone. 

    Did your CloseStack() include both a call to BSC_Shutdown and BTPS_DeInit?

    Thanks,
    Jacob

  • Sorry jacob or hit the wrong button and don't reply.

    Yes, in my CloseStack () there is both BSC_Shutdown () and BTPS_DeInit (), but the problem is definitely in BSC_Shutdown ().

     I can't see the library code, but there is probably a control that prevents the stack from closing under certain conditions.

    In BTPS_DeInit (), I added the KernelMutex shutdown, if not it stayed hanging.

    Sorry but I can't help you further, I don't see the code of BSC_Shutdown ().

    Bye

    Michele

  • Hi Michele,

    That is alright, this is helpful. I will try adding the KernelMutex shutdown to my code.

    Thanks,
    Jacob

  • Hi Jacob

    how are you

    Do you have any news for me?

    Thanks

    Michele

  • Hi Michele,

    No more updates yet, I will follow up more tomorrow.

    Thanks,
    Jacob

  • Hi Michele,

    Can you try this code snippet from another E2E thread to see if this solves your issue? It shows an example of how to properly close and reinitialize the Bluetooth stack.

    if(BluetoothStackID)
    {
    /* Simply close the Stack */
    BSC_Shutdown(BluetoothStackID);
    
    Display(("Stack Shutdown.\r\n"));
    
    /* Flag that the Stack is no longer initialized. */
    BluetoothStackID = 0;
    
    /* Flag success to the caller. */
    ret_val = 0;
    }
    else
    {
    /* A valid Stack ID does not exist, inform to user. */
    ret_val = UNABLE_TO_INITIALIZE_STACK;
    }
    
    And here is our code snippet for Initialize
    
    if((HCI_DriverInformationCopy))
    {
    Display(("\r\n"));
    Result = BSC_Initialize(HCI_DriverInformationCopy, 0);
    Display(("Result: %d\r\n", Result));
    if(Result > 0)
    {
    /* The Stack was initialized successfully, inform the user */
    /* and set the return value of the initialization function */
    /* to the Bluetooth Stack ID. */
    BluetoothStackID = Result;
    Display(("Bluetooth Stack ID: %d\r\n", BluetoothStackID));
    
    }
    else
    {
    /* The Stack was NOT initialized successfully, inform the */
    /* user and set the return value of the initialization */
    /* function to an error. */
    DisplayFunctionError("Stack Init", Result);
    
    BluetoothStackID = 0;
    
    ret_val = UNABLE_TO_INITIALIZE_STACK;
    }
    }

    Thanks,
    Jacob

  • Good morning Jacob
    Many Thanks for your help.
    Unfortunately your research doesn't help me, I already do the things described in that code.
    I need to see inside BSC_Shutdown () what are the conditions for which the Stack does not close properly.
    You can see the code of BSC_Shutdown (), TimerThread (), HCICallbackTread (), go into debug and see what is not closing them properly?
    I am also available to see these things for myself, if you send me the library code.
    Sorry, but I have to find a solution to the problem, or switch to some other device that allows me to do what I want.
    Thanks
    Michele
     
  • Hi Michele,

    I am trying a new solution and will get back to you tomorrow after testing.

    Thanks,
    Jacob

  • Hi Michele,

    I believe the OpenStack and CloseStack calls are working correctly. I think the -4 error you saw referred to a function error in the audio sink  initialization, not an HCI initialization error. You must specify the AUDInitialized variable to be false in the CloseStack routine to ensure the sink is reinitialized during the Initialize_Sink routine. 

    With the code below, I am able to close the stack, open the stack, and perform BT functions like an inquiry. 

    int CloseStackCommand(ParameterList_t *TempParam)
    {
        int ret_val = -1;
        if(BluetoothStackID)
        {
            /* Simply close the Stack */
            BSC_Shutdown(BluetoothStackID);
    
            Display(("Stack Shutdown.\r\n"));
    
            /* Flag that the Stack is no longer initialized. */
            BluetoothStackID = 0;
            AUDInitialized = FALSE;
            /* Flag success to the caller. */
            ret_val = 0;
        }
        else
        {
            /* A valid Stack ID does not exist, inform to user. */
            ret_val = UNABLE_TO_INITIALIZE_STACK;
        }
        return ret_val;
    }
    
     int OpenStackCommand(ParameterList_t *TempParam)
    {
      int ret_val = -1;
        Display(("\r\n"));
        int Result = OpenStack(&HCI_DriverInformation, &BTPS_Initialization);
        Display(("Result: %d\r\n", Result));
        if(Result >= 0)
        {
            /* The Stack was initialized successfully, inform the user */
            /* and set the return value of the initialization function */
            /* to the Bluetooth Stack ID. */
            ret_val = 0;
            //BluetoothStackID = Result;
            Display(("Open Stack Successfully - BT Stack ID: %d\r\n", BluetoothStackID));
        }
        else
        {
            /* The Stack was NOT initialized successfully, inform the */
            /* user and set the return value of the initialization */
            /* function to an error. */
            DisplayFunctionError("Stack Init", Result);
            BluetoothStackID = 0;
            ret_val = UNABLE_TO_INITIALIZE_STACK;
        }
        return ret_val;
    }

    Can you try this solution?

    Thanks,
    Jacob

  • Good evening Jacob

    Thanks as always for your help.

    I was already doing something similar to the one you proposed in my firmware, but to be fair I tried your code and it doesn't work.

    But today I also have good news, I understand where the problem is and how to solve it.

    As I told you it was necessary to analyze the threads that the stack opens and that is TimerThread (), HCICallbackTread () and RxThread ().

    If you want to close the Stack and then reopen it, the program needs to properly close all the tasks it has created and clear the memory.

    This can only be done if the three threads close naturally.

    RxThread () is stopped at a semaphore, so just close the HCI serial, set HCITransportOpen = 0 and finally give the semaphore to unlock it.

    The code is visible you can find it in the HCITR_COMClose () routine and it is the following:

                  /* Signal the receive thread to terminate and wait for it to */
                 /* close. */
                xSemaphoreGive(UartContext.DataReceivedEvent);
               while(UartContext.ReceiveThreadHandle)
                    BTPS_Delay(1);

               /* Close the semaphore. */
              vQueueDelete((xQueueHandle)(UartContext.DataReceivedEvent));

    HCICallbackTread () is not visible and is waiting for a Mailbox that should arrive from the library. When I close the Stack I don't immediately launch CloseStack () but I do this procedure:

    int CloseApplication(void)
    {
       int ret_val = 0;

       // Try to Close the Endpoint
       ret_val = CloseA3DPEndpoint(NULL);

       if (!ret_val)
       {
         // Attempt to set the attached device not pairable.
         ret_val = GAP_Set_Pairability_Mode(BluetoothStackID, pmNonPairableMode);

         if (!ret_val)
         {
            // Attempt to set the attached device not Discoverable.
            ret_val = GAP_Set_Discoverability_Mode(BluetoothStackID, dmNonDiscoverableMode, 0);

            if (!ret_val)
            {
                // Attempt to set the attached device not Connectable.
                ret_val = GAP_Set_Connectability_Mode(BluetoothStackID, cmNonConnectableMode);
             }
         }
       }
       else
       {
           // There was an error while attempting to close the Endpoint.
          Display(("Unable to close the Endpoint.\r\n"));
        }

        // Now, attempt to Close the Stack
        ret_val = CloseStack();

        /* Delete all Stored Link Keys. */
        BTPS_MemInitialize(&A2DPRemoteBD_ADDR, 0, sizeof(A2DPRemoteBD_ADDR));

        DeleteLinkKey(A2DPRemoteBD_ADDR);

       //if(ret_val < 0)
       //{
       //  DisplayFunctionError("CloseStack", ret_val);
       //}

    return(ret_val);
    }

    Maybe some steps are too many, the important thing is to do CloseA3DPEndpoint (NULL) because if the Bluetooth device is paired or streamed, first we interrupt the connection and then close the Stack.

    This communication exchange with Bluetooth device and library causes the Mailbox message to be sent to HCICallbackTread (), which unlocks and closes when RxThread () is closed.

    The problem arises if the Bluetooth device is not paired, because even if you force the call to CloseA3DPStream (), the library does not forward the Mailbox message to HCICallbackTread () and thus remains blocked and does not close.

    To make it close I changed the code under HCITR_COMClose () like this:

        /* Signal the receive thread to terminate and wait for it to */
        /* close. */
        BTPS_AddMailbox(MailboxHeaderCopy, (void *)a);

        xSemaphoreGive(UartContext.DataReceivedEvent);
        while(UartContext.ReceiveThreadHandle)
            BTPS_Delay(5);

        /* Close the semaphore. */
        vQueueDelete((xQueueHandle)(UartContext.DataReceivedEvent));

    where is it

    MailboxHeaderCopy is a copy of the Mailbox header that I copied when it was created

    a is an int a [2] = {0,0};

    This causes HCICallbackTread () to unlock and close. I also increased the wait time a bit to make sure both tasks close properly.

    TimerThread () I don't know how it's done, but if the first two close, then it closes too.

    I don't think this is the correct solution to the problem, because I shouldn't know or manage the Mailbox, it is the library that must send the correct messages whether the device is paired or not.

    However it works and I hope it will be helpful for all those who have this problem and for those who should update the library.

    How many points have I earned? Joke

    Bye

    Michele

  • Great to hear it Michele, this is an excellent response. I'm sure future users will appreciate the advice you shared that solved the CloseStack issue.

    I'd personally give you +50 points for this issue, but TI handles the point scoring according to this chart.

    Thank you for your contribution,

    Jacob