[NEW] Improved PAL driver with synchronous API

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

[NEW] Improved PAL driver with synchronous API

Post by Giovanni »

Hi,

This is an example of the new PAL driver, note, the same application is implemented using callbacks or the new synchronous API, the new API looks much simpler.

Code: Select all

/*
    ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "ch.h"
#include "hal.h"
#include "portab.h"

/*===========================================================================*/
/* Generic code.                                                             */
/*===========================================================================*/

#if defined(PORTAB_LINE_LED2)
/*
 * LED blinker thread, times are in milliseconds.
 */
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    systime_t time = palReadLine(PORTAB_LINE_BUTTON) == PORTAB_BUTTON_PRESSED ? 250 : 500;
    palToggleLine(PORTAB_LINE_LED2);
    chThdSleepMilliseconds(time);
  }
}
#endif

#if PAL_USE_WAIT || defined(__DOXYGEN__)

/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

#if defined(PORTAB_LINE_LED2)
  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
#endif

  /* Enabling events on both edges of the button line.*/
  palEnableLineEvent(PORTAB_LINE_BUTTON, PAL_EVENT_MODE_BOTH_EDGES);

  /*
   * Normal main() thread activity.
   */
  while (true) {
    /* Waiting for an edge on the button.*/
    palWaitLineTimeout(PORTAB_LINE_BUTTON, TIME_INFINITE);

    /* Action depending on button state.*/
    if (palReadLine(PORTAB_LINE_BUTTON) == PORTAB_BUTTON_PRESSED) {
      palWriteLine(PORTAB_LINE_LED1, PORTAB_LEN_ON);
    }
    else {
      palWriteLine(PORTAB_LINE_LED1, PORTAB_LEN_OFF);
    }
  }
}

#endif /* PAL_USE_WAIT */

#if !PAL_USE_WAIT && PAL_USE_CALLBACKS

static event_source_t button_pressed_event;
static event_source_t button_released_event;

static void button_cb(void *arg) {

  (void)arg;

  chSysLockFromISR();
  if (palReadLine(PORTAB_LINE_BUTTON) == PORTAB_BUTTON_PRESSED) {
    chEvtBroadcastI(&button_pressed_event);
  }
  else {
    chEvtBroadcastI(&button_released_event);
  }
  chSysUnlockFromISR();
}

/*
 * Application entry point.
 */
int main(void) {
  event_listener_t el0, el1;

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /* Events initialization and registration.*/
  chEvtObjectInit(&button_pressed_event);
  chEvtObjectInit(&button_released_event);
  chEvtRegister(&button_pressed_event, &el0, 0);
  chEvtRegister(&button_released_event, &el1, 1);

#if defined(PORTAB_LINE_LED2)
  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
#endif

  /* Enabling events on both edges of the button line.*/
  palEnableLineEvent(PORTAB_LINE_BUTTON, PAL_EVENT_MODE_BOTH_EDGES);
  palSetLineCallback(PORTAB_LINE_BUTTON, button_cb, NULL);

  /*
   * Normal main() thread activity.
   */
  while (true) {
    eventmask_t events;

    events = chEvtWaitOne(EVENT_MASK(0) | EVENT_MASK(1));
    if (events & EVENT_MASK(0)) {
      palWriteLine(PORTAB_LINE_LED1, PORTAB_LEN_ON);
    }
    if (events & EVENT_MASK(1)) {
      palWriteLine(PORTAB_LINE_LED1, PORTAB_LEN_OFF);
    }
  }
}
#endif /* !PAL_USE_WAIT && PAL_USE_CALLBACKS */

#if !PAL_USE_WAIT && !PAL_USE_CALLBACKS
/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

#if defined(PORTAB_LINE_LED2)
  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
#endif

  /*
   * Normal main() thread activity.
   */
  while (true) {
    palToggleLine(PORTAB_LINE_LED1);
    chThdSleepMilliseconds(500);
  }
}
#endif /* !PAL_USE_WAIT && !PAL_USE_CALLBACKS */


The test application is available under /testhal/STM32/multi/PAL

Giovanni
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: [NEW] Improved PAL driver with synchronous API

Post by Giovanni »

More changes, now it is possible to enable/disable the callback and synchronous APIs independently, this way it is possible to save memory disabling what it is not needed.

Giovanni
User avatar
tfAteba
Posts: 551
Joined: Fri Oct 16, 2015 11:03 pm
Has thanked: 91 times
Been thanked: 50 times

