Solved RP continuous GPIO pin reading (polling)

nactusberrilli

Member

Reaction score: 15
Messages: 70

I'm writing a little lib (wrapper) in NodeJS using basic gpioctl commands for the RP. Something like this:
JavaScript:
...
module.exports.toggle_led = function (pin_number, callback) {
    let err = new Error();
    if (typeof (pin_number) != "number") {
        err.name = errlist.ERR818.name;
        err.message = errlist.ERR818.message;
        callback(err, feedback);
    }
    else {
        shell_cmd(`gpioctl -t ${pin_number}`, `utf8`, (error, stdout, stderr) => {
            if (error != null) {
                err.name = error.code;
                err.message = error.signal;
                callback(err, feedback);
            }
        });
    }
}
NodeJS spawns a new process and pipes the command gpioctl -<flag> -<pin_num> to the OS. This works O.K. for setting pins/toggling pins.
Now, I'd like a way to constantly monitor the input from a specific pin, such that (say) when I push a button (or when a digital peripheral - sensor) outputs a new/changed value (0/1) I can capture that data.

I think I can write an EventListener that would interface with a shell (or a running CLI program) and listen for those values, however, I can't seem to find a way to constantly monitor a given "OUT" pin by using any of the gpio commands.
 
Last edited:

Phishfry

Son of Beastie

Reaction score: 1,339
Messages: 3,977

OP
OP
nactusberrilli

nactusberrilli

Member

Reaction score: 15
Messages: 70

Thanks for pointing me in the right direction. It seems sysctl could help me here, however I don't think I understand how you set up your temp. sensor to be:
dev.ow_temp.0.temperature
How did you associate GPIO pin <x> (supossily the pin where your sensor was connected) to be dev.ow_temp.0.temperature? Is dev.ow_temp.0.temperature pseudocode?

I used sysctl dev.gpio and I found a large list, specifically the:
Code:
dev.gpio.0.pin.53.function: alt3
dev.gpio.0.pin.52.function: alt3
dev.gpio.0.pin.51.function: alt3
dev.gpio.0.pin.50.function: alt3
dev.gpio.0.pin.49.function: alt3
dev.gpio.0.pin.48.function: alt3
dev.gpio.0.pin.47.function: input
dev.gpio.0.pin.46.function: input
dev.gpio.0.pin.45.function: alt0
dev.gpio.0.pin.44.function: input
dev.gpio.0.pin.43.function: input
dev.gpio.0.pin.42.function: input
dev.gpio.0.pin.41.function: input
dev.gpio.0.pin.40.function: alt0
dev.gpio.0.pin.39.function: input
dev.gpio.0.pin.38.function: input
dev.gpio.0.pin.37.function: input
dev.gpio.0.pin.36.function: input
dev.gpio.0.pin.35.function: input
dev.gpio.0.pin.34.function: input
dev.gpio.0.pin.33.function: input
dev.gpio.0.pin.32.function: input
dev.gpio.0.pin.31.function: input
dev.gpio.0.pin.30.function: input
dev.gpio.0.pin.29.function: input
dev.gpio.0.pin.28.function: input
dev.gpio.0.pin.27.function: input
dev.gpio.0.pin.26.function: input
dev.gpio.0.pin.25.function: input
dev.gpio.0.pin.24.function: input
dev.gpio.0.pin.23.function: input
dev.gpio.0.pin.22.function: input
dev.gpio.0.pin.21.function: output
dev.gpio.0.pin.20.function: input
dev.gpio.0.pin.19.function: input
dev.gpio.0.pin.18.function: input
dev.gpio.0.pin.17.function: input
dev.gpio.0.pin.16.function: output
dev.gpio.0.pin.15.function: alt0
dev.gpio.0.pin.14.function: alt0
dev.gpio.0.pin.13.function: input
dev.gpio.0.pin.12.function: input
dev.gpio.0.pin.11.function: input
dev.gpio.0.pin.10.function: input
dev.gpio.0.pin.9.function: input
dev.gpio.0.pin.8.function: input
dev.gpio.0.pin.7.function: input
dev.gpio.0.pin.6.function: output
dev.gpio.0.pin.5.function: output
dev.gpio.0.pin.4.function: input
dev.gpio.0.pin.3.function: input
dev.gpio.0.pin.2.function: input
dev.gpio.0.pin.1.function: alt0
dev.gpio.0.pin.0.function: alt0
It looks like those are all the GPIO pins available on the RP. From here it would only be a matter of "listening" on a specific pin for a change in "value", right?
 
