FirmwareV2, osek, lcd

42 views
Skip to first unread message

Carlos Pantelides

unread,
Apr 25, 2018, 9:00:12 PM4/25/18
to CIAA-Firmware
Hola

Tengo un programita en osek parcialmente funcionando (asunto "FirmwareV2, osek, adc"), al cual quiero agregarle que use el display LCD.

Este programita es para dar una charla el sábado para lo cual me hubiese venido lindo hacerlo con osek, zafo con sapi baremetal, no hay problema.


Tengo un mail de como 80 lineas analizando todo lo que falla, puedo pegarlo si alguien lo quiere ver, pero creo que todo se reduce a:

1) No está implementado sapi_delay en freeOSEK.

Primero me imagine que por delayInaccurateUs() y delay() que no deben ser muy amigos de un sistema cooperativo, pero he visto que uart tambien es bloqueante, ¿funciona?

Ahora mas bien estoy pensando que tiene que ver mas con el systick o equivalente que osek lo usa y sapi tambien y evidentemente no a la vez y me suena haber oido/leído a Éric.


Pero si me queda tiempo o luego, me resulta en extremo muy instructivo tratar de resolver el problema de alguna de estas maneras:

2) Si vale bloquearse como con uart por breves períodos, se me ocurre que los tiempos de espera de lcd se pueden implementar con for(), puedo simplemente hacerlo así, sólo para esta vez.

3) Tambien se me ocurre un esquema medio complicado en el cual las esperas del setup son como en 1), pero las esperas posteriores mediante tasks ingeniosamente encadenadas, ahora no recuerdo bien que recusos hay disponibles, pero en el humus de mi cerebro me suena que es factible. Esto implica que para usar osek+lcd hay que partir de un .oil con algunas cosas ya precocinadas, a mi no me disgusta pero no sé si es la idea en general.

4) Me imagino que lo mejor sería de algún modo que delay pueda de algún modo "ver" el systick usado por osek y hacer sus menesteres, pero aun no comprendí lo suficiente de lo que ví.

Cualquier reflexión será bienvenida, perdón por lo latoso y si estoy diciendo gansadas, pero es mi manera de aprender.

Saludos



Eric Pernia

unread,
Apr 27, 2018, 2:06:01 AM4/27/18
to Carlos Pantelides, CIAA-Firmware
Buenas noches Charly, esto que preguntás parte del tema de las 2 sAPIs de Firmware v2 así entendés como viene la mano, respondo entre líneas:

El 25 de abril de 2018, 22:00, Carlos Pantelides <carlos.p...@gmail.com> escribió:
Hola

Tengo un programita en osek parcialmente funcionando (asunto "FirmwareV2, osek, adc"), al cual quiero agregarle que use el display LCD.

La biblio de LCD de sAPI, está armada para ser independiente de todo, hasta del resto la sAPI, cambiando estos define podrías usarlo para cualqueir micro:

https://github.com/ciaa/firmware_v2/blob/master/modules/lpc4337_m4/sapi/inc/sapi_lcd.h#L73


Este programita es para dar una charla el sábado para lo cual me hubiese venido lindo hacerlo con osek, zafo con sapi baremetal, no hay problema.


Tengo un mail de como 80 lineas analizando todo lo que falla, puedo pegarlo si alguien lo quiere ver, pero creo que todo se reduce a:

1) No está implementado sapi_delay en freeOSEK.

La idea es NO USAR las funciones de delay o tick de sAPI cuando se hace un programa con RTOS ya que este se encarga de gestionar todos los tiempos. Entonces conceptualmente estarías haciendo lío. Para bare metal vienen bien para ayudarte a gestionar tiempos pero si pasas a un RTOS el debería tener la responsabilidad de manejar los tiempos.

Una alternativa que estuvimos probando con Martín para Firmware v3 es que al usar RTOS las funciones de sAPI pasen a usar la API de tiempos del RTOS por debajo en lugar del hardware directemente. Pero la verdad no me termina de convencer (aunque está funcionando con FreeRTOS si lo querés probar).

Después está el tema de manejo de interrupcionesÑ

En freeRTOS el Sistema Operativo no absorve el manejo de las interrupciones, es decir la manejas vos con lo que ofrece el fabricante, lo único que si hace es tener el FreeRTOS una API especial para cuando usas cosas del S.O. desde funciones de interrupción. O sea, es la misma API pero le agrega a "fromISR" a los nombres d elas funciones. De esta manera se asegura no hacer líos entre los cambios de contexto propios del sistema apropiativo y los que provoquen otras interrupciones aparte de la de SysTick que usa el S.O. de base de tiempos.

