I am basically exporting any gpios in my application. I started to implement this on the beaglebone black. After having no problem, I passed onto implementing the application on beaglebone blue. So, I realized that the application can run for the first time, then it fails for the second time. Afterwards, it again can run for the third time.
After a little bit of search, I realized the problem is occurring when exporting the any gpio on beaglebone blue, not only it does not let overwriting desired GPIO value, but it also deletes existing gpio. As an example, simple echo 23 > /sys/class/gpio/export command gives the output on beaglebone black and beaglebone blue as follows:
Beaglebone Black (3.8.13-bone86)
root@beaglebone# echo 23 > /sys/class/gpio/export
root@beaglebone# ls /sys/class/gpio/
export gpio23 gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport
root@beaglebone# echo 23 > /sys/class/gpio/export
bash: echo: write error: Device or resource busy
root@beaglebone# ls /sys/class/gpio/
export gpio23 gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport
Beaglebone Blue (4.9.105-ti-rt-r113)
root@beaglebone# echo 23 > /sys/class/gpio/export
root@beaglebone# ls /sys/class/gpio/
export gpio23 gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport
root@beaglebone# echo 23 > /sys/class/gpio/export
bash: echo: write error: Operation not permitted
root@beaglebone# ls /sys/class/gpio/
export gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport
So, how can I get rid of this problem on beaglebone blue ?
I repeated this 'bug' in BeagleBone Black (4.14.71-ti-r80).
It was occurring in some C++ copied from the excellent Exploring BeagleBone book by Derek Molloy Issue 1, which was written when the 3.8 kernel was the latest.
I checked new version of the book (released this year), but no mention of this issue.
I 'fixed' it by putting a test for the gpio# directory existence, before writing the gpio number to the export sysfs file.
I.e. I checked for the existence of '/sys/class/gpio/gpio7'
Before writing 7 to '/sys/class/gpio/export'
I changed the existing exportGPIO function in Molloy's GPIO.cpp from:
int GPIO::exportGPIO(){
return write(GPIO_PATH, "export", this->number);
}
to:
int GPIO::exportGPIO(){
// APM - 2019-05-27 - export twice kills it
if (checkDirectoryExists(GPIO_PATH + this->name)) {
cout << std::string("GPIO: export ") + GPIO_PATH + this->name + " already exists" << endl;
return 0;
}
return write(GPIO_PATH, "export", this->number);
}
The checkDirectoryExists function I wrote based on a stat() call.
A similar approach should be quite simple in a shell script.