Last edited:

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

Dear nactusberrilli , i am not an EE, but polling a digital pin is the thing you do not want to do in an Operating System. That is ok for Arduino because it polls and does nothing else.

I recommend you to give a look to Derek Molly books. They are really great to get the grip on these things.

I see you want to use Node. Fantastic ! Great approach !
The BeagleBone + Linux comes with BoneScript. Take a look, that may be the path of maximum satisfaction for you.
 
OP
OP
nactusberrilli

nactusberrilli

Member

Reaction score: 15
Messages: 70

polling a digital pin is the thing you do not want to do in an Operating System
Why not? What do you suggest I do instead? I'm open to suggestions.
That is ok for Arduino because it polls and does nothing else
I'm not sure what you mean by "nothing-else".
The BeagleBone + Linux comes with BoneScript
Are you suggesting I switch the SoC & the OS? (from RP to BeagleBone & from FreeBSD to Linux?)
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

ok nactusberrilli , i will tell you all i can remember ;)

I was deeply messing with BBBlack and Linux Debian last Fall, then i switched to FreeBSD. Since I am not an EE but i wanted to know what i was doing i studied
Derek Molly "Exploring Beagle Bone" (there is the same book for RP) for quite a long time.

Polling is not good because your OS does a lot of things. If just in the moment you will press the button (gpio input ON) the system is loaded by other processes there is a good chance you will loose the button signal. There are two at least 2 ways to fix this:
1] interrupts
2] in the BB there are the PRUS, two separate processors you can use like 2 Arduino, to loop forever at maximum speed doing easy things. (32KB mem available AFAIR)

"Nothing else" means that an Arduino program is a while loop. It does only what you say. A while loop you run in FreeBSD run concurrently with a lot of other processes, you can never be sure 100% that your button will be polled say every 1ms (random unit here).

Third question. If you intend to write your application in Javascript I racomend you to switch to BeagleBone and Linux. In that configuration BoneScript is well working, ready to deploy. There are books already written, all ready for you to start coding.

If you want to stick for FreeBSD there is an option that can save you a lot of time. I considered it as well. Offload all electronics control to an Arduino and let Arduino and FreeBSD comunicate via serial. FB is the brain, maybe network connected, maybe sshd, maybe with a firewall ... ARD is the arm, doing silly things that must be done fast and for sure in a fixed time unit.

If i remember well this is the same approach was followed in a BSDCan presentation where they had problems with PWM in FreeBSD so they used Arduino to offload that task.

I hope to have been of some help :)

bye
n.
 

Phishfry

Son of Beastie

Reaction score: 1,339
Messages: 3,977

I understand how you set up your temp. sensor to be:
I am using the onewire(4) driver.
It has to have a DTB entry to work. In it you define the pins you want. Like a mux.
Here is the RPi3 instructions. A couple of ways.
https://forums.freebsd.org/threads/onewire-on-raspberrypi3.64033/

The RPI3 had issues with onewire driver. I never got it going.
These same type instructions do work on Pi2 rev1.1 and BBB.
Either compile-in support for onewire or decompile and recompile the DTB.
It's not pretty but works.
 
OP
OP
nactusberrilli

nactusberrilli

Member

Reaction score: 15
Messages: 70