En OSEK la cosa es distinta, es mucho más invasivo, tiene su propia tabla de interrupciones y las maneja el sistema operativo, de hachohay 2 tipos, una en la que el sistema hace sus cosas y leugo ejecuta tu código d einterrupción y el otro tipo en que realmente te encargás vos de tocar el hardware directamente.

Es por esto último que hay 2 sAPIs en Firmware v2, por un lado por las funciones de sapi_tick que usan el systick y tanto FreeRTOS como OSEK lo usan como base de temporización. Por otro lado el OSEK absrove todo el resto de las interrupciones entonces no deberías usar ninguna directamente sin que sea a través de el. Esto hizo que en la sAPI para RTOS saque la API de PWM y servo además de la de tick porque usaba también interrupciones. La de UART también las usa pero en la versión de sarpi RTOS le borré esa parte ya que era opcional.

Primero me imagine que por delayInaccurateUs()

Ese delay es más bien académico, para msotrar que se puede hacer un delay inexacto en base a contar cuanto duran unas instrucciones y loopearlas en un for para perder tiempo.
 
y delay()

Este es bloqueante como el inexacto pero usa la base de tiempos que le da las funciones de sapi_tick para tener un delay más exacto.

sapi_tick  usa el periférico Systick, en otro micro sin este epriférico podrá ser un timer común, como TIMER2 en la sAPI para AVR que hice.
 
que no deben ser muy amigos de un sistema cooperativo,

Nada bloqueante es amigo de un sistema cooperativo, tanto FreeRTOS como OSEK pueden usarse en modo cooperativo o apropiativo.
 
pero he visto que uart tambien es bloqueante, ¿funciona?

Depende como la uses.

Si haces una tarea única que use la UART desde un buffer (en OSEK no viene, se puede usar el de sAPI o el que proveen en LPCOpen, en freeRTOS son las queues) y lo que hace la tarea es que cada vez que hay un nuevo byte en el buffer se desbloquea, envía un byte y se vuelve a bloquear no pasa nada.

Si en cambio en una tarea envias por UART todo un texto usando uartWriteString() y desde otra tarea haces lo mismo (ambas a la misma prioridad) te va a pasar que en freeRTOS te salen los textos mezclados porque hace round robin de las tareas, es decir, te las fetea el tiempo de tick y las mezcla ejecutando un cachito de cada una. En OSEK si tienen la misma prioridad las tareas son cooperativas a  mismo nivel de prioridad y no pasa nada, si hay una de mayor prioridad te meteria en el medio de un texto si T1 se corta todo el texto de T2 de mayor prioridad.

Entonces cuando usamos una tarea o más que manejan un cierto periférico en un RTOS para evitar estos problemas de concurrencia de tareas que quieran usar el mismo recurso entonces podemos decir que esa tarea es un driver de UART para ese S.O.

El otro modo es usar interrupciones, según uses OSEK o FreeRTOS se hace de formas distintas.

Todos estos párrafos es lo mismo para cualquier otro periférico.

 

Ahora mas bien estoy pensando que tiene que ver mas con el systick o equivalente que osek lo usa y sapi tambien y evidentemente no a la vez y me suena haber oido/leído a Éric.

Si, lo que puse más arriba.


Pero si me queda tiempo o luego, me resulta en extremo muy instructivo tratar de resolver el problema de alguna de estas maneras:

2) Si vale bloquearse como con uart por breves períodos, se me ocurre que los tiempos de espera de lcd se pueden implementar con for(), puedo simplemente hacerlo así, sólo para esta vez.

Usá la API del RTOS para el manejo de tiempos, en este caso las alarmas en OSEK.

3) Tambien se me ocurre un esquema medio complicado en el cual las esperas del setup son como en 1), pero las esperas posteriores mediante tasks ingeniosamente encadenadas, ahora no recuerdo bien que recusos hay disponibles, pero en el humus de mi cerebro me suena que es factible. Esto implica que para usar osek+lcd hay que partir de un .oil con algunas cosas ya precocinadas, a mi no me disgusta pero no sé si es la idea en general.

4) Me imagino que lo mejor sería de algún modo que delay pueda de algún modo "ver" el systick usado por osek y hacer sus menesteres, pero aun no comprendí lo suficiente de lo que ví.

