1
\$\begingroup\$

I am working on an embedded program on the TM4C123GH6PM microcontroller from the Texas Instruments Tiva C Series LaunchPad.

The program is supposed to sample an external ADC in a timer interrupt and push the converted values into a queue (in this case a array-based circular buffer).

The main loop is transferring the values (popping bytes out of the queue) to a PC through the UART.

Inside the timer interrupt, a check is done to ensure that space is available in the queue. If so, bytes are pushed onto the queue. If not, it stops the timer. The main loop will transfer the remaining bytes and start the timer again once the queue is empty (all bytes have been transferred).

My problem is that the timer is not always stopped even if the queue is full.

Could this be a concurrency problem? If so, how do I solve it?

By the way, I have played around with locks but this causes deadlocks. I have also ensured that the queue and related variables accessed both by the main loop and the timer interrupt is declared volatile.

Thanks in advance :-)

\$\endgroup\$
  • \$\begingroup\$ I don't think anyone will really be able to help without seeing your code. \$\endgroup\$ – DigitalNinja Oct 15 '15 at 18:33
  • \$\begingroup\$ My code is too complex to be posted right away. If I posted my code, nothing will make sense at all. I rather have a more general answer to the problem. I think my problem with a main loop and an interrupt handler interacting with the same data is a very common issue? \$\endgroup\$ – pvh1987 Oct 15 '15 at 18:45
  • \$\begingroup\$ You don't have to post all of it, just the parts that aren't working correctly. Maybe just the timer ISR, where you are stopping the timer. \$\endgroup\$ – DigitalNinja Oct 15 '15 at 18:56
2
\$\begingroup\$

If your queue has exactly one producer and one consumer make sure consumer has higher priority at all times. After this is achieved the concurrency won't cause any issues. Implementation depends on the hardware used, here's (my) code using such a queue on PIC24 micro -> https://github.com/felis/lcdtune/blob/master/lcdtune.c . The queue, as well as head and tail are defined here -> https://github.com/felis/lcdtune/blob/master/lcdtune.c#L50 , the producer is here -> https://github.com/felis/lcdtune/blob/master/lcdtune.c#L233 , and the consumer (the ISR) is here -> https://github.com/felis/lcdtune/blob/master/lcdtune.c#L102

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you very much. It will take some time for me to find out what is going on since I am not used to PIC, but it can't be that hard. I guess my problem could be that the consumer (popping bytes of the queue) has lower priority (main loop) than my producer (Timer ISR), right? \$\endgroup\$ – pvh1987 Oct 15 '15 at 20:37
  • \$\begingroup\$ nothing in the queue code is hw-specific. The priority of anything outside interrupt is zero, and interrupt is pointed to by the last link. \$\endgroup\$ – Oleg Mazurov Oct 15 '15 at 20:39
  • \$\begingroup\$ So I looked into your code and it seems to me, that you do the opposite of what I want to do. Your ISR is consuming, and your main loop is producing. Maybe I could put my consumer code into a software interrupt with higher priority than my Timer (producer) interrupt? \$\endgroup\$ – pvh1987 Oct 15 '15 at 21:19
  • \$\begingroup\$ I have now fixed the problem by putting the consumer in a interrupt with higher priority than my timer ISR. Thanks a lot for your solution :-) \$\endgroup\$ – pvh1987 Oct 16 '15 at 14:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.