0

I am trying to program a kind of cli with uart receive interrupts for an embedded system. I want my code to stay in uart function till i press the enter as '\r' then go on till it gets to the next uart function and wait for enter again. like some kind of scanf.

int main(void)
{
  while (1)
  {
    uart_interrupt_receive(); 

    //something else 

   uart_interrupt_receive(); 

    //something else 

  }

I dont want to use scanf or getchar if possible. I got here so far. I cant decide which flags to use to make it work the way i want or how else i can change it?

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)(){
  if (USART2->ISR & USART_ISR_RXNE)                        //is rx flag active
  {
    char rx = (char)(USART2->RDR & 0xFF);                 //received char rx      
 
    if ((rx == '\r') || (rx == '\n'))                    //if rx enter
    {
                                          
                   //go on


     }//if
    else 
    {
      
                //wait
       
    }//else
  }//if
 
}//uart_rxcplt_callback
aaalyson
  • 3
  • 1
  • This is very specific to a certain MCU. Nobody can answer unless you tell which one. – Lundin Feb 04 '22 at 10:37
  • 1
    Keeping a micro controller in an interrupt while waiting for user input sounds like a really bad idea. You should put the received chars in some rx buffer, then periodically check that from your main code. Your interrupt routine could set some flag when receiving '\r' to indicate to the main code that a full command has been received. – Klas-Kenny Feb 04 '22 at 10:37
  • @Klas-Kenny then function doesnt stays and keeps going. I cant make it wait and read the rx buffer till its enter then move to next function – aaalyson Feb 04 '22 at 10:51
  • @Lundin *"This is very specific to a certain MCU. Nobody can answer unless you tell which one."* -- Not true for either of your statements. And you disproved the latter by posting an answer! – sawdust Feb 10 '22 at 20:59
  • @aaalyson *"then function doesnt stays ..."* -- Your code is incomplete. What does **uart_interrupt_receive()** (that is called from **main()**) do? *"I cant make it wait and ..."* -- What is this *"it"* that you refer to? – sawdust Feb 10 '22 at 21:07

1 Answers1

0

Stalling the whole MCU inside an interrupt is not a great idea. Generally speaking, you should keep data reception and higher layer application logic separated if possible. There's two ways to deal with UART rx:

  • "Old school" way of interrupts where the hardware doesn't have much in the way of rx hardware buffers. In that case you would let the UART rx interrupt store the incoming character in a software ring buffer. This ring buffer needs protection against race conditions.
  • If DMA is supported then you can skip interrupts and DMA everything into a DMA buffer. Race condition considerations apply here too.

In the end your main application sits with a buffer of received data of some kind. It call poll that buffer until empty and do whatever the program should be doing based on data received.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • *"There's two ways ..."* -- Not really, you seem to subscribe to the simplified "interrupt vs DMA" misconception of I/O. See https://stackoverflow.com/questions/25318145/dma-vs-interrupt-driven-i-o/38165400#38165400 – sawdust Feb 10 '22 at 21:20
  • @sawdust Not really, please note "where the hardware doesn't have much in the way of rx hardware buffers". This means interrupts per every UART byte received, very CPU-intensive. With DMA you can reduce this as you like. If you expect to receive a full packet of 50 bytes every 100ms, then you can set DMA accordingly and _poll_ the DMA flag, no burden for the CPU at all. – Lundin Feb 11 '22 at 07:21