I have a single threaded Linux application using boost :: asio for asynchronous I / O. Now I need to extend this reader application in the GPIO inputs to /sys/class/gpio/gpioXX/value .
Can this be done using boost :: asio :: posix :: stream_descriptor on GPIO inputs with multiple edges?
I configured the GPIO input as follows:
echo XX >/sys/class/gpio/export echo in >/sys/class/gpio/gpioXX/direction echo both >/sys/class/gpio/gpioXX/edge
I was able to write a test application based on epoll that locks the GPIO file descriptor until the GPIO signal changes, but boost::asio does not seem to be able to block correctly. The boost::asio::async_read always immediately calls the handler (of course, only inside io_service.run() ) with EOF or - if the file pointer was set back - 2 bytes of data.
I am not an expert in boost::asio internal, but maybe the reason is that the boost::asio epoll reactor starts at the level instead of starting in the case of posix::stream_descriptor ?
Here is my code:
#include <fcntl.h> #include <algorithm> #include <iterator> #include <stdexcept> #include <boost/asio.hpp> boost::asio::io_service io_service; boost::asio::posix::stream_descriptor sd(io_service); boost::asio::streambuf streambuf; void read_handler(const boost::system::error_code& error, std::size_t bytes_transferred) { if (error.value() == boost::asio::error::eof) { // If we don't reset the file pointer we only get EOFs lseek(sd.native_handle(), 0, SEEK_SET); } else if (error) throw std::runtime_error(std::string("Error ") + std::to_string(error.value()) + " occurred (" + error.message() + ")"); std::copy_n(std::istreambuf_iterator<char>(&streambuf), bytes_transferred, std::ostreambuf_iterator<char>(std::cout)); streambuf.consume(bytes_transferred); boost::asio::async_read(sd, streambuf, &read_handler); } int main(int argc, char *argv[]) { if (argc != 2) return 1; int fd = open(argv[1], O_RDONLY); if (fd < 1) return 1; try { sd.assign(fd); boost::asio::async_read(sd, streambuf, &read_handler); io_service.run(); } catch (...) { close(fd); return 1; } close(fd); return 0; }
c ++ boost-asio epoll gpio
Florian
source share