Beaglebone Black, how to export peripheral at boot, or as a regular user? - Page 1
Forum section: electronics / general

author: JPortici
author_rank: Super Contributor
timestamp: August 03, 2019, 09:28:58 am
content: TL;DR: At the bottomHi,It's august and there isn't much to develop at work so i started working again on an idea i had been toying with for some time: to build an automated test machine for our products.I've put together all the reasonable requirements and most if not all the unreasonable and i'm confident i can do this. It's actually not the first tester i design/build but this time i want it to beDefinitivein the sense that it can be expanded in the future.As the brain of the whole thing i'm going to use a Beaglebone Black i bought a couple of years ago for this very purpose because- I don't have to design the ADC/DAC structure around it, it's already in there -so no need to debug usb stacks or to use very slow uart links-- builtin networking and graphics- the PRUs, because i'll need pattern generators and a ways to send/receive data in non-common protocols. This saves me the pain of dealing with a dedicated decoder/encoder chip (which i can do, but if i don't need to, better.)- The PRUs will also let me implement >1 pic programmers, without having to deal with the shitty production programmers we have.. they were good until we needed updates to support new pics. We are back on using several pickits.So, in the past few days i dug out the BBB and after a number of tries with different images installed the latest available. I had to go on to the process of updating kernel and bootloader several times but now i have a truly up to date board.This is good, because i found that the newer ways to control the hardware are much less confusing and convoluted.This is bad, because almost all the documentation out there is for older kernels. It took me litterally days to figure out how to enable the pwm.Also, i have the Exploring Beaglebone Black book, which i found very helpful as i went from ZERO linux experience to a bit of linux experience and once i figured out how to adapt the old ways to the new ones i was able to run all the examples.I've come to a point where i have configured almost every pin i'll need, i can begin writing the first draft of an application that can run a test (without graphical interface, that will be developed on its own. Interface will call the test program, in case i decide to drop the GUI completely at some point)but there are some issues i can't get around with, basically for my lack of knowledge of the whole linux thing. I hope that you can help me see the lightSO TO THE QUESTIONSAt this point i'm able to run a script to configure the pins as needed (config-pin command) and i can do that as a regular user.However, i have to first enable the peripherals (like, as root, echo 0 > export in pwmchip1)Question 1: How can i export/enable all the peripherals i need at boot?I figure that once they are enabled i can just run different script to map different pinouts. I'm not sure because on the web there are different ways for different kernels and i don't know what is the current way to do it.Question 2:There is also another issue, the paths to many of the peripherals is different at every boot. Actually, it's the same up to a point. For example now PWM0 control is located at this pathCode:/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip1but at the next boot it could be atCode:/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip4I'm sure that there's a way to write a script that just enters the folder, as there is only one but i don't know how to do it.A good resource on writing bash scripts for the script rookie?Question 3:The only (safe) way i know that writes/reads the peripherals is by writing/reading the associated files, my program should also be aware of the path.Would it be a good idea to also create symbolic links to the peripherals so my program just refers to those paths?Also, is there a better and or faster (but still safe) way to access the peripherals? I know i can directly access the memory but i read this could lead to nasty issues when another process also wants to access the same resource.Question 4:Obviously i need to be root in order to read/write the peripherals. sigh. However i tested and with chmod i can make it so i can access the files as a regular users. Naturally i have to do it at every boot.Would it be good or bad practice? Is there a better way?Thank you for any help..

author: Nominal Animal
author_rank: Super Contributor
timestamp: August 03, 2019, 10:17:35 am
content: Use an init script. The details depend on whether you use SystemD or something else. For SysV init, it's just dropping that script into /etc/init.d/, and adding symlinks to it from the relevant /etc/rc?.d/ directories.MaybeBash Beginners Guide? Dunno.Let udev do it, by creating the necessary rules.No, you don't. udev can do it for you, and you are almost certainly already using udev.