Re: [NEW] Improved PAL driver with synchronous API

Post by tfAteba »

Hi Giovanni,

I just want to know, is the synchronous API allow to use External interruptions in the PAL lld ?

What is the advantage to have a synchronous API?

Thanks.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: [NEW] Improved PAL driver with synchronous API

Post by Giovanni »

See the demo, you can make a thread wait for a state transition without having to define callbacks.

Giovanni
User avatar
tfAteba
Posts: 551
Joined: Fri Oct 16, 2015 11:03 pm
Has thanked: 91 times
Been thanked: 50 times

Re: [NEW] Improved PAL driver with synchronous API

Post by tfAteba »

Hi,

Yes, by reading the demo, it is clear now.

Now I have to implement this feature and make some test :)

Thanks.
omcdr
Posts: 89
Joined: Wed Aug 17, 2016 3:25 pm
Has thanked: 7 times
Been thanked: 7 times

Re: [NEW] Improved PAL driver with synchronous API

Post by omcdr »

When this new PAL driver will be added in stable branch ? I see it only in trunk.
It is safe to use ?
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: [NEW] Improved PAL driver with synchronous API

Post by Giovanni »

Hi,

It will be included in next major release, probably 18.1.

It is safe to use knowing that it could change, usually I commit usable code, if not then I put a warning in this forum (note there is a warning right now, trunk is in the middle of something).

Giovanni
Xela
Posts: 15
Joined: Thu Sep 07, 2017 12:05 pm
Has thanked: 3 times

Re: [NEW] Improved PAL driver with synchronous API

Post by Xela »

I have been following some example to write an interrupt handler, but failed to compile with the following:
./os/hal/ports/STM32/LLD/EXTIv1/hal_ext_lld.h:30:29: fatal error: hal_ext_lld_isr.h: No such file or directory
That has led me to this forum thread.

Are the 'events' referred to in this demo meant to replace the EXTI subsystem?
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: [NEW] Improved PAL driver with synchronous API

Post by Giovanni »

Hi,

Correct, the EXT driver has been obsoleted, PAL replaces it (it uses EXTI internally).

Giovanni
Xela
Posts: 15
Joined: Thu Sep 07, 2017 12:05 pm
Has thanked: 3 times

Re: [NEW] Improved PAL driver with synchronous API

Post by Xela »

If I understand the example code, it is demonstrating the use of events. In the first example application it demonstrates polling for an event.
The second application demonstrates issuing an event in a callback that is triggered by an interrupt (the main while loop also listens for the event).

It is all a bit overkill for an interrupt example as I am getting a bit confused between the event listening and interrupt handling. Well I think I understand it but I don't follow how in the example event listeners are instantiated, registered, and never referenced again (I don't see the purpose of el0,el1).

Code: Select all

event_listener_t el0, el1;
chEvtRegister(&button_pressed_event, &el0, 0);
chEvtRegister(&button_released_event, &el1, 1);


However, that is very much an aside as at this point I am only interested in the latest convention for setting up an ISR as EXT is depreciated.

If rip eveything out that is related to event signalling, all I am left with is the following:

Code: Select all

palEnableLineEvent(PORTAB_LINE_BUTTON, PAL_EVENT_MODE_BOTH_EDGES);
palSetLineCallback(PORTAB_LINE_BUTTON, button_cb, NULL);
 



Following this I have the bare minimum for and ISR:
(heartbeat green output and if the interrupt pin is reset once the red light comes on permanently)

Code: Select all

static void ledtest_cb(void *arg) {
  (void)arg;
  XAL_LED_on(&LED_RED);
}


int main(void) {

  halInit();
  chSysInit();

  palEnableLineEvent(GPIOC_TEST_INT, PAL_EVENT_MODE_FALLING_EDGE);
  palSetLineCallback(GPIOC_TEST_INT, ledtest_cb, NULL);

  while (true) {
    XAL_LED_on(&LED_GREEN);
    XOS_SleepMs(30);
    XAL_LED_off(&LED_GREEN);
    XOS_SleepMs(940);
  }
}


It is a Monday so of course this doesn't actually work. So either I don't understand the minimum requirements for an ISR or I have my pin GPIOC_TEST_INT configured incorrectly.


Also, is the following guide still the preferred way to write an ISR?:
http://www.chibios.org/dokuwiki/doku.ph ... interrupts

It is what I have been following but haven't been able to figure out how to trigger the myIRQ handle yet.
Post Reply