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.

RTOS/CC2640R2F: Software serial scif driver API's not working when called from within other tasks

Part Number: CC2640R2F


Tool/software: TI-RTOS

Hi,

I generated the uart emulator driver using the latest SCS and have integrated it with my application. The API's such as scifUartTxPutChars( ) and others work well when called within the sensor controller task. However, when called from any other task, it does not work. I have been through the SCIF Driver - How to use document which does show the method to integration of the driver with the app and also how to manage running multiple tasks within the SC. But I did not find how we can call these API's within tasks that are running on the main processor.

One such case is shown below where I try to call the scif API in another task but its not working.

static void User_taskFxn(UArg a0, UArg a1)
{
	scifUartTxPutChars(txBuff, len);
    while(1)
    {
		scifUartTxPutChars(txBuff, len);
        /* Now, can add code here to process multiple events */
    }
}

Could anyone, please provide a bare minimum example on how to perform a simple write and read using these API's from within other tasks?. And please shed some light on how to do this.

  • - Why do you want to use the Sensor Controller UART emulator for this task and not UART available from the CM3 side?
    - Are you referring to the "scif_how_to_use.html" file? This file contains code that shows how to use the APIs.
    - You just show a few line of code, you are not showing how you have set up the sensor controller task etc.
  • -There is currently one hardware UART which I am using for debug logs. Need an extra UART for interfacing some external device, the reason why I want use this.

    - Yes. But doesn't really show how I can call the scif API's such as for example: scifUartTxPutChars( ) from within another task that is running on the main processor and not on the SC.

    - The same code generated by the SCS with slight changes. Here you go. In the above code, I just showed an example of how I am calling the Tx  API from within another task to send some bytes which doesn't seem to be working. But when called within the below task i.e. sensor controller task, it works. I'd like to get it to work when called from other tasks as well.

    /****************************************************************
     * Function Name : SerialSoftware_taskFxn
     * Description   : Enables sending and receiving bytes
     * Returns       : None
     * Params        : Task aruguements
     ****************************************************************/
    void SerialSoftware_taskFxn(UArg a0, UArg a1) {
    
        /* Initialize the Sensor Controller */
        scifOsalInit();
        scifOsalRegisterCtrlReadyCallback(scCtrlReadyCallback);
        scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);
        scifInit(&scifDriverSetup);
    
        /* Start the UART emulator */
        scifExecuteTasksOnceNbl(BV(SCIF_UART_EMULATOR_TASK_ID));
    
        /* Enable baud rate generation */
        scifUartSetBaudRate(57600);
    
        /* Enable RX (10 idle bit periods required before enabling start bit detection) */
        scifUartSetRxFifoThr(SCIF_UART_RX_FIFO_MAX_COUNT / 2);
        scifUartSetRxTimeout(10 * 2);
        scifUartSetRxEnableReqIdleCount(10 * 2);
        scifUartRxEnable(1);
    
        /* Enable events (half full RX FIFO or 10 bit period timeout */
        scifUartSetEventMask(BV_SCIF_UART_ALERT_RX_FIFO_ABOVE_THR | BV_SCIF_UART_ALERT_RX_BYTE_TIMEOUT);
    
        while (1)
        {
    
            /* Wait for an ALERT callback */
            bool gotBytes = Semaphore_pend(Semaphore_handle(&semScTaskAlert), 100);
           
            /* Looks like we received something - handle it */
            if(gotBytes)
            {
                /* Clear the ALERT interrupt source */
                scifClearAlertIntSource();
    
                /* Add code to handle the Rx Bytes */
    
                /* Clear the events that triggered this */
                scifUartClearEvents();
    
                /* Acknowledge the alert event */
                scifAckAlertEvents();
            }
            else
            {
                /* Do Nothing------>*/
            }
        }
    }
    

  • Before going into details: I assume that in the final application you don't need to use the CM3 UART for debug logs. Wouldn't it be easier to use the CM3 UART to communicate with the other device and you system_printf or similar for debug logs?
  • That would be fine, I can replace all the logs to be dumped via the system_printf. But, either way we need the software serial as in the near future we will also be connecting an external nbiot module for Internet connectivity. Hence, any advise on getting this to work would be helpful.
  • From what I understand you want to access the same resource from more than one task. The first question is then, do you need to access this UART resource from more than one task?

    If you for some reason need to access the same resource from more than one task, how do you ensure that only one task tries to access the resource at a given time?

    The example you gave in the first post will block the resource since you are accessing it in an infinite while loop.
  • Yes I need to access the software UART from just one another task i.e. User_taskFxn, running on the main processor. By sharing same resources I believe you mean the software serial API's that access the data structures. Sorry if I misunderstood something, still getting a hang on the RTOS.

    From my understanding, we can use a semaphore to control access to the shared resource. Haven't used one until now and if given some insights on how to go about using it in this context, I'd be happy to use it to achieve the above.

    In the example, calling the API in an infinite loop blocks the resources makes sense. But the question is, what If change that example to as below, will it work? I checked by probing the tx line and it doesn't. Just a one time entry call.

    static void User_taskFxn(UArg a0, UArg a1)
    {
        /* One time call - Should this work? */
        scifUartTxPutChars(txBuff, len);
    
        while(1)
        {
            
        }
    }

    Also, in the case I call scifUartTxPutChars( ) within the sensor controller task which does work, how does one know when all the bytes has been pumped out of the TX bus? I don't see any events or callbacks generated to notify that.

    
    

  • Could you explain why you need two tasks to access the UART: SerialSoftware_taskFxn and User_taskFxn? Both are running on the CM3.

    The UART emulator which is a bit banged UART is running on the SCE MCU but all access to this resource is happening from task(s) in the CM3 domain.

    I rechecked the help in Sensor Controller Studio again and found: "This resource can only be used in one task per project. "

    As I understand it scifUartTxPutChars is blocking meaning that the program will be stuck on this line of code until len bytes are sent.
  • Okay, it makes sense now.

    I actually don't need two tasks accessing the UART. I want to access the UART from only the User_taskFxn. I was confused to thinking that the tirtos main code containing a task generated by the SCS(I changed  its name to SerialSoftware_taskFxn)  also run on the SCE MCU and misunderstood that we need this task to be running at all times for us to actually access the UART emulator.

    To solve the above problem and since the resource can only be used in one task per project, I will now just get rid of the SerialSoftware_taskFxn( ) task and move the SCE MCU init code and related code to the User_taskFxn( ) and will be then successfully able to access the UART emulator from within the  User_taskFxn( ). I will try this and believe it should work.

    scifUartTxPutChars blocking sounds good to me.