Polling is not good because your OS does a lot of things. If just in the moment you will press the button (gpio input ON) the system is loaded by other processes there is a good chance you will loose the button signal. There are two at least 2 ways to fix this:
1] interrupts
2] in the BB there are the PRUS, two separate processors you can use like 2 Arduino, to loop forever at maximum speed doing easy things. (32KB mem available AFAIR)
I think I understand what you're saying now. You are referring to the difference between a monolithic kernel OS(such as the BSD kernel) and an RTOS - where the kernel guarantees the execution of a task in a specific time-constraint. However, please keep in mind that the BSD kernel allows for soft-realtime support --> this means that the kernel can be optimized by prioritizing certain processes, but yes, there is no guarantee that an application's "dead-lines" are met.

  • Hard – missing a deadline is a total system failure.
  • Firm – infrequent deadline misses are tolerable, but may degrade the system's quality of service. The usefulness of a result is zero after its deadline.
  • Soft – the usefulness of a result degrades after its deadline, thereby degrading the system's quality of service.
(source)

If you want to stick for FreeBSD there is an option that can save you a lot of time. I considered it as well. Offload all electronics control to an Arduino and let Arduino and FreeBSD comunicate via serial. FB is the brain, maybe network connected, maybe sshd, maybe with a firewall ... ARD is the arm, doing silly things that must be done fast and for sure in a fixed time unit.
I like your idea. Using an MCU for the real-time parts of the application and interfacing that MCU with a CPU. I can see this as a possible solution in a custom PCB where I could couple an ARM and an AVR or MSP430 (both very cheap). In that case, the question would be: if I pair an ARM CPU with a micro-controller and run (say) FreeBSD on the ARM, wouldn't the serial communication between those two fall under the same "soft-real-time" constraints? In other words, the serial communication (be it I2C, UART) would still happen without the "guarantee" of real-time execution (as far as FreeBSD is concerned). Right?

I am using the onewire(4) driver.
So, say I didn't use this driver, what if instead I would use the sysctl dev.gpio.0.pin.<x> Would querying that pin directly work?
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

In that case, the question would be: if I pair an ARM CPU with a micro-controller and run (say) FreeBSD on the ARM, wouldn't the serial communication between those two fall under the same "soft-real-time" constraints? In other words, the serial communication (be it I2C, UART) would still happen without the "guarantee" of real-time execution (as far as FreeBSD is concerned). Right?
Ok, the point you rise is correct !
To make things more concrete i will give you two examples.

[case 1] You want to implement a system doing this. "when somebody crosses a laser beam a picture is taken to see who was him". Let's suppose all your control electronics is two digital wires. INPUT is ON if for at least 1ms (unit invented) if somebody crosses the laserbeam, OUTPUT will be ON for at least 1ms if I want to take the picture.

In this case the secure way would be to let Arduino (or similar) control INPUT and OUTPUT. The reason is you whant instantaneously take a picture when the laser beam is crossed, you can not wait a little bit.

[case 2] You want to be mailed when somebody crosses a laser beam. Now INPUT again will be under control of Arduino, it will never miss a crossing. Then Arduiono, when it detects a crossing, it sends a the text line "CROSSED" over the serial line to FreeBSD. Now, this serial signal will never be lost because serial has its buffers. FreeBSD will see it, maybe with a delay if the system is under load, but it does not matter if your mail is sent 500ms after the laser beam is crossed.

You can do the same with PRUS in BeagleBone, so bypassing Arduino and the serial line. But, i tried only once and in Linux, it is considerably more difficult.
 
OP
OP
nactusberrilli

nactusberrilli

Member

Reaction score: 15
Messages: 70

Between the two different suggested appoaches, I think I have enough information to start experimenting using the poll and the MCU method. I will mark this thread as solved and start a new one describing my adventures & detailing my progress. Thank you much for your help.
 
OP
OP
nactusberrilli

nactusberrilli

Member

Reaction score: 15
Messages: 70

You can do the same with PRUS in BeagleBone, so bypassing Arduino and the serial line. But, i tried only once and in Linux, it is considerably more difficult.
I looked a bit into PRU. From what I can tell it's basically an MCU (RISC architecture) that does just that: handles the RT segment of an application.

