TODOPIC
Microcontroladores PIC => RTOS => Mensaje iniciado por: fram_22 en 05 de Septiembre de 2012, 13:57:45
-
HOla:
estoy comenzando a utilizar freertos con un dspic33fj128mc802. Deseo utilizar un semaforo ligado a una interrupccion.
Sin emgaro me confundo un poco como utilizarlo ya que en un ejemplo que vi (de un cortex) viene este ejemplo de uso del semaforo en la interrupcion:
void vSoftwareInterruptHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* 'Give' the semaphore multiple times. The first will unblock the handler
task, the following 'gives' are to demonstrate that the semaphore latches
the events to allow the handler task to process them in turn without any
events getting lost. This simulates multiple interrupts being taken by the
processor, even though in this case the events are simulated within a single
interrupt occurrence.*/
xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken );
xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken );
xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken );
xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken );
/* Clear the software interrupt bit using the interrupt controllers
Clear Pending register. */
mainCLEAR_INTERRUPT();
/* Giving the semaphore may have unblocked a task - if it did and the
unblocked task has a priority equal to or above the currently executing
task then xHigherPriorityTaskWoken will have been set to pdTRUE and
portEND_SWITCHING_ISR() will force a context switch to the newly unblocked
higher priority task.
NOTE: The syntax for forcing a context switch within an ISR varies between
FreeRTOS ports. The portEND_SWITCHING_ISR() macro is provided as part of
the Cortex M3 port layer for this purpose. taskYIELD() must never be called
from an ISR! */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
donde dice que la función taskyield nunca debe ser llamada desde una ISR. Sin embargo en otro ejemplo de uso de colas en un dspic me encuentro con lo siguiente:
void __attribute__((__interrupt__, auto_psv)) _U2RXInterrupt( void )
{
char cChar;
portBASE_TYPE 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();
}
}
alguien ha utilizado semáforos en pics o dspics? Este me parece confuso. Cualquier ayuda se las agradezco de antemano
saludos!
-
Yo también pase por la misma duda, y a lo que dice en la pagina de freeRTOS depende del port que se este usando:
http://www.freertos.org/FreeRTOS_Support_Forum_Archive/October_2011/freertos_taskYIELD_in_an_ISR_4743414.html
void __attribute__((__interrupt__,auto_psv)) _DMA1Interrupt(void)
{
// canal 1 configurado para RX para el controlador CAN número 1
// Lo único que tiene que hacer es activar la tarea que procesará el mensaje que
// que buffer se ha llenado
// que filtro ha tenido exito?
//escribe_led_lp(2);
//while(1);
portBASE_TYPE xHigherPriorityTaskWoken_lp = pdFALSE;
portBASE_TYPE xHigherPriorityTaskWoken_hp = pdFALSE;
portBASE_TYPE res_lp=pdFAIL;
portBASE_TYPE res_hp=pdFAIL;
// 'Give' the semaphore to unblock the task. */
if ((C1RXFUL1&0x00FF)!=0) // high priority
res_hp=xSemaphoreGiveFromISR( ECAN_SemHP, &xHigherPriorityTaskWoken_hp );
if (((C1RXFUL1&0xFF00)!=0)||((C1RXFUL2&0xFFFF)!=0)) // low priority
res_lp=xSemaphoreGiveFromISR( ECAN_SemLP, &xHigherPriorityTaskWoken_lp );
// Giving the semaphore may have unblocked a task - if it did and the
// unblocked task has a priority equal to or above the currently executing
// task then xHigherPriorityTaskWoken will have been set to pdTRUE and
// portEND_SWITCHING_ISR() will force a context switch to the newly unblocked
// higher priority task.
// NOTE: The syntax for forcing a context switch within an ISR varies between
// FreeRTOS ports. The portEND_SWITCHING_ISR() macro is provided as part of
// the PIC32 port layer for this purpose. taskYIELD() must never be called
// from an ISR!
// EN LA DEMO PARA dspic EMPLEA taskYIELD() de esta forma
if ((res_lp==pdPASS)&&(xHigherPriorityTaskWoken_lp))
taskYIELD();
if ((res_hp==pdPASS)&&(xHigherPriorityTaskWoken_hp))
taskYIELD();
IFS0bits.DMA1IF = 0;
}
Saludos!!
-
Muchas gracias por tu respuesta:
Me has aclarado una gran duda. Lastima que no exista un libro para dspics y freertos tal y como lo existe para el pic32. Eso podria ayudar a solucionar dudas como esta.
Alguien quizás conozca un buen libro al respecto, cualquier recomendación sera amplia mente agradecida. Yo solo conozco el libro "Sistemas empotrados en tiempo real", el cual mencionaste en otro hilo.
saludos!
-
Lastima que no exista un libro para dspics y freertos tal y como lo existe para el pic32.
Hola fram_22, apenas estoy comenzando en el mundo del RTOS y tu mencionaste que existe un libro para freertos con pic32 y quisiera saber cual es, ya que estoy trabajando con un pic32 y de verdad me seria de gran ayuda.
Muchas gracias.
-
Lo encuentras en la página de Freertos, sale algo así como 35 u$s Creo que se refiere a ese, no he visto otro :roll:
Edit: http://shop.freertos.org/FreeRTOS_Tutorial_Book_Microchip_PIC32_Edition_p/pdf_pic32_tutorial_book.htm
-
A bueno no lo conocía, seria bueno comprarlo... vamos a ver cuando se podra.
-
Lastima que no exista un libro para dspics y freertos tal y como lo existe para el pic32.
Hola fram_22, apenas estoy comenzando en el mundo del RTOS y tu mencionaste que existe un libro para freertos con pic32 y quisiera saber cual es, ya que estoy trabajando con un pic32 y de verdad me seria de gran ayuda.
Muchas gracias.
HOla yo conosco 3 libros la respecto, uno es que esta en venta en el sitio de freertos, el otro es "Sistemas Empotrados en Tiempo Real Por José Daniel Muñoz Frías" viene bien explicado y con ejemplos. te puedes descargar la version de PDF gratis desde la pagina de ww.lulu.com
El tercer libro que conosco lo puedes ver aqui (http://www.crcpress.com/product/isbn/9781439841549). Sin embargo aun estoy esperando que me lo entreguen.
espero la información te sea de utilidad.
-
El esquema que intentas utilizar es simple.
1. Ocurre un evento y pide interrupción
2. Se desencadena el proceso de atención a la nterrupción en el uC
3. El proceso de atención redirecciona el contador de programas a la ISR (subrrutina de atención a interrupción)
4. En el código de la ISR se entrega un semáforo binario o contador con xSemaphoreGuive() (no puedes utilizar MUTEX para esto)
5. Terminas el proceso de interrupción
6. La tarea liberada comienza a ejecutar código y cuando termina pide nuevamente el semáforo.
Para que el esquema funcione bien el semáforo debe ser tomado inmediatamente después de creado o creado con cero tokens si es contador. De esta forma la tarea quedará bloqueada la primera vez que intente tomarlo y esperará por la interrupción que es quién da el give().
Otro detalle es colocar el código de habilitación de la interrupción antes del for de la tarea, de este modo disminuyes la probabilidad de que la ISR se ejecute antes que la tarea y evitas molestos funcionamientos erráticos de tu código (lo digo por mi propia expeirencia) además debes limpiar cualquier solicitud de interrupción pendiente antes de ejecutar el código de tareas.
En cuanto al uso de TaskYield() es cierto que depende del tipo de puerto, lo que ocurre es que una vez que la ISR da el semáforo podría ocurrir que la tarea que espera por él sea la de más alta prioridad y la única forma de hacer que al salir del la ISR sea esta la que comience a ejecutar código es forzar un cambio de contexto. Algunos puertos utilizan una macro específica para esto, mientras que otros sobrecargan a vTaskYield con el mismo propósito o simplemente la utilizan tal cual. Sin embargo debes ver cómo funciona en tu puerto porque puede haber problemas si no utilizas la función apropiada.
Saludos
Reinier
-
Muchas gracias por la explicación. ha dejado mas claro el asunto.!