The "overhead" of Lazarus, etc., just gets in the way of my project timewise - I don't want to invest much into it when I won't be implementing or using it. A CLI is all I need to run, test and complete the work.What overhead do you mean? How does it get in the way?
The "overhead" of Lazarus, etc., just gets in the way of my project timewise
Don't assume I'm not reading.
I'll be working on the project tomorrow.
As to the history of Pascal, I do know that had attention been paid to rapidly adding to the initial Wirth version early and not kept ring fenced it would likely be a major language today. Indeed, Ada could have been built around it as a core instead of merely inspired by it had such attention been paid earlier...
First off I'd like to second that Lazarus is really light weight.
However since I'm new to both Pascal and Lazarus I have not got around to do actual coding in Lazarus (its on my todo list).
I've written everything in Nano and compiled with "fpc <program>" directly on the RPi and launching with "./<program>".
Here are the units i have created to make my life easier. (It probably looks like crap to experienced programmers)
You can use it as an example or straight up if you find it sufficient for your needs.
@Mark: re: Ada, I read part of the linked article. One doesn't typically "do Ada" because "want to try using it". One does Ada because they get hired by an aerospace or defence co. and the Booch is thrown on their desk, "to get familiar" before having some code thrown at them to change. And here's the company style guide. And here's the flowed down B----g contract paragraph that says: "No recursion and no task rendez-vous". Here's how you check out code. Report before you leave for the day.
Even if the GPIO array is only temporary, accepted practice would be to have it in one place with published/exported routines for getting and setting pins. You could also have a unit-level property to make it look like you were accessing a variable.
That would have the undeniable advantage that you could put a breakpoint on the setter and see exactly what was happening, and any overhead that the compiler didn't optimise out would be miniscule compared with what the kernel was having to do to process your 0/1 character through the standard API, and then put it through a module/driver to access the physical bit.
re: real time: I do hope to be able to set up a timer interrupt at 1 KHz, possibly 2 KHz. That will be essential to sampling my sensors as well as running a Kalman-ish filter at 10 Hz. Otherwise I'll have to turn the Pi into an embedded system w/o OS. (I'd prefer that in some ways...)
EDIT: Forgot to mention, last night installed Laz on the Pi, and made the project from the Wiki, got it to build and run. All I get is a blank form. Not sure if I need to set up the hardware to 'drive' that, but should get to it sometime today.
Laz is pretty clunky on the Pi (Pi 4 B (4 cores/1.5GHz) with 8 GB of ram).
@ojzOr well your code compiles ... :)
But there was an error in there - a comma instead of a semicolon in GVL.pas in the code you sent w/o further units below.
Testing me, eh?
implementation uses IO_GPIO,
edit:
Then tried your test code (main) which was full of errors, but managed to fix those.
Runs (and quits immediately) - I guess because I haven't wired it up yet... not sure why you're testing on GPIO 20, oh, well, I should be able to sort it out from here....
Oh yeah the units. I had to delete some other IO_ units, i had SPI "drivers" for some mcp's (adc & dac) also declared in the GVL unit.
The code embedded was just a generic example how i use it. You have to declare the pins in the iolist. The pin 20 was just a random number i picked when writing the post.
I notice 7 others have downloaded the .zip file you posted ... I guess laziness is fun for everyone!
Over the last few months I've been playing with a CH341 board as discussed at https://hackaday.com/2018/02/21/linux-adds-ch341-gpio/ I found that I had to tweak the module/driver slightly in order to get predictable kernel-generated names, but after that it behaved very much as would be expected on an RPi. I was using GPIO access via /sys, which is the "old" kernel standard, there's also a "new" kernel standard interface via /dev/gpiochip* which I've not yet played with, and the RPi-specific one via /dev/mem which I've /definitely/ not played with https://embeddedbits.org/new-linux-kernel-gpio-user-space-interface/
I'll be looking at the /dev/gpio_____ methods tomorrow. Glad for now that I have ojz0r's code compiled and running.
Assuming that your RPi has kernel >= 4.8, what is the user:group ownership of your /dev/gpiochip* ?
QuoteAssuming that your RPi has kernel >= 4.8, what is the user:group ownership of your /dev/gpiochip* ?
pi@raspberrypi:/dev $ uname -r 5.10.11-v7l+ pi@raspberrypi:/dev $ ls -al | grep gpio crw-rw---- 1 root gpio 254, 0 Feb 17 20:46 gpiochip0 crw-rw---- 1 root gpio 254, 1 Feb 17 20:46 gpiochip1 crw-rw---- 1 root gpio 246, 0 Feb 17 20:46 gpiomem
I'll probably stick to Raspbian (or whatever it's called these days)
And my major use for Ada is using it to point out that when the DoD was looking for a language base they didn't seriously consider Lisp, although I've seen other people revisiting it comparatively recently and being impressed https://www.revk.uk/2017/11/ada.html
It used to take our 80186 cross compiler on the VAX 24 hours to compile and link about 5000 lines of code...
it's reasonable to assume that an RPi is more powerful- at least for single-user stuff- than a VAX.But yes, a 4 core Pi at 1.5GHz could host many virtual VAX-785's (16 MHz IIRC) and 16 MB of RAM...
Two labs began Ada at about the same time. Each chose a different compiler vendor.
Our lab had to meet US military s/w standards for avionics, they had to meet commercial. (The US military generally uses commercial standards for s/w these days). We were at similar criticality (about DO-160B level C).
Both had to meet divisional standards for s/w (which was a melding of both to a large degree).
Yes, the compiler was full compliance and that was a big part of the slowness. Obviously we would avoid full builds as much as possible.
Quoteit's reasonable to assume that an RPi is more powerful- at least for single-user stuff- than a VAX.But yes, a 4 core Pi at 1.5GHz could host many virtual VAX-785's (16 MHz IIRC) and 16 MB of RAM...
https://www.linkedin.com/pulse/vaxcluster-raspberry-pi-wilm-boerhout
The other lab's compiler seemed much faster though...
another:
https://www.askwoody.com/2020/ibm-system-370-on-a-raspberry-pi/
I could tell you were an ex-Ada man. You're one of the minority who knows how to spell it...
I do however recall that we sold a copy of Logitech Modula-2 on a QIC cartridge for a VAX... it's an extreme minority who remembers Logitech as a compiler supplier.
Revisiting the empty Tform ..... (see attached screen grab).
I remember a very experienced and highly respected programmer say "Wow. This record construct could be really useful!"
( I don't recall her ever doing anything other than assembler before that - HP-2100 ...)
A few years ago, I requested here, that FPC be modified to allow undeclared counter/index vars in procedures and functions as in Ada. People beat the crap out of me - you may have been one of them! Still seems like a good idea to me!
I did write some Modula-2 (Borland) back OUAT ... I seem to recall it was a university class for an easy A. (I never went to class so I think I hit a B- on that...). In those (DOS) days it was pretty tedious IIRC as one had to edit the unit interface file separately from the implementation. So main, units (interface), units (implementation). That was a loooong time ago though. I might have preferred it over Pascal if editing wasn't so tedious. Then TP 4 came out with Units and - wow! What an improvement.
I believe, had Wirth simply extended Pascal with concepts from Modula-2, that Ada could have begun there...
I do seem to recall buying stuff from Logitech and getting 'bonus packs' of s/w of all sorts...
While I don't like undeclared variables, I believe that declaring the index variable inside a for..do would be an advance since the current situation where the index value is undefined on loop termination (unless by break) is most unpleasant.
Please zip or tarball the entire project, since without- in particular- the .lfm it's meaningless.I'll pack everything in a .zip asap - need to separate the project from all sorts of other files first.
QuotePlease zip or tarball the entire project, since without- in particular- the .lfm it's meaningless.I'll pack everything in a .zip asap - need to separate the project from all sorts of other files first.
Please zip or tarball the entire project, since without- in particular- the .lfm it's meaningless.
The code I posted is that from https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi - the first two code blocks beginning at:
https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi#Switching_a_device_via_the_GPIO_port
@Mark,
I believe you mentioned Devon earlier - England? Is that where you are now?
Closest I got to Devon was Yeovil...
OK - running. Need to make some wiring changes to test that.
WARNING: Rant follows.
But, this illustrates exactly what I meant earlier about not wrapping a hardware demo in all the trappings of GUI.
Discovery 1. For this to work, the main program had be .lpi, not .pas. (How would I have known that from the Wiki page).
2. I have no idea how the form got generated. From the source code? From the form file?
3. What happened to the main program?
Ah well, I'll plodge through it ...
Thanks.
Well. It works.
And it's slow.
And it misses button presses.
I'll start stripping it down...
Is there a description of that API anywhere? I've searched and come up dry.
It occurs to me that a souped up Arduino could be my "sampler" (easy to program timer interrupts on that), compress the data and ship it to the Pi over serial (of some sort). I'll look into that possibility too. Not sure it could manage 1 Khz though. I did have a main loop on the Arduino running 1300-1400 Hz (16 MHz clock) with all sorts of things going on. Write tight and good things happen... I could also modify the Arduino to get 20 MHz ... though that's a little more complicated...
QuoteQuote from: AlanTheBeast on Today at 04:11:31 pm
Is there a description of that API anywhere? I've searched and come up dry.
gpiod
https://rasp.io/duino/ is a good start,
I do want to look into opening once per program instance and closing once per program instance - that's just more globals to hold the references.
To me a unit is fine for this w/o needing a class. A unit has a globals section to hold state and handles whether in the interface or implementation and that's fine for this - at least for my hobby purposes. And that's how ojz0r's unit was. Fine.
Old school. I know.
Generally for h/w applications of the port, I wouldn't expect the direction or configuration of a pin to change during the instance of the program. If a device were more sophisticated than that, then the programmer would have to up his sophistication to match.
Now that I'm grasping how this GPIO interface is implemented in Linux I have to say I'm really not pleased with it - sucks would be a compliment. I'm less and less sure I can do my project as originally envisioned. I may need a sensor processor that is sans OS and has a very tight interface to the general system.
Don't need no stinkin' OS.https://ultibo.org/
@ojz0r
I've made some changes (as I was trying to understand it, these made sense to improve the speed).
1- Eliminated GVL.
2- Classless unit (removed try/finally)
3- Added a control array to speed evaluation
An FPGA could do it if I can acquire the processor cell for free - but I don't have a dev environment for that either... not sure how hard it is to do these days for that matter or what it would take out of my non-infinitely deep budget. I never did an FPGA. The engineers were stuck with that. I seem to recall a lot of hair being pulled out. But that was a long time ago.
A 64 bit Arm or intel SoC mounted on a breakout board and some programming tools would really be all I need. Don't need no stinkin' OS. Give me an interrupt controller and a timer and that's all a boy needs for a hot time. I'd even, yes, I'll say it, lower myself to programming in C <spit!>. I'll shop around - there has to be something out there that doesn't need Linux.
An FPGA could do it if I can acquire the processor cell for free - but I don't have a dev environment for that either... not sure how hard it is to do these days for that matter or what it would take out of my non-infinitely deep budget. I never did an FPGA. The engineers were stuck with that. I seem to recall a lot of hair being pulled out. But that was a long time ago.
On that note, if I know the memory mapping (ports?) of the devices, can I end run the /sys/class/gpio ??? or will the memory controller intercept that?
QuoteI've made some changes (as I was trying to understand it, these made sense to improve the speed).
3- Added a control array to speed evaluation
I just settled when i got it working, i dont really need exceptional speed.
However your code looks much neater, i will check it out more in detail when i get the chance.
I like the FPGA's more, full control of every aspect of the hardware and no pesky OS to hold you back :D
There's this sort of thing, which implies that /dev/gpiomem and possibly /dev/mem might be usable.
https://raspberrypi.stackexchange.com/questions/99785/what-is-the-correct-way-to-use-dev-gpiomem-with-mmap-to-get-access-to-raspberry
That is definitely not something I will be playing with, since it is non-portable (i.e. RPi-specific) and only conceals the performance issue rather than providing a robust solution.
I append a compiles-but-untested implementation of static and dynamic interface units for the gpiod library. Use /either/ gpiod.pas /or/ gpiod_dynamic.pas, the API exposed should be identical and should behave as documented for C etc.
Nice! Funny that the question is "what is the correct way" and yet the solution is most likely the least correct way! (I haven't looked yet...). That's great for me!
At the risk of being inflammatory, "what is the correct way to operate the napalm dispenser ..."
I'll look into the rest tomorrow or Friday. Herself believes I have "communal chores" to catch up on... and if she believes it, well...
QuoteDon't need no stinkin' OS.https://ultibo.org/
Noted.
And it looks like housework is good for me as my mind wanders... While I have to confirm the behaviour, I recalled that the gyro/accel module can be configured to output the data at a desired sampling rate. It has an OCXO, so the sampling should be reasonably accurate. Can set rates well in excess of 1 Khz. Each sample 'frame' would be about 20 bytes or so... I assume that Linux will buffer serial data coming in ??? I can hit it pretty often to 'drain' and process...
I have to see how well I can use the GPS to 'frame' the timing of the gyro/accel - but for that I would have liked to use the 1PPS pin - that no longer seems viable. I was going to set the GPS to 10 Hz frames, but it can be up to 18 (such a messy number hopefully I can set it to 16 Hz).
Edit:
As part of this, I suppose I can use my fav: "now" to do rough RT dispatching of tasks and "now" and GPS time to discipline some sort of local to the code soft clock and some sort of task to back fill time on recent accel/gyro frames. The actuator part of this job will be relatively slow at about 40 - 100 Hz. I think. TBD.
PPS trailing edge interrupt would be fantastic. Not sure if I can do this in Linux. Possibly if I go the Ultibo route that DonAlfredo pointed out.
It's not clear to me yet that I actually need PPS. But for sure that would be the most accurate time check possible if not for the app then for testing. I may buy a USB sillyscope to check timing between my code and the GPS PPS signal - if the software can 'manage' time well enough, then the PPS won't be needed.
QuotePPS trailing edge interrupt would be fantastic. Not sure if I can do this in Linux. Possibly if I go the Ultibo route that DonAlfredo pointed out.
I don't think it's safe to assume you can do that without a kernel module, although the gpiod API has a monitor capability... which still might not get you better than 10 mSec resolution.
And in any event- again- LINUX IS NOT AN RTOS so you can never rely on its latency.
QuoteIt's not clear to me yet that I actually need PPS. But for sure that would be the most accurate time check possible if not for the app then for testing. I may buy a USB sillyscope to check timing between my code and the GPS PPS signal - if the software can 'manage' time well enough, then the PPS won't be needed.
Remember that you'll find it difficult to get a calibration certificate for GPS, so "the most accurate time check possible" has to be treated cautiously. "The most accurate readily available" perhaps.
A Royal Navy ship (possibly a minesweeper) experimentally disconnected its GPS a few years ago, and found that its primary radar stopped working. A certain amount of paranoia is, IMO, justified.
Re. DSO: https://forum.lazarus.freepascal.org/index.php/topic,53058.msg392300.html#msg392300
No need to repeat ... got it the first time. I will, post integration, also try DonAlfredo's suggestion...
As to resolution, if as I believe, the gyro/accel module samples as described, then the integration of that data can take place in nearish realtime and can be soft aligned. If they have a serial number or timestamp, even better (but I don't believe so). IOW counting those frames will provide me a time reference at 1/frame_rate s. I don't know offhand if there's a checksum, so reasonableness checking might be needed as well.
The PPS is the calibration. These things are, even in the cheapest sensors, on the order of 100 ns or better compared to UTC (at the phase centre of the antenna - if you have cable from the antenna to the correlator front end, then account for propagation in the cable at about 2/3 the speed of light). IAC I don't care about UTC - I do care about the period. This necessitates an interrupt, obviously.
The first GPS I'm buying states about 40ns (IIRC). 1 usec period accuracy would be much more than accurate enough for my project.
I'm surprised the radar system didn't have a fallback mode however. Such in aviation is simply unacceptable for many systems (DO-178B/C level B or A [Boeing didn't heed that on the Max]) and even lesser level systems typically have some functionality when aiding data is not provided.
In the meantime since I appreciate everything you've written over the last while (very much!), I will reward you with a curse:
https://www.youtube.com/watch?v=d4EgbgTm0Bg (quaternions - which you may be familiar with... I've found some very nicely done C source code on GitHub that I'll translate to Pascal at some point in the not distant future ...).
https://github.com/MartinWeigel/Quaternion/blob/master/Quaternion.c
With respect to everybody concerned, I've looked only slightly at Ultibo and so far I don't recall seeing anything about a *guaranteed* interrupt latency.
You misunderstand. Correct me it I'm wrong, but I don't believe that the DoD give out calibration certificates or guarantees of service level.
I read the report, and it appeared that the pilots- at least one of whom wasn't exactly the sharpest knife in the rack- had made absolutely no attempt to refer to GPS to deduce their altitude or rate of ascent/descent. And the report- which was of course French- didn't seem to think that was in any way out of the ordinary.
Meanwhile, I'm still trying to sort out some aspects of the gpiod stuff, and am rebuilding my WPi to help out with that. It's the usual sort of Linux problem: sometimes you need to map from a named device in /dev to a more detailed description in /sys, and that can be tedious.
But so far the interface units I posted don't look too bad.
Wrapping this up from my POV, after comparing GPIO handling on a PC and a Raspberry Pi, with particular emphasis on the (new) gpiod API.
Thanks. I look forward to trying that out with the package you posted the other day.
I believe that the stuff I posted the other day is functionally OK.
QuoteI believe that the stuff I posted the other day is functionally OK.
I guess I missed something along the road. I'll look for the latest version.
Only been posted once. See #73 of this thread.Great - already DL'd - not unpacked yet. Probably tomorrow. I have a test target - an old GPS with a serial port.
I have a test target - an old GPS with a serial port.
Sounds right. Wasn't clear I had to "install" anything - I thought the package (so to speak) would just be a complete thing - soup to nuts.
gpiod - Tools for interacting with Linux GPIO character device - binary
libgpiod-dev - C library for interacting with Linux GPIO device - static libraries and headers
The basic gpiod package will include a dynamically-linkable library, to which gpiod_dynamic.pas should interface.
The libgpiod-dev package will include a statically-linkable library, to which gpiod.pas should interface.
Absolutely nothing to do with Lazarus. this is RPi stuff.
GPIOPath : Pchar = '/sys/class/gpio/gpiochip0';
does not work, returns a nil for the chiphandle.
pi@raspberrypi:~/Documents/PharosGPS $ gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)
Doesn't really clarify where they are, now does it? (other than that there is -h and -v ... no other commands).
Further the following call does not work (crashes) with a valid path in it:
t := gpiod.gpiod_is_gpiochip_device(PChar('/dev/gpiochip0'));
Now trying to figure out serial data (UART). That is truly opaque in this well documented program.
Esp. as I don't have a reliable source of UART input that I know for sure is outputting data to the pin...