libpruio  0.6.8
Fast and easy Digital/Analog Input/Output for Beaglebones
Messages

libpruio contains two types of software

  • software running on the host (ARM), reporting human readable messages, and
  • software running on the PRUSS, reporting its state in form of a number code.

The number codes for the states of the PRUSS software get written to PruIo::DRam [0] and the codes are defined in file pruio.hp. Ie. code PRUIO_MSG_INIT_OK signals that the init instruction executed successfuly. In normal operations the user need not care about this feature, except when using RB mode.

Instead the user communicates with the functions of the API from the host software. Most of this functions are designed to return 0 (zero) on success or an error text (ZSTRING PTR in FB, char* in C) in case of an error. Additionaly the member variable PruIo::Errr gets set to the same message text. You can use either of them to handle the error message. The texts are always internal strings owned by libpruio and must not be freed.

Just a few functions do not follow this principle

For those functions the error message (if any) is only available in variable PruIo::Errr.

In all cases, libpruio just sets the pointer PruIo::Errr. The calling code may or may not handle the error message. When the code tries to continue, it should reset the pointer to 0 (zero) to avoid blocking further function calls due to former errors.

There's a last exception: The main destructor PruIo::~PruIo() cannot use the variable PruIo::Errr, since it isn't available after the destructor has finished. Instead, the destructor writes error messages (if any) directly to stderr.

Here's an overview of all possible error messages from the public UDT member functions and some hints on how to fix the related code:

PruIo

Constructor

The constructor doesn't return a value. In order to check for errors, you have to check the error variable PruIo::Errr. It contains 0 (zero) on success. Otherwise it points to one of the following error messages:

  • "cannot open /dev/uio5": The constructor failed to open the interrupt file /dev/uio5 for read and write access. -> Make sure that the kernel driver uio_pruss is loaded (ie. by an appropriate device tree overlay) and the user has write privileges. Find details in section uio_pruss Driver.
  • "failed loading Pru_Init instructions": The constructor failed to load the init instructions to the PRU. -> Internal problem, no hint for fixing.
  • "failed executing Pru_Init instructions": The constructor failed to execute the init instructions on the PRU. -> There's some internal error in the PRU instructions due to customization. Re-install or re-compile the libpruio library.
  • "out of memory": The constructor failed to allocate memory for the configurations (Init and Conf). -> Make sure that you have at least 5 kB free.
  • "parsing kernel claims": The constructor failed to scan for kernel pinmux claims. This is not an error, but a warning. It occurs when you loaded the kernel module for pinmuxing on kernel 3.8, and libpruio cannot read in directory /sys/kernel/debug. Anyway, your program will run unless it tries to change a pin configuration. (Like on a no-pinmux configuration. In contrast, when an universal overlay is loaded, you won't see this message. The constructor auto-switches the overlay pinmuxing method.) -> Either execute the program with sudo, or enable the free pinmux feature (= calling constructor PruIo::PruIo(PRUIO_ACT_FREMUX OR ...) ).
  • "segfault": There are lots of reasons for this kind of message. When you're sure that it happens in the constructor, then it's most likely that it happens because the driver tried to wtite to PRUSS memory while the PRUSS isn't enabled. -> Make sure that the PRUSS are enabled, by loading a device tree overlay that includes &pruss { status = "okay" } and check if the uio_pruss kernel module is loaded. See chapter uio_pruss Driver for further info.

Destructor

Th destructor doesn't return a value. It also doesn't use the error variable PruIo::Errr.

Note
The variable PruIo::Errr is no longer valid when the destructor is called. That's why destructor messages don't use that variable. Instead all messages get streamed directly to STDERR.

You may see one of the following output:

  • "failed loading Pru_Exit instructions": The destructor failed to load the instructions to restore the subsystems initial state to the PRU. -> Make sure that the library libprussdrv is working properly. (Follow the documentation and test some examples.)
  • "failed executing Pru_Exit instructions": The destructor failed to execute instructions to restore the subsystems initial state on the PRU. -> There's some internal error in the PRU instructions due to customization. Re-install or re-compile the libpruio library.
  • "destructor warning: subsystems are NOT restored": This is not an error but just a warning. The destructor didn't restore the subsystems initial state, since there were no data. Either the constructor couldn't prepare this data due to an error, or the user deleted the data to prevent restoring.
  • "destructor warning: constructor failed": This is not an error but just a warning. The destructor didn't do anything (and didn't restore the subsystems initial state), since the constructor failed in an early state.

