OPNsense Forum

English Forums => Development and Code Review => Topic started by: Cavadus on October 25, 2017, 05:36:03 pm

Title: libgpio.h: linker command failed
Post by: Cavadus on October 25, 2017, 05:36:03 pm
Hi,

So I'm completely unfamiliar with HardenedBSD aside from what I've picked up over the last week or so.  I'm also not a C dev but I work in a small shop and was the one tasked with this.

So I'm just trying to turn some GPIOs on and off.  I'm using the libgpio.h library but I'm having linker issues.

Here is my small, simple test script:

Code: [Select]
#include <sys/types.h>
#include <err.h>
#include <libgpio.h>

int main() {
  gpio_handle_t handle;

  handle = gpio_open(0);
  if(handle == GPIO_INVALID_HANDLE)
    err(1, "gpio_open failed");
  gpio_pin_output(handle, 36);
  gpio_pin_high(handle, 36);
  gpio_close(handle);
  return 0;
}

I run this in the shell as root, simply, as:

Quote
# clang gpio_test.c

When I try to compile this script in clang (and gcc, went through the nightmare of fumbling through a manual install with no prior knowledge) I get the following linker error:

Quote
/tmp/gpio_test-dcfacd.o: In function `main':
gpio_test.c:(.text+0x12): undefined reference to `gpio_open'
gpio_test.c:(.text+0x42): undefined reference to `gpio_pin_output'
gpio_test.c:(.text+0x52): undefined reference to `gpio_pin_high'
gpio_test.c:(.text+0x5d): undefined reference to `gpio_close'

And here's the more verbose stacktrace:
Quote
FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0)
Target: x86_64-unknown-freebsd11.0
Thread model: posix
InstalledDir: /usr/bin
 "/usr/bin/clang" -cc1 -triple x86_64-unknown-freebsd11.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name gpio_test.c -mrelocation-model static -mthread-model posix -mdisable-fp-elim -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -v -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/bin/../lib/clang/3.8.0 -fdebug-compilation-dir /root -ferror-limit 19 -fmessage-length 173 -fobjc-runtime=gnustep -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/gpio_test-400842.o -x c gpio_test.c
clang -cc1 version 3.8.0 based upon LLVM 3.8.0 default target x86_64-unknown-freebsd11.0
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../lib/clang/3.8.0/include
 /usr/include
End of search list.
 "/usr/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --hash-style=both --enable-new-dtags -o a.out /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /tmp/gpio_test-400842.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
/tmp/gpio_test-400842.o: In function `main':
gpio_test.c:(.text+0x12): undefined reference to `gpio_open'
gpio_test.c:(.text+0x42): undefined reference to `gpio_pin_output'
gpio_test.c:(.text+0x52): undefined reference to `gpio_pin_high'
gpio_test.c:(.text+0x5d): undefined reference to `gpio_close'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

libgpio.h is where it should be:  /usr/include/

Quote
# /usr/include # ls -l
total 1928
[...]
-r--r--r--   1 root  wheel   3564 Jul 24 05:19 libgpio.h
[...]

And the header's content is as follows:

Code: [Select]
void            gpio_close(gpio_handle_t);
/*
 * Get a list of all the GPIO pins.
 */
int             gpio_pin_list(gpio_handle_t, gpio_config_t **);
/*
 * GPIO pin configuration.
 *
 * Retrieve the configuration of a specific GPIO pin.  The pin number is
 * passed through the gpio_config_t structure.
 */
int             gpio_pin_config(gpio_handle_t, gpio_config_t *);
/*
 * Sets the GPIO pin name.  The pin number and pin name to be set are passed
 * as parameters.
 */                                                                         
int             gpio_pin_set_name(gpio_handle_t, gpio_pin_t, char *);       
/*                                                                         
 * Sets the GPIO flags on a specific GPIO pin.  The pin number and the flags
 * to be set are passed through the gpio_config_t structure.               
 */                                                                         
int             gpio_pin_set_flags(gpio_handle_t, gpio_config_t *);         
/*                                                                         
 * GPIO pin values.                                                         
 */                                                                         
int             gpio_pin_get(gpio_handle_t, gpio_pin_t);                   
int             gpio_pin_set(gpio_handle_t, gpio_pin_t, int);               
int             gpio_pin_toggle(gpio_handle_t, gpio_pin_t);                 
/*
 * Helper functions to set pin states.
 */
int             gpio_pin_low(gpio_handle_t, gpio_pin_t);
int             gpio_pin_high(gpio_handle_t, gpio_pin_t);
/*
 * Helper functions to configure pins.
 */
int             gpio_pin_input(gpio_handle_t, gpio_pin_t);
int             gpio_pin_output(gpio_handle_t, gpio_pin_t);
int             gpio_pin_opendrain(gpio_handle_t, gpio_pin_t);
int             gpio_pin_pushpull(gpio_handle_t, gpio_pin_t);
int             gpio_pin_tristate(gpio_handle_t, gpio_pin_t);
int             gpio_pin_pullup(gpio_handle_t, gpio_pin_t);
int             gpio_pin_pulldown(gpio_handle_t, gpio_pin_t);
int             gpio_pin_invin(gpio_handle_t, gpio_pin_t);
int             gpio_pin_invout(gpio_handle_t, gpio_pin_t);
int             gpio_pin_pulsate(gpio_handle_t, gpio_pin_t);