author: Nominal Animal
author_rank: Super Contributor
timestamp: August 03, 2019, 10:42:14 am
content: For udev rules, I think theguide at Debian Wikiis a good one for initial description; then seethe udev man page.Essentially, you'll need to first find out a way to detect the particular device reliably, usingmatches. For example,KERNEL=="gpio*", SUBSYSTEM=="gpio", ACTION=="add"matches when the kernel finds a GPIO device. Then, you can add one or more keys, likeNAME,OWNER,GROUP,SYMLINK, orRUNto get the desired effect. For example, Adafruit usesPROGRAM=path-to-scriptto execute a script that changes the ownership and mode of the related device nodes on Beaglebones; they really should use, RUN{program}+=path-to-scriptinstead, because PROGRAM is intended for probes; a matching rule (returning zero to match, nonzero to not match).Fortunately, in/sys/, for each device you can see the udev settings because the kernel exports a pseudofile nameduevent. In particular, I think you'll find/sys/class/pwm/pwmchip*/ueventthat correspond to the PWM devices, and adding suitable matching rules withGROUP:=groupname, SYMLINK+=/dev/pwm-nameshould do what you want.

author: JPortici
author_rank: Super Contributor
timestamp: August 03, 2019, 12:05:49 pm
content: thanks for answering. The problem with /sys/class/ is the one i mentioned in my previous post: thehardwareperipheral corresponding to pwmchip* can be different at each boot. For example some times pwmchip1 corresponds to hardware pwm0, sometimes to hardware pwm2, sometimes it isn't even present, in his place you have pwmchip4.Wouldn't this mean that if my program were to look for that particular path at one boot it would control the correct PWM, the next boot a different pwm and the boot after it would control nothing and maybe crash?This is why i thought i should go with /sys/devices/ instead, because the path is consistent up to that point... And me creating links at boot just because it's not the program anymore that has to check the addresses but can work assuming they are always rightor is there something i'm still not understanding?

author: andersm
author_rank: Super Contributor
timestamp: August 03, 2019, 12:24:10 pm
content: That sounds like a weird issue in your Linux distribution, but with udev you can match on any attributes from the root to the leaf of the device tree. The command "udevadm info --query=all --attribute-walk --path=<sysfs path to device>" will print all attributes in the hierarchy of the device. I assume that eg. the "48300200.pwm" comopnent uniquely identifies the peripheral by its memory address.Udev can also create symlinks for you. The only issue is that if you're writing something that's supposed to run on boot, you have to delay it until after udev has done its job. Systemd has a "systemd-udev-settle" service you can use, dunno the best way to to it with other inits.

author: Nominal Animal
author_rank: Super Contributor
timestamp: August 03, 2019, 12:39:19 pm
content: JPortici, could you post your kernel version,uname -a?I'm not exactly sure which part of the path is the device, as I don't have a Beagle*, but the output of I guessCode:for D in /sys/devices/platform/ocp/*/*/pwm/pwmchip? ; do printf '\n%s:\n' "$D" ; udevadm info --query=all --attribute-walk "--path=$D" ; donebasically expanding on what andersm suggested, might show how to tell the difference. The numbering itself might be a probing quirk in the kernel, and the device nodes still have uniquely identifying information that can be used to generate reliable persistent symlinks.

author: JPortici
author_rank: Super Contributor
timestamp: August 05, 2019, 09:08:32 am
content: Code:debian@beaglebone:/sys/class/pwm$ uname -aLinux beaglebone 4.14.108-ti-r113 #1 SMP PREEMPT Wed Jul 31 00:01:10 UTC 2019 armv7l GNU/LinuxI have actually retried booting a couple of times, but the pwm assignment haven't changed. Could it be that it was an issue with older kernels? because i do remember a guy metioning that behaviour in a video tutorial.If it was and it's not anymore, good for me, i can probably just use an init.d script to configure everything

author: Nominal Animal
author_rank: Super Contributor
timestamp: August 05, 2019, 11:22:43 am
content: The behaviour stabilized in 4.11, if I recall correctly; and even had a different path before that (based on various github repos involving BBB GPIOs, like the Adafruit one).If there is only onepwmchipNdevice at run time, you can always add something likeCode:ln -sf /sys/devices/platform/ocp/*.epwmss/*.pwm/pwm/pwmchip[0-9] /dev/bbb-pwmas an init script, to generate/refresh the symlink.