config

  • "ADC not enabled": Sampling analog lines is required (parameter Mask not equal zero), but the ADC subsystem isn't enabled. -> Either check constructor parameter Act (bit 1 - ADC must be set). Or, if you don't need ADC sampling, pass zero as parameter Mask in the function call PruIo::config().
  • "no step active": The RB or MM mode is active (parameter Samp > 1), but the parameter Mask didn't specify any active channel. -> Check those parameters in the previous call to function PruIo::config().
  • "out of memory": The external memory isn't big enough for the required number of samples. -> Either reduce the number of samples (parameter Samp) or the number of active steps (parameter Mask) in the previous call to function PruIo::config(). Or increase the size of the external memory (see Memory Organisation for details).
  • "sample rate too big": The specified sampling rate isn't reachable with the current step configuration. -> Either reduce the number of active steps (parameter Mask), or decrease the sampling rate (increase parameter Tmr) in the previous call to function PruIo::config(). Or decrease the step delays (Open and / or Sample Delay in AdcSet::St_p) before that call.
  • "failed loading Pru_Run instructions": For safety reasons the PRU instruction get (re-)loaded each time in function PruIo::config(). The function failed to load the instructions to the PRU. -> Make sure that the library libprussdrv is working properly. (Follow the documentation and test some examples.)
  • "failed executing Pru_Run instructions": The function failed to execute the PRU instructions on the PRU. -> There's some internal error in the PRU instructions due to customization. Re-install or re-compile the libpruio library.

rb_start

  • "ring buffer mode not ready": Starting ring buffer (RB) mode is required, but the PRU software isn't ready. -> Check if the ADC subsystem is enabled. Check if there's at least one active step (AdcUdt::ChAz > 0). Check the previous call to function PruIo::config().

mm_start

  • "measurement mode not ready": Starting measurement (MM) mode is required, but the PRU software isn't ready. -> First, call function PruIo::config().
  • "Trg...: too much pre-trigger samples": (... replaced by trigger number) The number of pre-trigger samples is too big. libpruio uses the DRam area as ring buffer for pre-trigger values. Its maximun size is 16 kB - PRUIO_DAT_ADC -> Either reduce parameter Samp in the previous call to AdcUdt::mm_trg_pre(). Or reduce the number of active steps in parameter Mask in the previous call to PruIo::config().
  • "Trg...: pre-trigger step must be active": (... replaced by trigger number) The function call specifies a pre-trigger for an non-active ADC step. -> Either adapt the parameter Mask in function call PruIo::config() and make the required pre-trigger step active. Or adapt the pre-trigger configuration in function call AdcUdt::mm_trg_pre() to a step that ist active in the current Mask parameter.
  • "Trg...: unknown trigger pin number": (... replaced by trigger number) The ball number in the trigger specification is too big. This means your trigger specification is brocken. (Did you customize it?) -> Re-create a correct trigger specification.
  • "Trg...: trigger pin must be in mode 7 (GPIO)": (... replaced by trigger number) The trigger specification ... should wait for an GPIO event, but the related header pin (CPU ball number) isn't in GPIO mode. -> Re-create the trigger specification with appropriate parameter Ball. Or change pin configuration by a call to function GpioUdt::config(), first.

Pin

  • "unknown pin number": The specified ball number is too big. -> Make sure that parameter Ball is less or equal PRUIO_AZ_BALL.

