2

My code is for serial communication and led blinking using timer interrupt, where led is toggle at a fix interval of time with some line prints on serial terminal and for fix time i have used timer.

Scenario:

I am sending data "while" on the serial terminal in continuous manner and when timer is expired, interrupts occurs and my led toggles with again serial data "RED LED blinked for 500 ms" on terminal. Ideally this timer function should get called only when timer get expired and rest of the time my while loop should execute and while loop data should be printed on the terminal. But this is not happening, the serial prints are not like as it should be printed.

Let me know what is the actual reason behind this.

I have changed baud-rate(115200 to 9600), and output was quite similar. But if u print only 'w' instead of "while" then also behaviour is similar, but timer "RED LED blinked for 500 ms" prints 2 times. Not getting clear idea where timer is busy for this behavior.

Below is my code:

define d9 "while\r\n"

int main(void) {

//Serial Communication Inilization done
//Timer Initialization done

    while (1) 
    {
        // This line prints continuously on the terminal 
        LPUART_DRV_SendDataPolling(INST_LPUART1, (uint8_t *) d9, strlen(d9));
    }
} 

Actual Output:

...
while
while
while
wRED LED blinked for 500 ms
hRED LED blinked for 500 ms
iRED LED blinked for 500 ms
lRED LED blinked for 500 ms
eRED LED blinked for 500 ms
while
while
...

Expected Output:

...
while
while
while
RED LED blinked for 500 ms
while
while
...
EN20
  • 51
  • 11
Naren
  • 159
  • 1
  • 7
  • 2
    blind guess: your sendData function(s) dont actually send any data, instead they put them into a buffer. this buffer mechanism is unaware that it might be interrupted and have another function input data when the first transaction has not finished. You could try to disable global interrupts while writing to your buffer to test this. – markus-nm Aug 06 '19 at 13:38
  • 3
    You just can't do things like this. You need a *single* part of your code to "own" the UART's sending capability, and you need to funnel everything through it. Originating and sending multi-character messages within an ISR is a bad idea anyway. Likely what you should do it *set a volatile flag* in the ISR and then check that and send the message in the main loop, where it can fit in between the other output. If you do have an ISR managing a software send buffer, it would only be moving however many byte(s) of data the hardware can accept at a time, not "saying things" on its own behalf. – Chris Stratton Aug 06 '19 at 16:05
  • 1
    Incidentally, if you want to debug an ISR, it's typically better to toggle a GPIO and watch that with a scope or cheapie sigrok compatible USB-based logic analyzer – Chris Stratton Aug 06 '19 at 16:08
  • Let me try the above mentioned both the methods, thanks a lot @markus-nm – Naren Aug 07 '19 at 05:22

1 Answers1

0

The actual output you present shows that the string "RED LED blinked for 500 ms" (=: "the ISR string") interrupts the string "while" (=: "the main loop string").

It does so with a monotonic frequency (leaving a single character of the main loop string pass between two calls), which matches perfectly with a reload timer and the monotonic behaviour inside the main loop.

This strongly supports (I'd almost say, "it proves...") the assumption of the two comments of @markus-nm and @Chris Stratton, that you have a concurrency problem.

Their hints are correct - the easiest solution to fix it is getting a mutex (or simplified: disabling interrupts) before accessing the global resource where the two data sources shall be merged. The resource where your concurrency problem originates may be a buffer in RAM or even the UART port register itself. In case you are still new to concurrent programming, please watch out not to run into sync/deadlock problems when you add further mutexes around the features all over the system without experience or background knowledge.

A more powerful (but more sophisticated) solution to your concurrency problem would be to use an RTOS and have a small task only output to UART what other context send to its input queue. Then, the RTOS takes care of concurrency. But, any details of this strategy are beyond the scope of your question.

HelpingHand
  • 1,294
  • 11
  • 27