[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.
User avatar
Giovanni
Site Admin
Posts: 11148
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 391 times
Been thanked: 321 times
Contact:

[NEW] Improved PAL driver with synchronous API

Postby Giovanni » Sat Sep 02, 2017 1:43 pm

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: 11148
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 391 times
Been thanked: 321 times
Contact:

Re: [NEW] Improved PAL driver with synchronous API

Postby Giovanni » Sun Sep 03, 2017 4:53 pm

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: 511
Joined: Fri Oct 16, 2015 11:03 pm
Location: Chartres, France
Has thanked: 75 times
Been thanked: 44 times

Re: [NEW] Improved PAL driver with synchronous API

Postby tfAteba » Sun Sep 03, 2017 8:03 pm

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.
regards,

Theo.

User avatar
Giovanni
Site Admin
Posts: 11148
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 391 times
Been thanked: 321 times
Contact:

Re: [NEW] Improved PAL driver with synchronous API

Postby Giovanni » Sun Sep 03, 2017 8:09 pm

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

Giovanni

User avatar
tfAteba
Posts: 511
Joined: Fri Oct 16, 2015 11:03 pm
Location: Chartres, France
Has thanked: 75 times
Been thanked: 44 times

Re: [NEW] Improved PAL driver with synchronous API

Postby tfAteba » Sat Sep 09, 2017 5:09 pm

Hi,

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

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

Thanks.
regards,

Theo.

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

Re: [NEW] Improved PAL driver with synchronous API

Postby omcdr » Fri Dec 01, 2017 4:26 pm

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: 11148
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 391 times
Been thanked: 321 times
Contact:

Re: [NEW] Improved PAL driver with synchronous API

Postby Giovanni » Fri Dec 01, 2017 6:30 pm

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

Postby Xela » Mon Apr 16, 2018 2:17 pm

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: 11148
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 391 times
Been thanked: 321 times
Contact:

Re: [NEW] Improved PAL driver with synchronous API

Postby Giovanni » Mon Apr 16, 2018 2:23 pm

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

Postby Xela » Mon Apr 16, 2018 5:37 pm

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.


Return to “Development and Feedback”

Who is online

Users browsing this forum: No registered users and 3 guests