This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

alternate way in absence of get_semaphore_value

I am implementing a uart communication, where i have various functions and/or tasks which may want to perform transmission using uart. Hence prior to new transmission on uart, i want to ensure that the resource (uart) is not already in use. this can be achieved by a binary semaphore whose value can be checked prior to new transmissions. But keil RTOS doesnt have sem_getvalue, in absence of which i am unable to think of any way of implementation.

one way around is to have a global flag. But currently trying to use any idea by which i can avoid using a global flag. In case of no other way, will have to use global flag.

any suggestions?

Parents
  • But keil RTOS doesnt have sem_getvalue, in absence of which i am unable to think of any way of implementation.

    I'm afraid you're attacking the wrong end of the problem there. The fact you believe you need a sem_getvalue() function indicates that your understanding of the purpose and meaning of semaphores is probably flawed. A semaphore is the wrong tool for that job.

    If you don't want to block in case of a failed access, you shouldn't be using a semaphore in the first place. You should be using other services provided by the RTOS, e.g. message passing.

Reply
  • But keil RTOS doesnt have sem_getvalue, in absence of which i am unable to think of any way of implementation.

    I'm afraid you're attacking the wrong end of the problem there. The fact you believe you need a sem_getvalue() function indicates that your understanding of the purpose and meaning of semaphores is probably flawed. A semaphore is the wrong tool for that job.

    If you don't want to block in case of a failed access, you shouldn't be using a semaphore in the first place. You should be using other services provided by the RTOS, e.g. message passing.

Children
  • Let me just explain you what i am trying to achieve. (this is a communication protocol & its big and has to be robust. kindly bare the patience).


    1.
    The ARM controller is acting as Slave to another controller. so it has to respond and take action to the master's commands. The master sends commands over uart.
    Hence, on receiving strings on uart, the data is processed to check what action is to be taken. some bytes in the string indicate the command to be executed. (all that is taken care of pretty-well).


    2.
    all the commands have different individual functions. hence any function may be executed. when a function completes the execution, it responds to master by sending some data via uart.


    3. Meanwhile, it may so happen that, while the function is being executed, the master may send a command to check the status of the execution. the status strings have not more than 10-15 bytes.


    how i have implemented?
    one task (rx_task) continuously monitors the reception on uart by waiting for a mail from uart rx interrupt. on checking the command & data (sometimes there may be some data which requires processing), another task (exe_task) is invoked by an event. rx_task sets a static flag exe_cmd_flg.
    the exe_task calls a function depending upon the rx command. at the end of execution, the processed data is loaded into a buffer which is passed via mail to tx_task.

    meanwhile, if chk_status command is received on the uart, and if exe_cmd_flg is set, then a function loads its static buffer & passes it via mail to tx_task. tx_task starts transmission & sets curtxflg.

    now my idea of using semaphore & its application....
    If you don't want to block in case of a failed access, you shouldn't be using a semaphore in the first place.
    I wanted the execution function (any function may be executing), to check if the transmission is already under progress or not (this transmission may be the reply for the check status - which is asynchronous event). if transmission is in progress, then wait untill the transmission is completed and then send the data (which can be done with help of a semaphore).

    no in absence of sem_getvalues(), i hav implemented the below code for tx_task & want to clear the doubt if this implementation work in case if the following case occurs...

    reply to chk_status command is being sent on uart.
    a function sends an event "event_txcmd" & then a msg box (obviously it wont be executed as curtxflg = 1)
    after completion of transmission, uart tx_interrupt will send event_complete, which will clear the curtxflg.
    will the previously sent event, event_txcmd be executed now. if not, then kindly suggest some alternate way.

    switch(rx_event)
    {
            case EVENT_TXCMD:
                    if(!CurTxflg)          //Check if any transmission is going on currently
                    {
                            os_mbx_wait(&MailTxBuf, &ptx, 0xFFFF);  //Wait for the Transmission Data
                            strcpy(DISPLAY_PORT_TXBUF, (uint8_t*)ptx);
                            CurTxflg = 1;
                            UTILS_AppendLRC(DISPLAY_PORT_TXBUF, UTILS_CalcLRC(DISPLAY_PORT_TXBUF));
                            UART_SendByte(DISPLAY_PORT_UART, *DISPLAY_PORT_TXBUF);
                    }
            break;
    
            case EVENT_COMPLETE:
                    CurTxflg = 0;
            break;
    }
    

    in case my explanation of the situation is not proper enough, kindly let me know.
    Thanking you for all your time & patience. :)

  • No - I really do not understand the complications.

    why not:

    while forever {
        wait for mail
        kick-start UART with first character in mail
        wait for event from UART interrupt that UART transmit buffer has been fully consumed
        release mail buffer
    }
    

    And a worker task:

    while forever {
        wait for work
        perform work
        wait for free mail buffer
        send mail with result
    }
    

    Receive task:

    while forever {
        wait for uart data
        process uart data
        if forming command
            if poll command
                wait for free mail buffer
                send mail will poll result
            else
                inform worker thread what to do
    }
    

    Whatever happens, your master processor must be bright enough to not send jobs or ask status requests faster than what the UART channel is able to send back responses or one or more of your threads in the slave processor will not be able to start with the next job because it is still waiting for a mail to use to report the previous result.

  • if transmission is in progress, then wait untill the transmission is completed and then send the data (which can be done with help of a semaphore).

    Yes. But it appears you really have no idea how that's supposed to be done with the help of a semaphore.

    I'm afraid I have to recommend that you stop what you're doing, right here and now, and go back to the fundamentals. Pick up a textbook. Really learn what a semaphore is, and what it does. Learn what P() and V() are, and why these are enough to do what a semaphor is meant to do. Only then does it make any sense for you to continue with the task at hand.

  • Whatever happens, your master processor must be bright enough to not send jobs or ask status requests faster than what the UART channel is able to send back responses...
    this is one of the problem....the master cant be smarter enough as different task at the slave take different amount of time. Though there is some pretty decent amount of delay that master will wait for (100ms or so) before sending a new command or the poll, but there is no estimation of this time period.

    But it appears you really have no idea how that's supposed to be done with the help of a semaphore...
    kindly elaborate how its can be done

    learn what a semaphore is, and what it does.
    suggest some good links or articles that may be noteworthy :)

  • before sending a new command or the poll,
    in absence of reply from slave...