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.

Counting Semaphore Count 2 - PendedTasks none

Hello,

I have some problem with my code and I dont know how to go on.

Device: TivaC launchpad + TI RTOS. I have several tasks running on uC and using USB Receive and USB transmit task to communicate with the serial host. I am using semaphores + queues combo for inter thread communication. The starting point of my application is "usbserialdevice" TI RTOS example.

When the serial host - client communication is very often, the uC program hangs in Usb transmit task. The uC can receive additional serial requests, but unable to transmit the answer to the serial host. 

Here is a screenshot of ROV:

I assume the problem is in the first row. How should it be possible that count is 2 but there is no pendedTasks?

And here is my Usb Transmit task:

//--------------------------------------------------------------------------
//  Task to transmit serial data.
//
//  This task periodically sends data to the USB host once it's connected.
void USB_Task_USBTransmit(UArg arg0, UArg arg1)
{
	USB_TransmitQueueElement_t msgobj;
	USB_TransmitQueueElement_t* msgp;
	msgp = &msgobj;

	char replyHeader[MSG_REPLY_HEADER_SIZE];

    while (true)
    {
        USBCDCD_waitForConnect(BIOS_WAIT_FOREVER);					// Block while the device is NOT connected to the USB */

        Semaphore_pend(USB_Semaphore_Transmit,BIOS_WAIT_FOREVER);	// Wait for incomming data to send to USB HOST
        msgp = Queue_get(USB_Transmit_Queue);

        replyHeader[0] = LOWBYTE(msgp->size);
        replyHeader[1] = HIGHBYTE(msgp->size);
        USBCDCD_sendData((const unsigned char*)replyHeader,MSG_REPLY_HEADER_SIZE,BIOS_WAIT_FOREVER);	// Send reply length as U16
        USBCDCD_sendData((const unsigned char*)msgp->data, msgp->size, BIOS_WAIT_FOREVER); 				// Send reply message
    }
}

In the project I am using 

Semaphore_pend(USB_Semaphore_Transmit,BIOS_WAIT_FOREVER);	// Wait for incomming data to send to USB HOST

only ones, in this task. 

  • A count of 2 means that two Semaphore_post were done on it (assuming the count was set to zero on the create). It does not mean there are two pending tasks. A count of 0 means the semaphore is not available and any calls when pend on it. A count of non-zero (e.g. 2) means a call to Semaphore_pend will decrement the count and return with a success return code.

    Todd
  • Hi,
    Thank you for your reply. So in USB transmit task, if the semaphore has value above zero means the task has job to be done. Am I right? Because Seamphore_pend waits forever.

    My problem is why this task is blocked if semaphore_pend should free to go?

    EDIT: The usb Transmit and Receive tasks priority are the highest.

    Using ROV here another result:

    You can see that the USB_Task_USBTransmit function is blocked by 0x20004e98 semaphore. What is that semaphore? This program can run over hours without any problem and randomly this semaphore hangs the usb transmit.

    It seems there are 2 semaphores that pends the same task and waiting for each other to run.

    The code below is shipped with examples, and I think the certain semaphore  is created here...

    void USBCDCD_init(void)
    {
        Hwi_Handle hwi;
        Error_Block eb;
        Semaphore_Params semParams;
    
        Error_init(&eb);
    
        /* Install interrupt handler */
        hwi = Hwi_create(INT_USB0, USBCDCD_hwiHandler, NULL, &eb);
        if (hwi == NULL) {
            System_abort("Can't create USB Hwi");
        }
    
        /* RTOS primitives */
        Semaphore_Params_init(&semParams);
        semParams.mode = Semaphore_Mode_BINARY;
        semTxSerial = Semaphore_create(0, &semParams, &eb);
        if (semTxSerial == NULL) {
            System_abort("Can't create TX semaphore");
        }
    
        semRxSerial = Semaphore_create(0, &semParams, &eb);
        if (semRxSerial == NULL) {
            System_abort("Can't create RX semaphore");
        }
    
        semUSBConnected = Semaphore_create(0, &semParams, &eb);
        if (semUSBConnected == NULL) {
            System_abort("Can't create USB semaphore");
        }
    
        gateTxSerial = GateMutex_create(NULL, &eb);
        if (gateTxSerial == NULL) {
            System_abort("Can't create gate");
        }
    
        gateRxSerial = GateMutex_create(NULL, &eb);
        if (gateRxSerial == NULL) {
            System_abort("Can't create gate");
        }
    
        gateUSBWait = GateMutex_create(NULL, &eb);
        if (gateUSBWait == NULL) {
            System_abort("Could not create USB Wait gate");
        }
    
        /* State specific variables */
        state = USBCDCD_STATE_UNCONFIGURED;
    
        /* Set the USB stack mode to Device mode with VBUS monitoring */
        USBStackModeSet(0, eUSBModeForceDevice, 0);
    
        /*
         * Pass our device information to the USB HID device class driver,
         * initialize the USB controller and connect the device to the bus.
         */
        if (!USBDCDCInit(0, &serialDevice)) {
            System_abort("Error initializing the serial device");
        }
    }
    

    I have set the priority for all of my tasks equal and the problem still exists.

  • Hi,

    It strongly seems the problem is here

    semParams.mode = Semaphore_Mode_BINARY;
        semTxSerial = Semaphore_create(0, &semParams, &eb);
        if (semTxSerial == NULL) {
            System_abort("Can't create TX semaphore");
        }

    When I change the Mode to Counting it seems the problem still exists, but application can run much longer.

    Could you review this issue and recommend any solution?

    EDIT:

    What baud rate is recommended for Host? 9600? 

  • What device and version of TI-RTOS are you using?
  • TM4C123GXL, TI RTOS: 2.12.1.33.

    I have higher verion of TI RTOS installed but when I set it, all of the following includes are missin:

    #include <inc/hw_memmap.h>
    #include <inc/hw_types.h>
    #include <inc/hw_ints.h>
    #include <inc/hw_gpio.h>

    #include <driverlib/gpio.h>
    #include <driverlib/sysctl.h>
    #include <driverlib/i2c.h>
    #include <driverlib/ssi.h>
    #include <driverlib/uart.h>
  • Is the out-of-the-box example failing? Or did you make changes? If it is the latter, I cannot really help debug this (other than answer questions like what does a count of 2 mean for a semaphore). If it is the former, please detail the exact steps to reproduce the problem.
  • I made lot of changes, but the backbone of my code is TI RTOS USB SerialDevice example.

    In my 3rd post, you can see the ROV output. You can see the 0x20004e98 Address Semaphore that blocks the usb transmit task.  If you open the usbserial example you can see the same ROV output. As I go into the functions I saw that 0x20004e98 semaphore is posted only in this function:

    static USBCDCDEventType cbTxHandler(void *cbData, USBCDCDEventType event,
                                        USBCDCDEventType eventMsg,
                                        void *eventMsgPtr)
    {
        switch (event) {
            case USB_EVENT_TX_COMPLETE:
                /*
                 * Data was sent, so there should be some space available on the
                 * buffer
                 */
                Semaphore_post(semTxSerial);
                break;
    
            default:
                break;
        }
    
        return (0);
    }

    Can you tell me why this Semaphore_post does not execute? 

  • Hey,

    The problem is solved, and here is the solution:

    USBCDCD_sendData((const unsigned char*)replyHeader,MSG_REPLY_HEADER_SIZE,BIOS_WAIT_FOREVER);    // Send reply length as U16
    USBCDCD_sendData((const unsigned char*)msgp->data, msgp->size, BIOS_WAIT_FOREVER);  

    The statements above should be merged into only one function call.  

    Cheers,