setPin

  • "unknown setPin ball number": The specified ball number is too big. -> Make sure that parameter Ball is less or equal PRUIO_AZ_BALL.
  • "no ocp access": The CPU ball isn't in the required modus and needs a new pinmux setting, but libpruio has no access to the sysfs folders. -> Either load the universal device tree overlay and execute the code with administrator privileges. Or make sure that digital lines are set to the required modes before you execute the code. Or consider to use the loadable kernel module and execute with administrator privileges.
  • "pinmux failed: P._.. -> x..": (points replaced by numbers) The CPU ball isn't in the required modus and needs a new pinmux setting, but either the pin or the mode isn't specified in the libpruio device tree overlay, or the overlay isn't loaded. -> Check the parameters Ball and Mo. Make sure that the required modus is defined in the libpruio device tree overlay and that overlay is loaded. Or consider to use the loadable kernel module and execute with administrator privileges.
  • "pin P._.. claimed by ...": (or "ball... claimed by ...") The LKM (loadable kernel module) is active and the program requires pinmuxing, but the related pin (CPU ball) is claimed by another system. -> Either enable the free pinmux feature (by calling constructor PruIo::PruIo(PRUIO_ACT_FREMUX OR ...) ). Or disable the pin claim by loading an other device tree overlay. Or (on kernel >= 4.14) remove the trigger file by executing
    sudo rm /boot/dtbs/`uname -r`/am335x-boneblack-uboot-univ.dtb
    
  • "pinmux missing": The program requires pinmuxing, but there is no pinmux configuration on your system. -> Provide the required pinmuxing, either before starting your application by a static boot overlay, or by a (deprecated) universal overlay, or by the LKM. The last option is the recommended solution.
Note
The above errors may also occur in any XXX.setValue() or xxx.config() function, since libpruio tries to adapt a pin when its muxmode doesn't match.
  • "failed opening PRUIO_EVNT": The CTOR failed to connect to the uio_pruss driver. This driver allows to control the PRUSS (load/start firmware, access memory). -> Make sure that the driver is working properly. Find further information in section uio_pruss Driver.

ADC

setStep

  • "ADC not enabled": You try to configure an ADC step, but in the constructor call PruIo::PruIo() the first parameter Act doesn't enable the ADC subsystem, so no sampling is possible. -> Enable the ADC subsystem by adding PRUIO_ACT_ADC to the first parameter Act in the constructor PruIo::PruIo() call.
  • "step number too big": The specified step number is too big. -> Make sure that parameter Stp is in the range of 0 to 16.
  • "channel number too big": The specified channel number is too big. -> Make sure that parameter ChN is in the range of 0 to 7.

mm_trg_pin

  • "ADC not enabled": You try to configure an ADC trigger, but in the constructor call PruIo::PruIo() the first parameter Act doesn't enable the ADC subsystem, so no sampling is possible. -> Enable the ADC subsystem by adding PRUIO_ACT_ADC to the first parameter Act in the constructor PruIo::PruIo() call.
  • "too much values to skip": The post trigger delay is too big. -> Make sure that parameter Skip is in the range of 0 to 1023.
  • "unknown trigger pin number": The specified ball number is too big. -> Make sure that parameter Ball is less or equal PRUIO_AZ_BALL.
  • "GPIO subsystem not enabled": The specified CPU ball is on a GPIO subsystem that isn't enabled. -> Either check parameter Ball. Or make sure that the GPIO subsystem is active (see constructor PruIo::PruIo() ) and enabled (PruIo->Gpio->Conf(n)->ClVa = 2 before the call to PruIo::config() ).
  • "pin must be in GPIO mode (mode 7)": The specified CPU ball isn't in GPIO mode. -> Either check parameter Ball. Or call function GpioUdt::config() to set appropriate mode, receiver and resistor configuration, first.

mm_trg_ain

  • "ADC not enabled": You try to configure an ADC trigger, but in the constructor call PruIo::PruIo() the first parameter Act doesn't enable the ADC subsystem, so no sampling is possible. -> Enable the ADC subsystem by adding PRUIO_ACT_ADC to the first parameter Act in the constructor PruIo::PruIo() call.
  • "invalid step number": The specification should get created for a non-valid step. -> Make sure to pass a number in the range of 1 to 16 as parameter Stp (the charge step - index 0 - cannot be used as trigger).
  • "trigger step not configured": The specification should get created for a step that isn't configured jet. -> Configure the desired step, first, by calling function AdcUdt::setStep().
  • "too much values to skip": The post trigger delay is too big. -> Make sure that parameter Skip is in the range of 0 to 1023.

