FirmwareV2, osek, adc

90 views
Skip to first unread message

Carlos Pantelides

unread,
Apr 23, 2018, 9:26:55 PM4/23/18
to CIAA-Firmware
Hola,

¿estoy más o menos bien encaminado para leer un ADC de modo no bloqueante con osek?

por favor aún no una respuesta completa, sólo pistas y advertencias, me interesan sobre todo las lineas terminadas en #####

Saludos

Charli


[main.oil]

   TASK adcReadCallBackTask {
      PRIORITY = 2;
      ACTIVATION = 1;
      STACK = 512;
      TYPE = BASIC;
      SCHEDULE = NON;
   }

    ISR ISR_ADC0 {
        CATEGORY = 2;
        INTERRUPT = ADC0;
        PRIORITY = 0;
      }

    TASK initTask {
      PRIORITY = 2;
      ACTIVATION = 1;
      STACK = 512;
      TYPE = BASIC;
      SCHEDULE = NON;
    }


[main.c]

ISR( ISR_ADC0 )
{
    ActivateTask( adcReadCallBackTask );
    Chip_PININT_ClearIntStatus( LPC_GPIO_PIN_INT,PININTCH( 0 ) );   ######
}

TASK( adcReadCallBackTask )
{
     channel = obtener de algun lado, quizas global
    uint16_t analogValue = adcReadCallBack( channel );
    // hace algo con analogValue //
   
    // podria seguir con invocar initTask
    TerminateTask();
}

TASK (initTask)
{
         // irrelevante desde donde es iniciada, primera vez puede ser autostart, siguientes por adcReadCallBackTask

         channel = obtener de algun lado, quizas global
         adcReadAsync(channel);
        TerminateTask();
}

[modules/lpc4337_m4/sapi/src/sapi_adc.c]

void adcReadAsync( adcMap_t analogInput ){

   uint8_t lpcAdcChannel = 66 - analogInput;

   Chip_ADC_EnableChannel(LPC_ADC0, lpcAdcChannel, ENABLE);

   Chip_ADC_Int_SetChannelCmd( LPC_ADC0, ADC_CH1, ENABLE );    #####

   Chip_ADC_SetStartMode(LPC_ADC0, ADC_START_NOW, ADC_TRIGGERMODE_RISING);   #####

}

uint16_t adcReadCallBack(adcMap_t analogInput) {

   uint8_t lpcAdcChannel = 66 - analogInput;

   uint16_t analogValue = 0;

   Chip_ADC_ReadValue( LPC_ADC0, lpcAdcChannel, &analogValue );

   Chip_ADC_EnableChannel( LPC_ADC0, lpcAdcChannel, DISABLE );

   return analogValue;

}

Matias Loiseau

unread,
Apr 24, 2018, 6:17:56 AM4/24/18
to CIAA-Firmware
Hola Charlie te escribo recién levantado y que lo leei muy por arriba pero mí pequeño aporte sería que te acuerdes que nosotros cuando usamos osek con sapi, usamos el module modules/lpc4337_m4/sapi_rtos.

Saludos !

Carlos Pantelides

unread,
Apr 24, 2018, 6:53:58 AM4/24/18
to Matias Loiseau, CIAA-Firmware
Gracias Matías, voy a revolver en los apuntes, pero quizás eso haya cambiado, partí del ejemplo actual de FirmwareV2, que no existía en ese momento.


Ahora me está compilando pero no linkea, no le debo estar pegando a algún nombre. Cambié algunos nombres con respecto al código anterior


[.oil]

   RESOURCE=AnalogValue;

   TASK adcStartAsyncWrapperTask {

      PRIORITY = 2;
      ACTIVATION = 1;
      STACK = 512;
      TYPE = EXTENDED;
      SCHEDULE = NON;
      AUTOSTART = TRUE {
          APPMODE = AppMode1;
      }
   }

   TASK adcReadAsyncWrapperTask {  -> va a ser ISR

      PRIORITY = 2;
      ACTIVATION = 1;
      STACK = 512;
      TYPE = EXTENDED;
      SCHEDULE = NON;
      RESOURCE = AnalogValue;
   }
  
   ALARM ActivateAdcStartAsyncWrapperTask{
      COUNTER = HardwareCounter;
      ACTION = ACTIVATETASK {
         TASK = adcStartAsyncWrapperTask;
      }
      AUTOSTART = TRUE {
          APPMODE = AppMode1;
          ALARMTIME = 500;
          CYCLETIME = 900;
      }
   }


