FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [October 2014 Threads] Queue helpPosted by tomirtos on October 28, 2014 Hi all!
I am trying to use a qeueu to get data from an interrupt to a task.
The interrupt is trigged by the UART. I receive a character there and send it with a queue to a task. The task should evaluate what character it received and according to that should light a led.
In the same task I also have a function that will send back the character that the microcontroller received just to test if the queue was working. I receive the character on my serial monitor no problem. The problem is I start receiving the same character over and over again even if I don't send any new characters. I don't really understand why this is happening, because when I used queues before the same way this never happened. Can anyone please explain this behaviour to me?
this is my task:
~~~~~~~~~~~~~~~~~~~
xQueueHandle UART_queue=0;
/******************************************************************************/
void examinertask()
{
while (1)
{
char stringreceived;
if(xQueueReceive( UART_queue , &string_received , 1000))
{
if( string_received=='s' )
{
LATAbits.LATA0=1;
}
else LATAbits.LATA0=0;
}
UART1PutChar(string_received);
}
}
~~~~~~~~~~~~~~~~
this is the interrupt handler:
~~~~~~~~~~~~~~~
void attribute((interrupt, noautopsv)) U1RXInterrupt(void)
{
unsigned char datain = 0;
data_in=U1RXREG; // save register value
xQueueSend(UART_queue , &data_in , 1000); // send data via queue
_U1RXIF = 0; // Clear the UART Recieve Interrupt Flag
}
~~~~~~~~~~~~~~~
Queue helpPosted by tomirtos on October 28, 2014 if I use xQueueSendToFrontFromISR(UARTqueue, &datain, &xHigherPriorityTaskWoken);
the same thing is happening
Queue helpPosted by markwrichardson on October 28, 2014 UART1PutChar() will be called with the last character for every loop regardless of an item in the queue. Before your first letter received, it will output whatever is in string_received at initialization.
Queue helpPosted by tomirtos on October 28, 2014 but isnt the task only woken up when there is something in the queue?
Queue helpPosted by rtel on October 28, 2014
send it with a queue to a task.
That is fine for low bandwidth comms, such as receiving key presses, but
very inefficient for high bandwidth comms where a circular buffer or DMA
is better.
while (1)
{
char string_received;
if(xQueueReceive( UART_queue , &string_received , 1000))
{
if( string_received=='s' )
{
LATAbits.LATA0=1;
}
else LATAbits.LATA0=0;
}
UART1PutChar(string_received);
}
}
If you receive only one character then this code will print out that
character every 1000 ticks. That is because you have the queue receive
timeout set to 1000, and print the character stored in string_received
whether a new value was received on the queue or not. Moving the
UART1PutChar() call inside the if() statement would fix that.
void attribute((interrupt, noautopsv)) _U1RXInterrupt(void)
I'm guessing this is a PIC32? Please read the documentation page for
this port as the way you are defining your interrupt is going to waste a
lot of RAM (although it will work).
xQueueSend(UART_queue , &data_in , 1000); // send data via queue
xQueueSend() cannot be called from an interrupt and definitely cannot
attempt to block in an interrupt. Please use xQueueSendFromISR()
instead and be sure to read the FAQs, especially the FAQ "My application does not
run, what could be wrong?".
Regards.
Queue helpPosted by rtel on October 28, 2014
but isnt the task only woken up when there is something in the queue?
Please see my reply to your first post - your code is not checking if
anything is received or not before just printing out whatever was
received last.
Regards.
Queue helpPosted by tomirtos on October 28, 2014 Thank you for the answers, cleared up a lot of things!
I am using a dspic33fj128mc802.
"Please read the documentation page for
this port"
http://www.freertos.org/portpic24_dspic.html
This was all I found, but i'm not sure what I should be looking for in here. I don't know any alternative ways of declaring an interrupt handler. Is this only a FreeRTOS concern or if I weren't using FreeRTOS this declaration would still be bad?
Thanks!
Cheers
Queue helpPosted by rtel on October 28, 2014 Sorry - I was thinking it was a PIC32 - you can disregard that part of
my reply.
Regards.
Queue helpPosted by tomirtos on October 28, 2014 In the dspic demo project in serial.c this is how interrupts are defined, they are the same as mine:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void attribute((interrupt, autopsv)) _U2RXInterrupt( void )
{
char cChar;
portBASETYPE xHigherPriorityTaskWoken = pdFALSE;
/* Get the character and post it on the queue of Rxed characters.
If the post causes a task to wake force a context switch as the woken task
may have a higher priority than the task we have interrupted. */
IFS1bits.U2RXIF = serCLEAR_FLAG;
while( U2STAbits.URXDA )
{
cChar = U2RXREG;
xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
}
if( xHigherPriorityTaskWoken != pdFALSE )
{
taskYIELD();
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Queue helpPosted by tomirtos on October 28, 2014 Sorry I didn't see your reply!
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|