mm_trg_pre

  • "ADC not enabled": You try to configure an ADC trigger, but in the constructor call PruIo::PruIo() the first parameter Act doesn't enable the ADC subsystem, so no sampling is possible. -> Enable the ADC subsystem by adding PRUIO_ACT_ADC to the first parameter Act in the constructor PruIo::PruIo() call.
  • "invalid step number": The specification should get created for a non-valid step. -> Make sure to pass a number in the range of 1 to 16 as parameter Stp (the charge step - index 0 - cannot be used as trigger).
  • "trigger step not configured": The specification should get created for a step that isn't configured jet. -> Configure the desired step, first, by calling function AdcUdt::setStep().
  • "trigger step not activated": The specification should get created for a step that isn't activated. -> Check parameter Stp. Make sure that the desired step bit is set in parameter Mask in the previous call to function PruIo::config().
  • "too much pre-samples": The number of pre-trigger samples is too big. -> Make sure that parameter Samp is in the range of 0 to 1023.
  • "more pre-samples than samples": The number of pre-trigger samples is too big. -> Make sure that parameter Samp isn't greater then parameter Samp in the previous call to function PruIo::config().

GPIO

Note
When the pin (CPU ball) is not in the matching mode, libpruio tries to configure it. In that case you also may get error messages as described in setPin.

config

  • "unknown GPIO output pin number": The specified ball number is too big. -> Make sure that parameter Ball is less or equal PRUIO_AZ_BALL.
  • "no GPIO mode": Setting a header pin in GPIO mode is required, but the specified mode in parameter Mo is not a GPIO mode. -> Make sure to specify a valid GPIO mode (ie. from enumerators PinMuxing).
  • "GPIO subsystem not enabled": Setting a header pin in GPIO mode is required, but the related GPIO subsystem isn't enabled. -> Set parameter Act in the CTOR call to PruIo::PruIo() so that PruIo->Gpio->Conf(n)->ClVa = 2 (n is the number of the GPIOSS controlling to that ball number).

Value

  • "unknown GPIO output pin number": The specified ball number is too big. -> Make sure that parameter Ball is less or equal PRUIO_AZ_BALL.
  • "no GPIO pin": Getting a GPIO input is required, but the specified header pin (CPU ball number) isn't in GPIO mode. -> Check the parameter Ball. Call function GpioUdt::config() to change the pin configuration to GPIO input mode.
  • "GPIO subsystem not enabled": Getting a GPIO input is required, but the related GPIO subsystem isn't enabled. -> Set PruIo->Gpio->Conf(n)->ClVa = 2 (n is the number of the GPIO subsystem connected to that ball number) and call function PruIo::config(), first.

setValue

  • "unknown GPIO output pin number": The specified ball number is too big. -> Make sure that parameter Ball is less or equal PRUIO_AZ_BALL.
  • "GPIO subsystem not enabled": Setting a GPIO configuration is required, but the related GPIO subsystem isn't enabled. -> Set parameter Act in the CTOR call to PruIo::PruIo() so that PruIo->Gpio->Conf(n)->ClVa = 2 (n is the number of the GPIOSS controlling to that ball number).
  • "no GPIO mode": Setting a new mode for the GPIO output is required, but the specified mode isn't a GPIO mode. -> Check the parameter Mo, use enumerators PinMuxing.

flush

  • "GPIO subsystem not enabled": Setting a GPIO configuration is required, but the related GPIO subsystem isn't enabled. -> Set parameter Act in the CTOR call to PruIo::PruIo() so that PruIo->Gpio->Conf(n)->ClVa = 2 (n is the number of the GPIOSS controlling to that ball number).
  • "main loop not running": You try to set a new subsystem configuration before the main loop was started. -> Make sure that the function gets called after PruIo::config() and (in case of RB mode) PruIo::rb_start().

PWM

Note
When the pin (CPU ball) is not in the matching mode, libpruio tries to configure it. In that case you also may get error messages as described in setPin.