[embrión de .c para ver si compila y hace algo, aun sin ADC]

TASK(adcStartAsyncWrapperTask)
{
   gpioToggle( LEDB );

   // adcStartAsync(xxx);

   TerminateTask();
}

TASK(adcReadAsyncWrapperTask) --> va a ser ISR
{
   GetResource(AnalogValue);  --> me parece recordar que no era buena idea usar resources en ISR, tengo que repasar

   gpioToggle( LED3 );

   adcReadAsync(xxx);

   ReleaseResource(AnalogValue);

   TerminateTask();
}


[modificación a modules/lpc4337_m4/sapi_rtos/src/sapi_adc.c]

/*
 * @brief   Start ADC sampling in one ADC channel. Mode: NONBLOCKING
 * @param   AI0 ... AIn
 * @return  void
 */
void adcStartAsync( adcMap_t analogInput ){


   uint8_t lpcAdcChannel = 66 - analogInput;

   Chip_ADC_EnableChannel(LPC_ADC0, lpcAdcChannel, ENABLE);

   Chip_ADC_Int_SetChannelCmd( LPC_ADC0, ADC_CH1, ENABLE );    //#####

   Chip_ADC_SetStartMode(LPC_ADC0, ADC_START_NOW, ADC_TRIGGERMODE_RISING);

}

/*
 * @brief   Get the value of one ADC channel. Mode: NONBLOCKING
 * @param   AI0 ... AIn
 * @return  analog value
 */
uint16_t adcReadAsync( adcMap_t analogInput ){


   uint8_t lpcAdcChannel = 66 - analogInput;
   uint16_t analogValue = 0;

   Chip_ADC_ReadValue( LPC_ADC0, lpcAdcChannel, &analogValue );

   Chip_ADC_EnableChannel( LPC_ADC0, lpcAdcChannel, DISABLE );

   return analogValue;
}
 
2018-04-24 7:17 GMT-03:00 Matias Loiseau <matias...@gmail.com>:
Hola Charlie te escribo recién levantado y que lo leei muy por arriba pero mí pequeño aporte sería que te acuerdes que nosotros cuando usamos osek con sapi, usamos el module modules/lpc4337_m4/sapi_rtos.

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 obtener más opciones, visita https://groups.google.com/d/optout.



--

Eric Pernia

unread,
Apr 24, 2018, 7:27:35 AM4/24/18
to Carlos Pantelides, Matias Loiseau, CIAA-Firmware
En firmware v2 el módulo sAPI está repetido, una vesión para bare metal y otra para RTOS, hay que usar la de RTOS con OSEK o FreeRTOS.

En el Fv3 ya lo solucionamos eso (hay un único módulo sAPI) pero no migramos aún el OSEK.

Lo demás cuando pueda lo reviso tranquilo.

Saludos.
Eric.

Para acceder a más opciones, visita https://groups.google.com/d/optout.

Carlos Pantelides

unread,
Apr 24, 2018, 7:00:11 PM4/24/18
to CIAA-Firmware
bien, voy bien encaminado, pero con obstáculos

en gen/src/cortexM4/Os_Internal_Arch_Cfg.c apareció
   OSEK_ISR2_adcReadAsyncWrapperISR, /* 0x21 0x00000084 ISR for ADC0 (IRQ 17) Category 2 */

así que le atiné al nombre de interrupción, iujjuuuu!!!!

pude compilar, linkear (recordé que los nombres de .oil y .c deben coincidir) y desplegar en la placa. primero sin la ISR, la task adcStartAsyncWrapperTask andaba ok

luego tal como está ahora, arranca, prende los dos leds y muere, a debugear

aviso de esta situación, Éric, para que no te pongas a ver versiones viejas, igual no le he podido aun invertir un tiempo, así que esperame antes de hacer cualquier análisis por encima de superficial

