Unsolved QProcess does not operate on /sys/class/gpioxx
-
I have written a QProcess to access gpio ports on a Riot running Debain. If I send the command from the console (terminal) it works as advertised, for example
"echo in > /sys/class/gpio/gpio112/direction "
This is true for export, in out & direction, but if I send the same with QProcess it does not return an error, but nothing happens./** --------------------------------------------------------------------------- * @brief riot_gpio::system_command * This method send a command line and list of arguments to the linux command * line and read the system response to the 'cmd' send * @note if more than one system reply this will concatenate the reponce * and send a single string as answer that must be parsed by the user * @param cmd * @param arguments * @param sys_return * @return */ uint32_t riot_gpio::system_command (QString & cmd, QStringList & arguments, QString & sys_return) { QProcess process; // qProcess 'forward' all stderr messages to the stdout process.setProcessChannelMode(QProcess::MergedChannels); // exec the system commands, check if we need arguments if (arguments.count() > 0) // yip we do have arguments process.start (cmd, arguments); else // no no arguments process.start (cmd); // wait for the system process to finish the system cmd if (!process.waitForStarted(10) ) { gprintf (FLRed"\nCould not start command %s "FGray, cmd.toLatin1().data() ); return false; } if (!process.waitForFinished(50)) { // send a error message to the console gprintf (FLRed"\nNo finito for %s "FGray, cmd.toLatin1().data() ); return false; } // read the system outout and passed this to the caller answer string QByteArray result = process.readAll(); sys_return.clear(); sys_return.append(result); return true; }
I tried to send normal command like ls, etc, it works, but not when you try to access the ports.
I also tried to run it as root, the same story
I initialise the GPIOs with the following/** --------------------------------------------------------------------------- * @brief riot_gpio::init_gpio_pin * This method used the ENUM port to lookup the pin number to set the port pin * as either input or output * @param port ENUM port pin; * @param input_output */ void riot_gpio::init_gpio_pin(uint32_t enum_port, bool input_nOutput) { QString command, answer; int32_t pin_number; // lookup the port pin pin_number = lookup_pin_number (enum_port); if (verbose) gprintf(FLCyan,"\n Set GPIO [%s] %03d %s "FGray, display_pin_number_name(enum_port), pin_number, display_direction(input_nOutput) ); // set the system variable in Linux command.sprintf("echo %d > /sys/class/gpio/export", pin_number); if (!system_command(command, answer)) { gprintf (FLRed"\ncmd[%s]\n Error: init_gpio_pin Export %s to %s %s"FGray, command.toLatin1().data(), display_pin_number_name(enum_port), display_direction(input_nOutput), answer.toLatin1().data()); } // set the system variable direction command.sprintf ("echo %s > /sys/class/gpio/gpio%d/direction \n", (input_nOutput==true?"in":"out"), pin_number); if (!system_command(command, answer)) { gprintf (FLRed"\ncmd[%s]\n Error: init_gpio_pin SetDir %s to %s %s"FGray, command.toLatin1().data(), display_pin_number_name(enum_port), display_direction(input_nOutput), answer.toLatin1().data()); } }
To access ports i have
/** --------------------------------------------------------------------------- * @brief riot_gpio::set_gpio_pin * @param pin_no * @param state */ void riot_gpio::set_gpio_pin(uint32_t pin_no, BOOL state) { QString command, answer; command.sprintf ("echo %d > /sys/class/gpio/gpio%d/value ", state, pin_no); if (!system_command(command, answer)) { gprintf (FLRed"\ncmd[%s]=> Error set pin %d to %d %s"FGray, command.toLatin1().data(), pin_no, state, answer.toLatin1().data()); } } /** --------------------------------------------------------------------------- * @brief riot_gpio::get_gpio_pin * @param pin_no * @return */ UINT_32 riot_gpio::get_gpio_pin(uint32_t pin_no) { UINT_32 li = 0; QString command, answer; command.sprintf ("cat /sys/class/gpio/gpio%d/value", pin_no); if (!system_command(command, answer)) { gprintf (FLRed"\ncmd[%s]=> Error read pin%d status %s"FGray, command.toLatin1().data(), pin_no, answer.toLatin1().data()); } li = answer.toInt(); if (verbose) gprintf ("\n>> Read gpio_pin::pin%d = '%d' ", pin_no, li); return li; }
I read that you cannot use scripts with QProcess, is this then also true with the echo?
Thanks
-
Hi! QProcess can call a program with arguments. This:
echo in > /sys/class/gpio/gpio112/direction
is not a program with arguments but a shell command.echo
is a program and herein
is passed as argument. So you could run this with QProcess but not the rest because the rest needs to be interpreted by a shell. There is also no reason use "echo blah > .." and another process here./sys/class/blah
is a file. You can just write to that file usingQFile
, etc. -
Thanks, I changed it and could access the file as output, but seem to have a problem reading the output state, and inputs, can you direct me to a site with an example, please.
-
You can see here how to use streams to read from files: http://doc.qt.io/qt-5/qfile.html#details.