Now, about BBB & Linux (and of course, this is my personal opinion) the board is a bit overpriced (all specs considered). I know TI is slightly more expensive than the competitors. They justify their prices based of their good designs (in most cases) and good reputation. Let's say I want to make an IoT application (with a web GUI) and a solid network-stack... firstly I'm pretty sure I would not go for Linux - mainly because of their ridiculous GPL2 licensing (but not only). While I'm not too bothered by having to release my customized .IMG of the OS with all the kernel modifications, DTS, drives etc. for anyone to look at, I'm not sure I would feel the same way about the core (network part of my software) of that peripheral. Another disadvantage I have noticed is that learning how to customize the chosen Linux distro used for that embedded device would take as long (if not longer) to set up and customize as it would take if I used FreeBSD (or any other BSD OS variation). So I figured, that if I'm going to put in the time to learn how to customize an OS to fit my needs, it might as well be FreeBSD. Does it make sense?
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

I looked a bit into PRU. From what I can tell it's basically an MCU (RISC architecture) that does just that: handles the RT segment of an application.

Now, about BBB & Linux (and of course, this is my personal opinion) the board is a bit overpriced (all specs considered). I know TI is slightly more expensive than the competitors. They justify their prices based of their good designs (in most cases) and good reputation. Let's say I want to make an IoT application (with a web GUI) and a solid network-stack... firstly I'm pretty sure I would not go for Linux - mainly because of their ridiculous GPL2 licensing (but not only). While I'm not too bothered by having to release my customized .IMG of the OS with all the kernel modifications, DTS, drives etc. for anyone to look at, I'm not sure I would feel the same way about the core (network part of my software) of that peripheral. Another disadvantage I have noticed is that learning how to customize the chosen Linux distro used for that embedded device would take as long (if not longer) to set up and customize as it would take if I used FreeBSD (or any other BSD OS variation). So I figured, that if I'm going to put in the time to learn how to customize an OS to fit my needs, it might as well be FreeBSD. Does it make sense?
ok, my considerations are the following

[about BBB]. My first experiments were with RPI (linux debian). I switched to the BBB because of these facts.
+1] BBB has 4GB internal memory, you don't need an SD card.
+2] BBB has PWM units (PWM is another thing you should not do with a for loop in user space, same argument as polling, it eats a lot resources and performs suboptimally)
+3] BBB has A/D converters (really i don't remember if RPI has)
+4] BBB has PRUS, now you know what they are;)
-1] BBB has not a x264 converter (name can be approximate) that RPI has, so it is reccomended you use RPI you intend to stream videos
-2] BBB costs about ~15$ more than RPI
=> BBB is more suited to experiments in electronics and automation.
There is also BBBlue which has other goodies as circuitry to control motors (check doc for details i don't remember well)

[about Linux]. For the electronics part Linux is one step forward respect to FreeBSD. Many things are working and more or less (ehm, double cough) documented. Consider with Bonescript you can control everything: GPIO, interrupts, I2C, serial, PWM, A/D converters. Only PRUS is out of reach. There are books.
On the other side, we all know, Linux is a mess. Out of electronics FreeBSD, is far better in order, documentation and stability.

[customization] Umm, what you say makes sense but, the order of diffculty of customizations you will need to do on FreeBSD is much higher that what you will need to do on Linux. Because in FreeBSD you will need to know how to make the hardware work (hard), in Linux you can control hardware with Javascript (very easy) and you would need to discover only how to replace /etc/rc.conf or how to cope with systemd (probably not even necessary).

[conclusion] Stick to FreeBSD if you heart tells you so:)
But if the electronics part becomes not trivial my reccomendation is to go for the Arduino (or other MCU) to help FreeBSD. It will be all more easy. You will finish you project in reasonable time and have more fun IMO.

Let us know how it goes !
 

Phishfry

Son of Beastie

Reaction score: 1,339
Messages: 3,977

Don't forget the BBB has about 4 times as many GPIO pins too.
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

Yes, Phishfry is right ;) I will add a picture comparing visually the 3 animals we were talking about recently. (the grey broken box is my 3d print ;)
 

Attachments

Phishfry

Son of Beastie

Reaction score: 1,339
Messages: 3,977

On BBB, everything Ti had was ported so we have good support on BBB.
There is stuff so deep I didn't get to use it all but

Using the PRUSS for button polling seems excessive.
I think the suggestion to use PWM on the PRUSS sounds more apt.