saludos y gracias

charlie





[codigo.oil]

   RESOURCE=AnalogValue;

   TASK adcStartAsyncWrapperTask {

      PRIORITY = 2;
      ACTIVATION = 1;
      STACK = 512;
      TYPE = EXTENDED;
      SCHEDULE = NON;
      AUTOSTART = TRUE {
          APPMODE = AppMode1;
      }
   }

   ISR adcReadAsyncWrapperISR {

      INTERRUPT = ADC0;
      PRIORITY = 0;
      CATEGORY = 2;

      RESOURCE = AnalogValue;
   }
  
   ALARM ActivateAdcStartAsyncWrapperTask{
      COUNTER = HardwareCounter;
      ACTION = ACTIVATETASK {
         TASK = adcStartAsyncWrapperTask;
      }
      AUTOSTART = TRUE {
          APPMODE = AppMode1;
          ALARMTIME = 500;
          CYCLETIME = 900;
      }
   }

[codigo.c]

uint16_t muestra = 0;

int main( void )  {
   boardConfig();
   adcConfig(ADC_ENABLE); 
   StartOS(AppMode1);
   return 0;
}

TASK(adcStartAsyncWrapperTask)  {
   gpioToggle( LEDB );
   adcStartAsync(CH1);
    TerminateTask();
}
 
ISR (adcReadAsyncWrapperISR)  {
   //GetResource(AnalogValue);
    gpioToggle( LED3 );
   muestra = adcReadAsync(CH1);
    //ReleaseResource(AnalogValue);
 }


[modificación a modules/lpc4337_m4/sapi_rtos/
src/sapi_adc.c]

/*
 * @brief   Start ADC sampling in one ADC channel. Mode: NONBLOCKING
 * @param   AI0 ... AIn
 * @return  void
 */
void adcStartAsync( adcMap_t analogInput ){


   uint8_t lpcAdcChannel = 66 - analogInput;

   Chip_ADC_EnableChannel(LPC_ADC0, lpcAdcChannel, ENABLE);

   Chip_ADC_Int_SetChannelCmd( LPC_ADC0, ADC_CH1, ENABLE );    //#####

   Chip_ADC_SetStartMode(LPC_ADC0, ADC_START_NOW, ADC_TRIGGERMODE_RISING);

}

/*
 * @brief   Get the value of one ADC channel. Mode: NONBLOCKING
 * @param   AI0 ... AIn
 * @return  analog value
 */
uint16_t adcReadAsync( adcMap_t analogInput ){


   uint8_t lpcAdcChannel = 66 - analogInput;

Carlos Pantelides

unread,
Apr 24, 2018, 7:04:59 PM4/24/18
to CIAA-Firmware
ya lo arregle, me faltaba


   Chip_PININT_ClearIntStatus( LPC_GPIO_PIN_INT,PININTCH( 0 ) );

en la ISR

cuando me pueda hace un rato le conecto algo al adc y lo muestro por lcd
      Chip_PININT_ClearIntStatus( LPC_GPIO_PIN_INT,PININTCH( 0 ) );
 }


Carlos Pantelides

unread,
Apr 29, 2018, 6:39:03 PM4/29/18
to CIAA-Firmware
Éric y si alguien más quiere mirar, Franco, alguien del curso de RTOS:

Implementé adc read no bloqueante para free osek[1] y lo estoy usando con aparente éxito[2]. Está funcionando aunque puede ser que le falte estilo y tenga alguna falla de diseño, pues aunque el resultado es el mismo que la versión sapi[3], la FSM está ciclando de un modo que no diagnostiqué aun si es legítimo.


La idea es que hay que tener una TASK que llame a adcStartAsync() que lo que hace es la primera mitad de lo que hace adcRead() y setea que se llame una interrupción.

Luego, debe existir una ISR que llame a adcReadAsync(), que hace la segunda mitad, opcionalmente llamando a
adcClearInterrupt()

Aunque estoy usando el poncho educativo por que apunto a usar el lcd con freeOSEK, no hace falta para lo actual.


Sigo experimentando antes de proponer un pull request, pero me vendría bien algún feedback, ya sea de algo fundamental como de estilo y nombres.