setValue

  • "pin has no PWM capability": The specified ball number has no TIMER capability. -> Make sure that parameter Ball is one of the PWM pins listed in section PWM.
  • "pin not in PWM mode": Setting the values of a PWM output is required, but the related header pin (CPU ball) isn't in PWM mode. libruio tried to configure the CPU ball, but the call to function PruIo::setPin() failed. -> Check the parameter Ball. Check if the CPU ball is specified in the libpruio device tree overlay. Extend the device tree overlay if you need access to further CPU balls.
  • "PWMSS not enabled": Setting a PWM output is required, but the related PWMSS subsystem isn't enabled. -> Set PruIo->PwmSS->Conf(n)->ClVa = 2 (n is the number of the PWMSS connected to that ball number) and call function PruIo::config(), first.
  • "set frequency in first call": This is the first call to set PWM output at the given pin, but the specified frequency in parameter Hz is invalid. -> Make sure to pass a valid frequency in the first call.
  • "frequency not supported": The module (PWM or CAP) isn't capable to generate output at the required frequency. -> Check the parameter Hz and set an appropriate value (CAP and PWM modules have different frequency ranges).

Value

  • "pin has no PWM capability": The specified ball number has no TIMER capability. -> Make sure that parameter Ball is one of the PWM pins listed in section PWM.
  • "pin not in PWM mode": Getting the values of a PWM output is required, but the related header pin (CPU ball) isn't in PWM mode. -> Call function PwmMod::setValue() to configure then header pin, first.
  • "PWMSS not enabled": Getting the values of a PWM output is required, but the related PWMSS subsystem isn't enabled. -> Set PruIo->PwmSS->Conf(n)->ClVa = 2 (n is the number of the PWMSS connected to that ball number) and call function PruIo::config(), first.
  • "eCAP module not in output mode": Getting the values of a PWM output of a CAP module in a PWMSS is required, but the module is in input mode. -> Check the previous configuration of that pin.

snyc

  • "libpruio LKM missing": This function needs the loadable kernel module (LKM) named libpruio. Check the output of lsmod | grep libpruio . If empty, you have to install and load that module. Otherwise you cannot use that feature. See chapter Preparation for details.

TIMER

Note
When the pin (CPU ball) is not in the matching mode, libpruio tries to configure it. In that case you also may get error messages as described in setPin.

setValue

  • "pin has no TIMER capability": The specified ball number has no TIMER capability. -> Make sure that parameter Ball is one of the TIMER pins listed in section TIMER.
  • "TIMER subsystem not enabled": Setting a TIMER output is required, but the related TIMERSS subsystem isn't enabled. -> Set parameter Act in the CTOR call to PruIo::PruIo() so that PruIo->TimSS->Conf(n)->ClVa = 2 (n is the number of the TIMERSS controlling to that ball number).
  • "duration too short": The module (TIMER or CAP) isn't capable to generate output at the required time periods. -> Check the parameters Dur1 and Dur2, and set appropriate values. TIMER and CAP modules have different ranges, see section TIMER. Note: in one shot mode the minimal duration is bigger.
  • "duration too long": The module (TIMER or CAP) isn't capable to generate output at the required time periods. -> Check the parameters Dur1 and Dur2, and set appropriate values. TIMER and CAP modules have different ranges, see section TIMER.
  • "pin not in TIMER mode": Setting the values for a TIMER output is required, but the pin is not in TIMER mode, and therefor cannot generate TIMER pulses. -> Check the (previous) configuration of that pin. Or enable LKM pinmuxing, see chapter Preparation for details.
Note
When the pin (CPU ball) is not in the matching mode, libpruio tries to configure it. In that case you also may get error messages as described in setPin.

Value

  • "pin has no TIMER capability": The specified ball number has no TIMER capability. -> Make sure that parameter Ball is on of the TIMER pins listed in section TIMER.
  • "TIMER subsystem not enabled": Setting a TIMER output is required, but the related TIMERSS subsystem isn't enabled. -> Set parameter Act in the CTOR call to PruIo::PruIo() so that PruIo->TimSS->Conf(n)->ClVa = 2 (n is the number of the TIMERSS controlling to that ball number).
  • "pin not in TIMER mode": Getting the values of a TIMER output is required, but the pin is not in TIMER mode, and therefor cannot generate TIMER pulses. -> Check the (previous) configuration of that pin. Or enable LKM pinmuxing, see chapter Preparation for details.