Take a look at this directory for all the goodies available.
/usr/src/sys/arm/ti/am335x/
For example: am335x_dmtpps.c
* AM335x PPS driver using DMTimer capture.
*
* Note that this PPS driver does not use an interrupt. Instead it uses the
* hardware's ability to latch the timer's count register in response to a
* signal on an IO pin. Each of timers 4-7 have an associated pin, and this
* code allows any one of those to be used.
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

This topic is closed, i keep on the discussion only becauase the title is good,
and maybe some newcomer will read this in the future.

On BBB, everything Ti had was ported so we have good support on BBB.
There is stuff so deep I didn't get to use it all but
I agree, but Phishfry do you agree it is not at all easy to get the things working? I am sure things will improve progressively but in this time moment we are very far from the simplicity of Linux-BBB-Bonescript. Or also the simplcity of programming an Arduino.

Using the PRUSS for button polling seems excessive.
I think the suggestion to use PWM on the PRUSS sounds more apt.
Umm, it depends on the button. if it is a button that turns on a lamp, no problem, we can push it twice and wait an (human insignificant) time bit for the light to turn on. But if the button is, for example, and emergency stop button. It must get all our attention, i would not consider using a PRU overkill, nor a separate MCU.

Take a look at this directory for all the goodies available.
/usr/src/sys/arm/ti/am335x/
For example: am335x_dmtpps.c
This seems interesting ! i admit i don't understand all but that seems a good way.
The only possible drawback i can see here are
1] It specifically about am335, so not for RPI (i guess)
2] Still remains the problem of the responce time, you can never but sure the system will
respond to the singnal in less than 10ms (invented unit). [we are not in Real Time OS].

Anyhow, time permitting will try to implement someting so we will have something concrete to discuss about;P

bye
n.
 

obsigna

Aspiring Daemon

Reaction score: 553
Messages: 947

...
I agree, but Phishfry do you agree it is not at all easy to get the things working? I am sure things will improve progressively but in this time moment we are very far from the simplicity of Linux-BBB-Bonescript. Or also the simplcity of programming an Arduino.
Please allow me to vote-in here as well.

Bonescript is something to get the fingertips wet, something for the very first experiments, e.g. for checking whether your connected hardware is responding, whether you choose the correct set of GPIO pins, etc. BoneScript is of course very slow.
For production usage on all these ARM-SoC based boards, you really want to put the results of your experiments into a C program, and not any script/jit-language like SH, JavaScript, Python, Java. I agree, the internet is dead-full of Linux scripting/jitting code examples for addressing any kind of that ARM devices, anyway, this won't help you to get the real work done. Only recently, in order to find out the correct DTB settings for the MC4725 I2C DAC breakout board on my BeagleBone Black, I put in a microSD with a Debian Linux and did some experiments with Bonescript, but it was out of question, that I would do the hard work on FreeBSD in C, and it is working now.

The source for the DTBO enabling I2C1 on FreeBSD 12-ALPHA3:
JavaScript:
/dts-v1/;
/plugin/;

/ {
    compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

    part-number = "I2C1";
    version = "0001";
    exclusive-use = "P9.17", "P9.18", "i2c1";
};


&am33xx_pinmux {
    i2c1_pins: pinmux_i2c1_pins {
        pinctrl-single,pins = <0x158 0x32 0x15c 0x32>;
    };
};

&i2c1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&i2c1_pins>;
    clock-frequency = <400000>;
    #address-cells = <0x1>;
    #size-cells = <0x0>;
};
A small C test program for setting the output voltage between 0 and 3.3 V (Vcc).
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <dev/iicbus/iic.h>

#define Vcc 3.3