__END_DECLS

#endif /* _LIBGPIO_H_ */

All of the referenced functions in my test script are where they should be.

So what am I doing wrong here?
Title: Re: libgpio.h: linker command failed
Post by: franco on October 25, 2017, 08:52:22 pm
Hi,

Almost there. :)

You're compiling, but missing the linker hint to the library where gpio functions reside:

# clang -lgpio gpio_test.c

(without testing)


Cheers,
Franco
Title: Re: libgpio.h: linker command failed
Post by: Cavadus on October 25, 2017, 09:51:15 pm
Awesome, that compiled it and created "a.out" but I'm still having issues.

I ran:
Quote
# ./a.out

And got the following error:
Code: [Select]
# ./a.out
a.out: gpio_open failed: No such file or directory

"gpio_open" is not int libgpio.h.  I also have a completely non-existent sys(usr/src/sys) directory where, I presume, gpio.h would normally live?

Long story short, all I'm trying to do is flip the bits for GPIOs 36 and 37 on my mobo so I can turn on and off some LEDs.
Title: Re: libgpio.h: linker command failed
Post by: franco on October 25, 2017, 10:04:40 pm
You're hitting the error in your program:

  if(handle   == GPIO_INVALID_HANDLE)
    err(1, "gpio_open failed");

There is also gpioctl in FreeBSD, some more explanation here: https://wiki.freebsd.org/FreeBSD/GPIO

It looks like you don't have any GPIO pins, seemingly only available under ARM or MIPS: https://www.freebsd.org/cgi/man.cgi?gpio(4)

Are you running i386 or amd64?


Cheers,
Franco
Title: Re: libgpio.h: linker command failed
Post by: Cavadus on October 25, 2017, 10:28:41 pm
Yeah, I get that the issue is with "gpio_open".  Where does that function live?  I pulled my test script verbatim from FreeBSD's gpio manual page example

I've tried running some simple gpioctl commands in the shell, and again just now, and no matter what I do get the same error that running the executable I just compiled gave when I tried to execute it.

I'm running an Intel Celeron CPU N2930 (https://ark.intel.com/products/81073/Intel-Celeron-Processor-N2930-2M-Cache-up-to-2_16-GHz) on an Intel Bay Trail Mini-ITX mobo.

So 64-bit.
Title: Re: libgpio.h: linker command failed
Post by: franco on October 26, 2017, 08:07:42 pm
I don't think these machines have GPIO, this is something inherent to small embedded boards for ARM and MIPS.

To go back to the beginning: what is the purpose of your task? To operate LEDs on the device that you have?


Cheers,
Franco
Title: Re: libgpio.h: linker command failed
Post by: Cavadus on October 26, 2017, 09:17:51 pm
Yes, blink some LEDs.

I have the manual for the Intel Bay Trail series right in front of me and it does claim to have an 10-pin GPIO header that allegedly has GPIOs 30 through 37.

Manual here:  http://www.jetwaycomputer.com/download/Manual/NF9HB_NF9HG/NF9HB_NF9HG.pdf

Page 16, diagram 6.

As you look at the above diagram I have two LEDs on GPIOs 36 and 37.

This message is a few years old but it has me wondering:
https://patchwork.ozlabs.org/patch/399265/

Sounds like there isn't any GPIO but there is a pin controller driver of sorts for Windows which isn't useful.
Title: Re: libgpio.h: linker command failed
Post by: Cavadus on October 30, 2017, 05:00:16 pm
Any further thoughts on this?
Title: Re: libgpio.h: linker command failed
Post by: franco on October 30, 2017, 06:20:00 pm
Sorry, missed this reply.

There is a LED driver and associated device nodes. It worked for PCEngines hardware. OPNsense removed the usage, but it's still in FreeBSD and can be used: https://www.freebsd.org/cgi/man.cgi?query=led&sektion=4

Maybe you can find a device there to flash LEDs programmatically.

The GPIO driver is not on i386/amd64 and likely supports no devices/chips in this range. In any case, getting this compiled into the kernel is unlikely and would be by subsequent firmware updates.

Maybe there is a simple USB device that could be used that has driver support to wiggle the pins... Out of ideas, but maybe one of our embedded tinkerers has a good idea?


Cheers,
Franco
Title: Re: libgpio.h: linker command failed
Post by: Cavadus on October 30, 2017, 08:04:36 pm
Yeah, kernel rebuilds and maintenance isn't going to happen so I'm currently researching 10-pin USB breakout boards.

Thanks for all of the help with this regardless.  It's been much appreciated.
Title: Re: libgpio.h: linker command failed
Post by: Cavadus on October 30, 2017, 09:58:39 pm
Does HardnedBSD allow a serial port to be opened?  If so I could possible interface with the port and use that to turn LEDs on and off.
Title: Re: libgpio.h: linker command failed
Post by: franco on October 31, 2017, 09:07:13 am
Should be possible to operate the serial port, yes. I was thinking that too, but found it a bit dirty so did not suggest it. But if it works why not. :)


Cheers,
Franco
Title: Re: libgpio.h: linker command failed
Post by: Cavadus on October 31, 2017, 02:42:53 pm
Any guides or resources you can think of that would be useful?  I've found some FreeBSD stuff but, typically, FreeBSD stuff has been of little value to me when operating in HardenedBSD.