<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <div class="moz-cite-prefix">On 10/31/2014 11:05 AM, Alan Cudmore
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAJrjN72z6xPQ5Duxg99XoCu292AfZrOseYDb0ATeZN0tjuq6+w@mail.gmail.com"
      type="cite">
      <div dir="ltr">I'm going to try to look at the Pi BSP warnings
        soon. I can try to help address some of the issues with this
        patch as well.
        <div><br>
        </div>
      </div>
    </blockquote>
    Once you figure the warning out, I hope it is easy to fix the other
    <br>
    two BSPs with the same issue. :)<br>
    <blockquote
cite="mid:CAJrjN72z6xPQ5Duxg99XoCu292AfZrOseYDb0ATeZN0tjuq6+w@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>What is the desired cut off date for 4.11? </div>
        <div><br>
        </div>
      </div>
    </blockquote>
    Last year. :)<br>
    <br>
    Chris was joking that we measure releases based on the number of<br>
    developers who have children during the gap. If I am counting right,
    <br>
    there are 4 children and a grandchild. <br>
    <br>
    Seriously, just as soon as it is ready. Settling the tools, the
    dynamic<br>
    loader, and getting the Beagle merged are also on the list.<br>
    <br>
    --joel<br>
    <blockquote
cite="mid:CAJrjN72z6xPQ5Duxg99XoCu292AfZrOseYDb0ATeZN0tjuq6+w@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>Alan</div>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">On Fri, Oct 31, 2014 at 11:41 AM,
            Pavel Pisa <span dir="ltr"><<a moz-do-not-send="true"
                href="mailto:ppisa4lists@pikron.com" target="_blank">ppisa4lists@pikron.com</a>></span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello
              Andre,<br>
              <div>
                <div class="h5"><br>
                  On Friday 31 of October 2014 12:56:40 Andre Marques
                  wrote:<br>
                  <br>
                  > +/**<br>
                  > + * @brief Generic ISR that clears the event
                  register on the Raspberry Pi<br>
                  > and calls + *        an user defined ISR.<br>
                  > + *<br>
                  > + * @param[in] arg Void pointer to a
                  handler_arguments structure.<br>
                  > + */<br>
                  > +static void generic_handler(void* arg)<br>
                  > +{<br>
                  > +  handler_arguments* handler_args;<br>
                  > +  int rv = 0;<br>
                  > +  int pin = 0;<br>
                  > +<br>
                  > +  handler_args = (handler_arguments*) arg;<br>
                  > +<br>
                  > +  pin = handler_args->pin_number;<br>
                  > +<br>
                  > +  /*  If the interrupt was generated by the pin
                  attached to this ISR<br>
                  > clears it. */ +  if (
                  BCM2835_REG(BCM2835_GPIO_GPEDS0) & (1 <<
                  pin) )<br>
                  > +    BCM2835_REG(BCM2835_GPIO_GPEDS0) &= (1
                  << pin);<br>
                  > +<br>
                  > +  /* If not lets the next ISR process the
                  interrupt. */<br>
                  > +  else<br>
                  > +    return;<br>
                  > +<br>
                  > +  /* If this pin has the deboucing function
                  attached, call it. */<br>
                  > +  if ( handler_args->debouncing_tick_count
                  > 0 ) {<br>
                  > +    rv = debounce_switch(pin);<br>
                  > +<br>
                  > +    if ( rv < 0 )<br>
                  > +      return;<br>
                  > +  }<br>
                  > +<br>
                  > +  /* Call the user's ISR. */<br>
                </div>
              </div>
              > +  (handler_args->handler)
              (handler_args->handler_arg);<br>
              > +}<br>
              <br>
              There has to be mechanism (array of pointers) for
              registering args<br>
              for each pin handler routine.<br>
              <span class=""><br>
                > +/**<br>
                > + * @brief Enables interrupts to be generated on a
                given GPIO pin.<br>
                > + *        When fired that interrupt will call the
                given handler.<br>
                > + *<br>
                > + * @param[in] dev_pin Raspberry Pi GPIO pin label
                number (not its position<br>
                > + *            on the header).<br>
                > + * @param[in] interrupt Type of interrupt to
                enable for the pin.<br>
                > + * @param[in] handler Pointer to a function that
                will be called every time<br>
                > + *                    @var interrupt is generated.
                This function must have<br>
                > + *                    no receiving parameters and
                return void.<br>
              </span>      @param[in] arg or context<br>
              <span class=""><br>
                > + *<br>
                > + * @retval 0 Interrupt successfully enabled for
                this pin.<br>
                > + * @retval -1 Could not replace the currently
                active interrupt on this<br>
                > pin, or + *            unknown @var interrupt.<br>
                > + */<br>
                > +int gpio_enable_interrupt(int dev_pin,
                gpio_interrupt interrupt, void<br>
                > (*handler)(void)) +{<br>
                <br>
                <br>
              </span><span class="">int gpio_enable_interrupt(int
                dev_pin, gpio_interrupt interrupt, void<br>
              </span>   (*handler)(void *arg), void *arg)<br>
              <br>
              It would worth to be able to register mutiple handlers for
              single<br>
              pin for case o emulating shared IRQ line - i.e. ISA bus,
              then information<br>
              about IRQ handled/unhandled state has to be returned by
              handler - but that<br>
              is not critical. Argument is critical as I have already
              stated.<br>
              <br>
              The handler function prototype should be same as for RTEMS
              ISR registration<br>
              <br>
              typedef void (*rtems_interrupt_handler)(void *);<br>
              <br>
              This allows to use drivers for some generic chips to be
              connected<br>
              to some external bus same way on different CPU and boards
              architectures<br>
              with same ISR handler when directly connected to some
              external interrupt<br>
              input and use same driver+handler when interrupt is
              connected<br>
              to GPIO ISR multiplexor.<br>
              <br>
              I have already raised this concern for previous patch
              version<br>
              - see mail thread<br>
              <br>
              <a moz-do-not-send="true"
                href="http://article.gmane.org/gmane.os.rtems.user/13211"
                target="_blank">http://article.gmane.org/gmane.os.rtems.user/13211</a><br>
              <span class=""><br>
                > +  rtems_status_code sc;<br>
                > +  rpi_gpio_pin *pin;<br>
                > +<br>
                > +  /* Only consider GPIO pins up to 31. */<br>
                > +  if ( dev_pin > 31 )<br>
                > +    return -1;<br>
                > +<br>
                > +  pin = &gpio_pin[dev_pin-1];<br>
                > +<br>
                > +  /* If the pin already has an enabled interrupt
                removes it first,<br>
                > +   * as well as its handler. */<br>
                > +  if ( pin->enabled_interrupt != NONE ) {<br>
                > +    sc = gpio_disable_interrupt(dev_pin);<br>
                > +<br>
                > +    if ( sc != RTEMS_SUCCESSFUL )<br>
                > +      return -1;<br>
                > +  }<br>
                > +<br>
                > +  pin->h_args.pin_number = dev_pin;<br>
                > +  pin->h_args.handler = handler;<br>
                <br>
              </span>  +  pin->h_args.handler_arg = arg;<br>
              <span class=""><br>
                <br>
                > +<br>
                > +  pin->h_args.last_isr_tick =
                rtems_clock_get_ticks_since_boot();<br>
                > +<br>
                > +  /* Installs the generic_handler, which will call
                the user handler<br>
                > received +   * a parameter. */<br>
                > +  sc =
                rtems_interrupt_handler_install(BCM2835_IRQ_ID_GPIO_0,<br>
                > +                                       NULL,<br>
                > +                                     
                 RTEMS_INTERRUPT_SHARED,<br>
                > +                                     
                 (rtems_interrupt_handler)<br>
                > generic_handler, +                                 
                     &(pin->h_args));<br>
                <br>
              </span>The use of RTEMS_INTERRUPT_SHARED and registering
              multiple handlers<br>
              for single pin group is significant overhead. It would be
              much faster<br>
              to register only one handler (when gpio_enable_interrupt
              is called first time).<br>
              Then read interrupt status register (if before HW masking,
              apply mask)<br>
              and use ffs (find first bit set) in loop to process all
              pending events.<br>
              Each time ffs gives the bit, clear the bit in the local
              copy,<br>
              retrieve pin description from the array (ffs gives the
              index)<br>
              and process user provided handler with corresponding user
              argument.<br>
              <div>
                <div class="h5"><br>
                  > +  if ( sc != RTEMS_SUCCESSFUL )<br>
                  > +    return -1;<br>
                  > +<br>
                  > +  switch ( interrupt ) {<br>
                  > +    case FALLING_EDGE:<br>
                  > +<br>
                  > +      /* Enables asynchronous falling edge
                  detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPAFEN0) |= (1
                  << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case RISING_EDGE:<br>
                  > +<br>
                  > +      /* Enables asynchronous rising edge
                  detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPAREN0) |= (1
                  << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case BOTH_EDGES:<br>
                  > +<br>
                  > +      /* Enables asynchronous falling edge
                  detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPAFEN0) |= (1
                  << dev_pin);<br>
                  > +<br>
                  > +      /* Enables asynchronous rising edge
                  detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPAREN0) |= (1
                  << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case LOW_LEVEL:<br>
                  > +<br>
                  > +      /* Enables pin low level detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPLEN0) |= (1
                  << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case HIGH_LEVEL:<br>
                  > +<br>
                  > +      /* Enables pin high level detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPHEN0) |= (1
                  << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case BOTH_LEVELS:<br>
                  > +<br>
                  > +      /* Enables pin low level detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPLEN0) |= (1
                  << dev_pin);<br>
                  > +<br>
                  > +      /* Enables pin high level detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPHEN0) |= (1
                  << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case NONE:<br>
                  > +      return 0;<br>
                  > +<br>
                  > +    default:<br>
                  > +      return -1;<br>
                  > +  }<br>
                  > +<br>
                  > +  pin->enabled_interrupt = interrupt;<br>
                  > +<br>
                  > +  return 0;<br>
                  > +}<br>
                  <br>
                </div>
              </div>
              The whole function and many others require to define some
              locking<br>
              to can be used from paralley running threads.<br>
              <br>
              There should be functions which do plain enable and
              disable of IRQ<br>
              generation and then functions to register and unregister
              handler for pin.<br>
              Register can/should probably call enable at the end to be
              consistent with<br>
              rtems_interrupt_handler_install(). The enable and disable
              functions<br>
              should and in case of RPi can be written (separates
              set/reset registers and<br>
              single CPU core so CPU level IRQ disable is cheap) such
              way that<br>
              they can be called from ISR context (no mutex locking). On
              the other hand<br>
              <br>
              gpio_enable_interrupt/gpio_interrupt_handler_install has
              quite little<br>
              other options than to use mutex. Use of CPU level IRQ
              disable<br>
              is not good for latencies.<br>
              <br>
              There are probably some compiler (SMP for case of multiple
              cores)<br>
              barriers to ensure that structure is updated before enable<br>
              of IRQ in hardware.<br>
              <div>
                <div class="h5"><br>
                  > +/**<br>
                  > + * @brief Stops interrupts from being generated
                  from a given GPIO pin<br>
                  > + *        and removes the corresponding handler.<br>
                  > + *<br>
                  > + * @param[in] dev_pin Raspberry Pi GPIO pin
                  label number (not its position<br>
                  > + *            on the header).<br>
                  > + *<br>
                  > + * @retval 0 Interrupt successfully disabled for
                  this pin.<br>
                  > + * @retval -1 Could not remove the current
                  interrupt handler or could not<br>
                  > + *            recognise the current active
                  interrupt on this pin.<br>
                  > + */<br>
                  > +int gpio_disable_interrupt(int dev_pin)<br>
                  > +{<br>
                  > +  rtems_status_code sc;<br>
                  > +  rpi_gpio_pin *pin;<br>
                  > +<br>
                  > +  pin = &gpio_pin[dev_pin-1];<br>
                  > +<br>
                  > +  switch ( pin->enabled_interrupt ) {<br>
                  > +    case FALLING_EDGE:<br>
                  > +<br>
                  > +      /* Disables asynchronous falling edge
                  detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPAFEN0) &=
                  ~(1 << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case RISING_EDGE:<br>
                  > +<br>
                  > +      /* Disables asynchronous rising edge
                  detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPAREN0) &=
                  ~(1 << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case BOTH_EDGES:<br>
                  > +<br>
                  > +      /* Disables asynchronous falling edge
                  detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPAFEN0) &=
                  ~(1 << dev_pin);<br>
                  > +<br>
                  > +      /* Disables asynchronous rising edge
                  detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPAREN0) &=
                  ~(1 << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case LOW_LEVEL:<br>
                  > +<br>
                  > +      /* Disables pin low level detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPLEN0) &=
                  ~(1 << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case HIGH_LEVEL:<br>
                  > +<br>
                  > +      /* Disables pin high level detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPHEN0) &=
                  ~(1 << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case BOTH_LEVELS:<br>
                  > +<br>
                  > +      /* Disables pin low level detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPLEN0) &=
                  ~(1 << dev_pin);<br>
                  > +<br>
                  > +      /* Disables pin high level detection. */<br>
                  > +      BCM2835_REG(BCM2835_GPIO_GPHEN0) &=
                  ~(1 << dev_pin);<br>
                  > +<br>
                  > +      break;<br>
                  > +<br>
                  > +    case NONE:<br>
                  > +      return 0;<br>
                  > +<br>
                  > +    default:<br>
                  > +      return -1;<br>
                  > +  }<br>
                  > +<br>
                  > +  /* Removes the handler. */<br>
                  > +  sc =
                  rtems_interrupt_handler_remove(BCM2835_IRQ_ID_GPIO_0,<br>
                  > +                                     
                  (rtems_interrupt_handler)<br>
                  > generic_handler, +                               
                        &(pin->h_args));<br>
                  > +<br>
                  > +  if ( sc != RTEMS_SUCCESSFUL )<br>
                  > +    return -1;<br>
                  > +<br>
                  > +  pin->enabled_interrupt = NONE;<br>
                  > +<br>
                  > +  return 0;<br>
                  > +}<br>
                  <br>
                  <br>
                </div>
              </div>
              You can look how interrupts are used in real-time RPi demo
              application<br>
              to control DC motor with incremental encoder signals
              detections by software.<br>
              We have succeed to process 25000 interrupts/second with
              fully preemptive<br>
              Linux kernel where actual IRQ handlers are run in kernel
              threads/this means<br>
              than each ISR results in kernel context switch.<br>
              <br>
              <a moz-do-not-send="true"
                href="http://lintarget.sourceforge.net/rpi-motor-control/index.html"
                target="_blank">http://lintarget.sourceforge.net/rpi-motor-control/index.html</a><br>
              <br>
              <a moz-do-not-send="true"
href="https://github.com/ppisa/rpi-rt-control/blob/master/kernel/modules/rpi_gpio_irc_module.c"
                target="_blank">https://github.com/ppisa/rpi-rt-control/blob/master/kernel/modules/rpi_gpio_irc_module.c</a><br>
              <br>
              RTEMS should be in much better situation there because its
              context switch<br>
              is much lighter - no MMU consideration etc. So same task
              should<br>
              be portable for RTEMS easily. Even quadrature decoding can
              be done in<br>
              single handler for both pins because there is no latency
              between<br>
              HW ISR and its handler running in the kernel thread. So
              simple<br>
              state decoding could be used by reading values from GPIO
              input register.<br>
              <br>
              Please, try to make API and functions robust and
              (re)usable.<br>
              If you have problem to see all consequences then I can
              help with<br>
              some advises or if others agree I would prepare some
              follow up<br>
              patches to clean the code as my time allows ....<br>
              I have not so big problem with time to rewrite code but
              time<br>
              for testing is much bigger problem.<br>
              <br>
              Best wishes,<br>
              <br>
                              Pavel<br>
              <div class="HOEnZb">
                <div class="h5"><br>
                  <br>
                  <br>
                  <br>
                  _______________________________________________<br>
                  devel mailing list<br>
                  <a moz-do-not-send="true"
                    href="mailto:devel@rtems.org">devel@rtems.org</a><br>
                  <a moz-do-not-send="true"
                    href="http://lists.rtems.org/mailman/listinfo/devel"
                    target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
                </div>
              </div>
            </blockquote>
          </div>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
    <pre class="moz-signature" cols="72">-- 
Joel Sherrill, Ph.D.             Director of Research & Development
<a class="moz-txt-link-abbreviated" href="mailto:joel.sherrill@OARcorp.com">joel.sherrill@OARcorp.com</a>        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
Support Available                (256) 722-9985</pre>
  </body>
</html>