int main(int argc, const char *argv[])
{
   double Vout;

   if (argc < 2 || (Vout = strtod(argv[1], NULL)) < 0.0 || Vcc < Vout)
   {
      printf("Usage: %s <DAC Output in V> [p(ermanent]\n", argv[0]);
      return 0;
   }

   int dac = open("/dev/iic1", O_RDWR);
   if (dac < 0)
   {
      perror("DAC Open");
      return -1;
   }

   uint16_t u = lround(Vout/Vcc*0x0FFF);
   uint8_t  output[3] = {(argc > 2 && *argv[2] == 'p') ? 0x60 : 0x40, u >> 4, (u&0x0F) << 4};
   uint8_t  result[2] = {};
   uint8_t  addr = 0x62 << 1;
   struct iic_msg msgs[2] = {{addr | IIC_M_WR, IIC_M_WR, 3*sizeof(uint8_t), output},
                             {addr | IIC_M_RD, IIC_M_RD, 2*sizeof(uint8_t), result}};
   struct iic_rdwr_data data = {msgs, 1};

  if (ioctl(dac, I2CRDWR, &data) < 0)
   {
      perror("DAC I2CRDWR");
      return -1;
   }

   close(dac);
   return 0;
}
...
Umm, it depends on the button. if it is a button that turns on a lamp, no problem, we can push it twice and wait an (human insignificant) time bit for the light to turn on. But if the button is, for example, and emergency stop button. It must get all our attention, i would not consider using a PRU overkill, nor a separate MCU.
In case you have in mind the respective BoneScript example http://beagleboard.org/Support/BoneScript/pushbutton, then everybody would agree, since the interval for checking the button state is 100 ms. This is of course out of question for any kind of real world applications.

On the other hand, if we write a tight loop in C for the 1 GHz ARMv7 of the BBB, then the polling interval would be much less than a microsecond.
C:
#include <stdint.h>
#include <unistd.h>
#include <libgpio.h>


int buttonPressedHandler(void)
{
   int rc = 0;

   // do something when the button was pressed
   // rc = something();

   return rc;
}

int buttonReleasedHandler(void)
{
   int rc = 0;

   // do another thing once the button has been released
   // rc = another_thing();

   return rc;
}

int main(int argc, const char *argv[])
{
   gpio_handle_t gpio0;

   if ((gpio0 = gpio_open(0)) != GPIO_INVALID_HANDLE)
   {
      gpio_pin_input(gpio0, 26);

      while (1)
      {
         while (!gpio_pin_get(gpio0, 26));
         buttonPressedHandler();

         while (gpio_pin_get(gpio0, 26));
         buttonReleasedHandler();
      }

      gpio_close(gpio0);
   }

   return 0;
}
Of course the above shall be put into a pthread.

The ultimate solution would of course be an interrupt handler for GPIO inputs, it seems that we can do this in FreeBSD, however I didn't found out yet how. There was a Linux tutorial on GPIO interrupts. The guy resolved it by letting the interrupt create a file and then he polls the file system for the new file created. Reading this, it came to my mind, that some Linux tutorials better would have never been written.
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

Hello obsigna !

I saw you interventions in the arm mailing list.
Expecially i remember i red the format for writing DTO/DTS is changed... that is why i am trying very slowly to use the BBB on FreeBSD-12 now;)

I will run your C code for polling once "mg" compiling will end ... it is taking dozen of minutes:/

Anyhow my pre-experimental guesses are these:
1] your code will eat at least 20% CPU (as visible in top)
2] its reliability will decrease when system will go under load generated from another process.

So, the experimt i would like to do (time permitting, saturday is flying away) is this
1] Generate a freq-X square wave signal
2] Use your C code to count the HIGH it sees on that signal
3] put the system under load with another process
=> verify if your code looses some HIGH, or better, at what value of X it
will start loosing some HIGH.

I agree BoneScript is a toy, but consider, to generate the freq-X signal is the fastest thing
I can think of.

Also, another thing which is very practical in Linux is this command
"config-pin P9_14 pwm", in this example, it sets P9_14 pin as PWM. This is 100 times easier than making a DTO. I don't know well how this things works, I red of Cape Universal, but really, this would be useful for us in FreeBSD as well :)

bye
n.
 

obsigna

Aspiring Daemon

Reaction score: 553
Messages: 947

A tight while loop would almost always lead to 100 % CPU utilization.

Depending on timing needs, we may want to put calls to nanosleep(2) into the while loop, in order to tune CPU utilization

C:
...
   struct timespec ts = {0, 50000};    // 50 µs