Gracias y saludos



[1] https://github.com/cpantel/firmware_v2/tree/feature/asyncAdcRead
     https://github.com/cpantel/firmware_v2/blob/feature/asyncAdcRead/modules/lpc4337_m4/sapi_rtos/src/sapi_adc.c
[2] https://github.com/cpantel/Pendulometro/tree/master/edu-ciaa-nxp/freeOSEK
[3] https://github.com/cpantel/Pendulometro/tree/master/edu-ciaa-nxp/sapi

On Monday, April 23, 2018 at 10:26:55 PM UTC-3, Carlos Pantelides wrote:Hola,

Franco Bucafusco

unread,
Apr 30, 2018, 6:21:33 PM4/30/18
to ciaa-f...@googlegroups.com

Carlos,

    Dos cosas:

    - Acordate que mandar bytes por la UART en un handler de ISR no es buena practica. Posiblemente lo estes haciendo para probar... pero te aviso.

    - Y, puntuelmente con lo que estoy viendo (y posiblemente te este faltando porque todavia esta en pañales) es enviar un evento desde el handler de isr a la tarea que luego evalue lo que ocurrio (en tu caso que este o no debajo del umbral). Tambien medis tiempo. Eso lo podes hacer en una varaible global, pero acordate de las secciones criticas.

    Esto quedaría como un ejemplo de fwv2 ?

    Solo eso.

    sds

    FB

--
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-firmwar...@googlegroups.com.

Carlos Pantelides

unread,
May 1, 2018, 10:33:38 AM5/1/18
to Franco Bucafusco, CIAA-Firmware
Franco,

Uso la UART por que necesito ver el valor, que en realidad quería ver en LCD, que no está implementado y hay que resolver un problema a la vez.

Voy a apalear al programa hasta ponerlo "en forma".

1) sacar el mostrar el valor de la ISR (eventos)
2) acceder de modo disciplinado al contador (resources)
3) ver por que no tiene el mismo comportamiento la FSM con sapi bare, que quizás sea corrija con lo anterior


>    Esto quedaría como un ejemplo de fwv2 ?

No sé lograré alcanzar la calidad necesaria.

Muchísimas gracias







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.

--
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,
May 6, 2018, 6:32:28 PM5/6/18
to CIAA-Firmware
A ver que les parece, llevo muchísimas horas a lo largo de días y estoy bloqueado. Hago un resumen para que no haga falta ver el resto de la cadena, aunque es el mismo tema.

Resumen: estoy intentando en lugar de usar acdRead, separar en adcStartNonBlocking y adcReadNonBlocking, tal que el segundo sea llamado en el contexto de una ISR en freeOSEK

Sin entrar en mucho detalle, aunque el código está en [1] y [2], tras mucho probar y mirar fijo la documentación he llegado a la conclusión de que el ADC arranca y no hace una sola conversión, sino que hace una cada tiempo N y dispara una interrupción, lo cual me mata todo. Si es así, no he logrado bajar la frecuencia ni llegar a deshabilitar interrupciones en la ISR.

Preguntas:

1) ¿Es así?

2.a) Si es así, ¿puedo con la implementación actual cambiar un sólo parámetro tal que baje la frecuencia o tome una sola muestra?

2.b) ¿Debo configurar un pwm que le pegue al trigger del adc, si es que esto existe y así regular la frecuencia? Esto es medio loco, no?, como mandarse mails a uno mismo para recordar que hacer. Es que por lo que vi en la documentación los nombres de las cosas insinuan este camino, pero son tantas opciones que no voy a llegar a tiempo a explorarlas antes de que se me acabe el tiempo que le había asignado a este asunto, más que ya me está funcionando ok con osek, sólo quería tomar el control de las interrupciones para aprender.


Agradezco cualquier sugerencia o pista

[1] https://github.com/cpantel/Pendulometro/tree/feature/asyncAdcRead/edu-ciaa-nxp/freeOSEK/isr
[2] https://github.com/cpantel/firmware_v2/blob/feature/asyncAdcRead/modules/lpc4337_m4/sapi_rtos/src/sapi_adc.c
Reply all
Reply to author
Forward
0 new messages