4 ms·
TLDR for old C hackers: The pins are memory-mapped registers at fixed physical memory addresses. You can use mmap to map the physical address to your process'
by corysama 10y ago
TLDR for old C hackers:
The pins are memory-mapped registers at fixed physical memory addresses. You can use mmap to map the physical address to your process's virtual address space. From there, you can just read and write the array. Note that you will run into hardware timing issues if you try to do this too fast.
> By using mmap and toggling the register directly from a C++ program, the GPIO can be toggled at about 2.8 MHz, much faster than the device driver approach.[3] If you think this approach will solve your problems, think again. As before, there are jitter and multi-millisecond dropouts if there is any other load on the system.
There is a system file abstraction in place. But, it seems like a lot more work for a 20x overhead vs manipulating a struct. The tiny example program at the bottom is what more my style. http://www.righto.com/2016/08/the-beaglebones-io-pins-inside-software.html#ref3 http://www.righto.com/2016/08/the-beaglebones-io-pins-inside...
I read through this article rather quickly. I'd be happy to hear if I got anything wrong.
- kens 10y agoThe interesting thing about the BeagleBone is there are two microcontrollers inside the processor chip that you can use if you want to do anything that's genuinely real-time. (I'm in the middle of using these to emulate an Ethernet for the Alto restoration. There's a big learning curve to use them.) As far as the file system abstraction, I'm not sure if it's clever or over-engineered. It seems like a whole lot of infrastructure to simply flip a bit. And the BeagleBone device trees - I can see why they did that, but it seems like there must be a better way.
- revelation 10y agoDo you use the MII interface for the PRU-ICSS to do the Ethernet? I can't really understand why they don't have even a one-page documentation on that stuff, but I've found code to interface that in parts of their industrial SDK.
- kens 10y agoI'm using bit-banging since the Alto's Ethernet is only 3 megabits/sec so the PRU (the microcontroller inside the processor chip) is fast enough. I'm pretty sure that using the MII (Media-Independent Interface, i.e. the Ethernet controller inside the PRU inside the chip) would just cause me more problems.
- Something1234 10y agoDid you ever find any good tutorials on using the beaglebone's micro controllers?
- cnvogel 10y agommap'ing /dev/mem and directly poking at registers is fine as long as you know what you are doing and one of the best ways to explore and play with something not yet "properly" supported... ;-) But of course for this you'll have to map whole memory pages (there's no smaller granularity in providing direct memory access to registers), and this typically includes all registers of (here:) the GPIO peripheral. Only toggling outputs via the set/clear registers has little potential for damage, but anything requiring a read-modify-write will race against anything the kernel might want to do with GPIO pins in this bank. And only a particular boards' configuration can tell you if there's anything important on any other pin. A serial bus might for example want to change the direction of a pin, a keyboard might enable/disable interrupts on pin-changes, there's SD-card insertion, control of a WiFi cards' transmit functionality (rfkill), power to USB busses, detection of USB OTG cables. A good compromise, if you really have to toggle pins fast, might be to first reserve and configure a GPIOs functionality via sysfs, and then only use the mmap() for the actual input/output. Or write a proper kernel module. There are inline functions/macros (for in-kernel-use) that basically do the single-register-write.
- nbadg 10y ago> By using mmap and toggling the register directly from a C++ program, the GPIO can be toggled at about 2.8 MHz, much faster than the device driver approach. I mean, it doesn't need to be C++. I was getting pretty close to that speed with the same strategy (mmap the registers directly) with a python library I wrote. It's not exactly pretty, and was the first semi-major python project I was working on, but it was fairly functional.[1] If I remember right (it was quite a while ago), I was routinely seeing speeds around 1MHz. BUT you'll occasionally see hiccups of as much as tenths of a second, because Linux is decidedly not real-time. I ran into a pretty tall brick wall when I started trying to do pin muxing[2] using the same strategy. Going pretty far down this path lead me to the conclusion that the best strategy for boards like BB/RazPi is to run them on an exokernel and then have per-language libraries that access the registers, with the exokernel[3] enforcing memory access rules. You could even use that library on multiple platforms by declaring the memory mapping for the registers as, for example, a json schema. All of the systems on a chip that I looked at datasheets for while I was working on that project (which was admittedly an extremely limited sample size) go through the same strategy of fixed physical memory addresses for peripheral pins. [1] https://github.com/Badg/hwiopy https://github.com/Badg/hwiopy [2] Pinmuxing is the process of switching functions for a given pin. Basically, SoC's are so small that the chip designers will put more than one thing, say USB + GPIO + HDMI, on the same pin. Muxing -- which is ultimately also controlled by a fixed physical register -- switches between modes. Muxing is only available from code running in protected mode, and besides, Linux wets the bed if you try to do this at runtime. That may sound silly -- why would I want to switch between USB and HDMI at runtime -- until you either think of other examples (for example, GPIO vs analog in), or realize how much of a pain in the ass it makes it to do a bunch of operating system modifications just to reconfigure your pinout. Basically, it makes development an enormous pain in the ass. [3] Exokernels are really cool, basically the lowest level of abstraction you could put in a kernel: it promises not to let you fuck up the hardware, and provides some very basic abstractions, but otherwise just gives you free reign. Very much the "consenting adults" strategy. https://en.wikipedia.org/wiki/Exokernel https://en.wikipedia.org/wiki/Exokernel
- amboar 10y agoI don't know how recently you've played with pinmux on Linux, but my understanding is the pinctrl subsystem should handle runtime muxing without wetting the bed. What issues did you run into?