...
...
   while (!gpio_pin_get(gpio0, 26))
      nanosleep(&ts, NULL);
   buttonPressedHandler();
...
With a nanosleep() of 50 µs, the utilization would be about 25 %. This is not as performant as I thought, but still 2000 times faster than the bonescript example with a polling interval of 100 ms. Anyway, using interrupts instead of polling would be better, of course.
 

Phishfry

Son of Beastie

Reaction score: 1,339
Messages: 3,977

not at all easy to get the things working?
I would agree there.
phk had a nice writeup on the arm mailing list for onewire using dtc dompiling modifying dts and recompiling back into a dtb.

The problem I found is the changes to Arm base are rather swift.
The Pi is advertised as a learing tool.
BBB seems more like an embedded tool. For instance, PWM is an actual hardware function. as is eQEP.
https://groups.google.com/forum/#!category-topic/beagleboard/udSAm7Afe9s
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

A tight while loop would almost always lead to 100 % CPU utilization.

Depending on timing needs, we may want to put calls to nanosleep(2) into the while loop, in order to tune CPU utilization

C:
...
   struct timespec ts = {0, 50000};    // 50 µs
...
...
   while (!gpio_pin_get(gpio0, 26))
      nanosleep(&ts, NULL);
   buttonPressedHandler();
...
With a nanosleep() of 50 µs, the utilization would be about 25 %. This is not as performant as I thought, but still 2000 times faster than the bonescript example with a polling interval of 100 ms. Anyway, using interrupts instead of polling would be better, of course.
I guess we could adjust the nanosleep according to the Nyquist-Shannon theorem, not to waste cycles. So if we suppose our button will be up for at least 1ms (unit invented) then it would be enough to sample every 0.5ms. [CAVEAT, i am not expert in signal theory, i may be saying incorrect things] .

On the other side, what would really kick our method is that if the sistem would go under load nobody could assure that we sample every 0.5ms.

The comparison with BoneScript polling is not much fair;) There is Node event loop machinery which is a nice abstraction but creates delays, and also Javascript is not C, of course. The only way to compare with BonseScript would be to let it use interrupts, wich is very easy in that framework.

I am going to have a beer in the center of my village:)

Nice talking with all you, intersting subject !
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

I would agree there.
phk had a nice writeup on the arm mailing list for onewire using dtc dompiling modifying dts and recompiling back into a dtb.

The problem I found is the changes to Arm base are rather swift.
The Pi is advertised as a learing tool.
BBB seems more like an embedded tool. For instance, PWM is an actual hardware function. as is eQEP.
https://groups.google.com/forum/#!category-topic/beagleboard/udSAm7Afe9s
Interesting, i did not know of the motor position reader machinery was also
into the BBB. Nice !

Yes, PWM is builtin hardware, this is one of the things that makes BBB superior
to RPI for electronics. In my opinion there is no comparison at all.

With time maybe, when things will stabilize a bit we will be able to document all
the stuff and make all functions availables in BBB accessible (with not too much
work) to FreeBSD users :)

... after that then we could also port Bonescript, wich is a nice toy IMO.

bye
n.
 

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

I prepared some stuff to make our experiment.

It is important to have in idea of the order of magnitueds we are considering.

If we were talking about the detection of a button pushed by a human then my (mini)
experiment tells that a long push button is about 120ms and
a short button push (more or less when you type at the keyboard)
is about 40ms. Measurements in attach.
 

Attachments

Nicola Mingotti

Well-Known Member

Reaction score: 160
Messages: 413

Step 2. Simulated continuous button press/relese

For the simulation we use PWM for these reasons.
1] I suppose we all have a BBB (even more than one;P )
2] PWM is independent hardware from the main BBB cpu
3] An alternative would be PRU, but still I have not configured them;P

I use pin P9_21.
Code:
#> sysctl dev.am335x_ehrpwm.0.freq=12
#> sysctl dev.am335x_ehrpwm.0.dutyB=32552
I discussed with Phishfry in another thread how to find these values.

In attach you can see the wave corresponds to many repeated
pushed-puttons events of ~ 40ms each.
 

Attachments

Top