Si, tenes que armar una alarma de OSEK que mueva un contador por ejemplo cada 10 ms (como hice con los programas que genera IDE4PLC) que usa OSEK como RTOS de los programas que genera a partir del LADDER. Para los Timers de PLC usa una tarea que es disparada por una alarma cada 10 ms, o sea, que esa es su resolución. Entonces reemplazas el sapi_tick por uno que use esto de osek para incrementar el tick y ahi delay sería válido, de todas maneras aunque en el S.O. apropiativo podés usar grandes esperas bloqueantes esto NUNCA ES RECOMENDABLE porque si en ese tiempo no mecha otras tareas simplemente podrias mandarlo a sleep para que no consuma, o sea, estas desperdiciando energía. Lo recomendable es usar algo que bloquee la tarea y si no queda ninguna en ejecución se vaya a dormir hasta el siguiente tick.

En resumen sería que si abastraemos con sAPI la API de delay del RTOS hay que hacerlo de manera que bloquee las tareas correctamente. Si solo abstraemos tick va a funcionar pero para nada es algo eficiente.
 

Cualquier reflexión será bienvenida, perdón por lo latoso y si estoy diciendo gansadas, pero es mi manera de aprender.

No hay drama, en la medida que tengo tiempo te puedo responder. Para esto que necesitas para el sábado te recomiendo que lo hagas baremetal si lo podés resolver así.

Saludos,
Eric.
 

Saludos



--
Has recibido este mensaje porque estás suscrito al grupo "CIAA-Firmware" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a ciaa-firmware+unsubscribe@googlegroups.com.
Visita este grupo en https://groups.google.com/group/ciaa-firmware.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Carlos Pantelides

unread,
Apr 27, 2018, 7:04:53 PM4/27/18
to CIAA-Firmware
Como siempre Éric, muchas gracias por tus didácticas y elaboradas explicaciones.

Para el sábado sí, estoy usando sapi pelado, lo estoy terminando ahora, espero.

Con respecto a osek, este es el mensaje, que entiendo está provocado por que lcd usa [delay]InaccurateUs() que no existe por los motivos por tí expuestos.

¿No sería prolijo por ahora borrar sapi_rtos/sapi_lcd de Firmware_v2?

Yo igual luego haré un esfuerzo inhumano por que no se me hunda en la pila de cosas postergadas el ver de reimplementar en ese contexto, guiándome por lo que has escrito.

Saludos, man


*** linking project freeOSEK ***
out/lpc4337_m4/libsapi_rtos.a(sapi_lcd.o): In function `lcdEnablePulse':
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:59: undefined reference to `delayInaccurateUs'
out/lpc4337_m4/libsapi_rtos.a(sapi_lcd.o): In function `lcdCommand':
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:81: undefined reference to `delayInaccurateUs'
out/lpc4337_m4/libsapi_rtos.a(sapi_lcd.o): In function `lcdInit':
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:122: undefined reference to `delay'
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:125: undefined reference to `delayInaccurateUs'
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:128: undefined reference to `delayInaccurateUs'
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:131: undefined reference to `delayInaccurateUs'
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:137: undefined reference to `delayInaccurateUs'
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:142: undefined reference to `delayInaccurateUs'
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:144: undefined reference to `delay'
out/lpc4337_m4/libsapi_rtos.a(sapi_lcd.o): In function `lcdGoToXY':
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:151: undefined reference to `delayInaccurateUs'
out/lpc4337_m4/libsapi_rtos.a(sapi_lcd.o): In function `lcdClear':
/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2/modules/lpc4337_m4/sapi_rtos/src/sapi_lcd.c:157: undefined reference to `delay'
collect2: error: ld returned 1 exit status
Makefile:115: recipe for target 'freeOSEK' failed
make[1]: *** [freeOSEK] Error 1
make[1]: Leaving directory '/home/carlos/Desktop/ciaa/github/cpantel/Firmware_v2'
Makefile:66: recipe for target 'all' failed
make: *** [all] Error 2

Saludos



Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a ciaa-firmwar...@googlegroups.com.

Eric Pernia

unread,
Apr 29, 2018, 6:32:04 PM4/29/18
to Carlos Pantelides, CIAA-Firmware
El inaccurate no molesta porque es un dir vloqueante. No usa systick. 
Reply all
Reply to author
Forward
0 new messages