CAP

Note
When the pin (CPU ball) is not in the matching mode, libpruio tries to configure it. In that case you also may get error messages as described in setPin.

config

  • "unknown CAP pin number": The specified ball number is too big. -> Make sure that parameter Ball is less or equal PRUIO_AZ_BALL.
  • "pin has no CAP capability": Setting a CPU ball in CAP mode is required, but it has no CAP capability. -> Check the parameter Ball. (Only P9_28 and P9_42 have CAP capability on the BBB.)
  • "CAP not enabled": Setting a CPU ball for CAP is required, but the related PWMSS subsystem isn't enabled. -> Set PruIo->PwmSS(n)->Conf->ClVa = 2 (n is the number of the PWMSS connected to that ball number) and call function PruIo::config(), first.
Note
When the pin (CPU ball) is not in the matching mode, libpruio tries to configure it. In that case you also may get error messages as described in setPin.

Value

  • "unknown CAP pin number": The specified ball number is too big. -> Make sure that parameter Ball is less or equal PRUIO_AZ_BALL.
  • "pin not in CAP mode": Fetching a value is required, but the header pin (CPU ball) isn't in CAP mode. -> Call function CapMod::config(), first.
  • "IO/RB mode not running": Fetching a value is required, but the PRU software isn't running. -> Call function PruIo::config(), first.
  • "CAP not enabled": Fetching a value is required, but the related PWMSS subsystem isn't enabled. -> Set PruIo->PwmSS->Conf(n)->ClVa = 2 (n is the number of the PWMSS connected to that ball number) and call function PruIo::config(), first.

QEP

Note
When the pin (CPU ball) is not in the matching mode, libpruio tries to configure it. In that case you also may get error messages as described in setPin.

config

  • pin has no QEP capability: The specified ball number can not get muxed to a PWMSS-QEP module -> Make sure to specify a correct pin, see QEP for details.
  • QEP not enabled: Setting a CPU ball for QEP is required, but the related PWMSS subsystem isn't enabled. -> Set PruIo->PwmSS(n)->Conf->ClVa = 2 (n is the number of the PWMSS connected to that ball number) and call function PruIo::config(), first.
  • frequency not supported: The specified frequency for speed measurement is out of the supported range -> Specify a frequency in the range of 12 to 50e6 Hz, see QEP for details.
Note
When the pin (CPU ball) is not in the matching mode, libpruio tries to configure it. In that case you also may get error messages as described in setPin.

Value

  • pin has no QEP capability: The specified ball number is not connected to a PWMSS-QEP module -> Make sure to specify a correct pin, see QEP for details.
  • IO/RB mode not running: Fetching a value is required, but the PRU software isn't running. -> Call function PruIo::config(), first.

CMake

CMake, or better CMakeFbc errors may occur when you prepare the build tree. That is after downloading and installing the source tree, but before building the binaries.

  • – Configuring incomplete, errors occurred!: CMake couldn't process all configurations. That's a fatal error, it's unlikely that building this configuration will produce anything reasonable. Check the lines before for errors or warnings and solve them. The system preparation is described in Chapter Preparation. The build tree is fine when the cmakefbc .. command output ends with:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/debian/YOUR/PATH/HERE
  • >> no target ...: Some components are missing on your system, necessary to build that target. Only the listed target is affected, other targets may work (reorted by text >> target <...> OK!). No action is required, until you need to build that target. In that case check the lines before for message for errors or warnings and solve them. The system preparation is described in Chapter Preparation.
  • cmakefbc_deps: skipping dir.bi ...: The dependency scanner misses an include file and cannot generate a CMake dependency for it. -> That's just a warning, no action is required. Find details in the cmakefbc package documentation.

make

Make errors occur after you installed and prepared the source tree, and when you start building targets. A common one is

  • file INSTALL cannot copy file: You executed a make install instruction for a restricted location. The script has no permission to perform the required write operations. -> Prepend sudo to your command (like sudo make lkm-install).

Other messages need individual treatment.