TM4C1294NCPDT:TI RTOS Semaphore or event

Part Number: TM4C1294NCPDT

Hello,

In my system, I receive a frame by ethernet that I transmit by Uart to another system which acknowledges the Uart which is retransmitted by ethernet.

For that I have an Ethernet task which recovers the TCP frame then I block this task with a semaphore.

Pseudo code
Ethernet_Task 
{
    while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0)
    {
    Semaphore_post(SEM_uart);
    Semaphore_pend(SEM_Ethernet, BIOS_WAIT_FOREVER);      
    		bytesSent = send(clientfd,modbusResponse, vModbusTCPApp_eReponseSize(), 0);	
    }
}
I unblock the Uart task which is blocked by a semaphore which transmits by a UART interrupt then during the acknowledgment by the other system we repeat a reception interrupt then we release the Ethernet semaphore to transmit the acknowledgment of the frame on the 'ethernet

UART_Task 
{
    // const char *twoSecondString = {"Two second task\r\n\0"};
     while (1)
     {
       //  Task_sleep((unsigned int)arg0);
         Semaphore_pend(SEM_uart, BIOS_WAIT_FOREVER);
         myUartTx(buffer, bytesRcvd);
	
     }
}

// UART0 Interrupt Function
void myUart0HwiFxn(void)
{
    intStatus = UARTIntStatus(UART0_BASE, true);
    if((intStatus & UART_INT_TX) == UART_INT_TX)
    {
        UARTIntClear(UART0_BASE, UART_INT_TX);
        if(staticLength == 0u)
        {
            UARTIntDisable(UART0_BASE, UART_INT_TX);
        }
        else
        {
            while(staticLength != 0u)
            {
                // Load FIFO with characters until full
                if(UARTCharPutNonBlocking(UART0_BASE, *pStaticString) == false)
                {
                    break;
                }
                pStaticString++;
                staticLength--;
            }
            if(staticLength == 0u)
            {

                // if all chars loaded, interrupt after last char sent
               UARTTxIntModeSet(UART0_BASE, UART_TXINT_MODE_EOT);
            }
            else
            {
                // else interrupt when more room in the FIFO
                UARTTxIntModeSet(UART0_BASE, UART_TXINT_MODE_FIFO);
            }
        }
    }
    if((intStatus & (UART_INT_RX | UART_INT_RT)) != 0u)
    {
        // Add the RX interrupt routine here
        ucChar = UARTCharGet(UART0_BASE);
        UARTRxBuf[g_len1]  = ucChar;
        g_len1++;
 Semaphore_post(SEM_Ethernet);

    }
}

I don't know if this is the right strategy. Shouldn't you use events?
Do you have an example with an Ethernet task communicating with another task?

Thanks in advance for your help

Christophe GG

  • HI,

      I think event is a more powerful form of the semaphore. So it really depends on your application which one is best suitable. For example, if you had a task that needed to unblock base on a logical combination (AND or OR) or three events occurring in the system. So the logic would be if A and B or C occurred, unblock the task. You could have done this with 3 different semaphores. Yes, it can be done but you will need to write this logic code in your application. What if you have more events to happen AND/OR at the same time before unblocking the task? That would be more difficult to do with semaphore. Using event makes the pend and post much easier. Please refer to section 4.2 Event Module in the TI-RTOS SYS/BIOS kernel user's guide for details. https://www.ti.com/lit/pdf/spruex3

      We don't have an Ethernet example that uses semaphore or event to synchronize between tasks. For Ethernet only examples, you can download from Resource Explorer from within CCS. 

    Also wanted to give you a head-up. I will be out of office starting tomorrow for the rest of the week. I will let my colleague follow up if you have further questions. In case, your post is missed, please open a new post so the moderator can address your question.