NI Linux Real-Time Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

integration with C on raspberry pi 4b [solved]

Solved!
Go to solution

Hi all,

 

I'm working on a project in labview that requires the use of a raspberry pi (or, if necessary, other similar SBC such as beaglebone), which I'm interacting with via makerhub's LINX and the realtime environment. Part of this project will require me to make system calls to the Linux kernel, so I've been trying to figure out how to interact with C libraries, but I'm at a loss as of to what I am missing here, as nothing seems to work.

 

C header file:

 

 

 

 

// header guard
#ifndef __libmylib__
#define __libmylib__

// C/++ compatability
#ifdef __cplusplus
extern "C" {
#endif

void test();

#ifdef __cplusplus
}
#endif

#endif

 

 

 

 

C file:

 

 

 

 

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

void test() {
    FILE *fp = fopen("/home/pi/.test", "w");

    if (fp == NULL) {
        exit(1);
    }

    fprintf(fp, "test success\n");

    fclose(fp);
}

 

 

 

 

compilation command:

 

 

 

 

gcc -Wall -Wextra -fpic -g -c libmylib.c -o libmylib.o
gcc -shared -g -o libmylib.so libmylib.o

 

 

 

 

testing the resulting .so file has proven it to work with both static and dynamic linking in pure C; when trying to connect to it with labview, however, I am given the error "name.vi loaded with errors on the target and was closed".

 

my configuration for the library call in labview looks like this:

call library function configurationcall library function configuration

 

 

 

 

 

 

 

 

 

 

 

 

 

my G code looks like this:

image.png

 

 

 

 

 

 

 

 

 

all of my VIs are underneath the raspberry pi realtime target in the project explorer.

 

finally, just to make sure all information is available, here is some information from the raspberry pi:

 

 

 

 

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.17-v7l+ #1414 SMP Fri Apr 30 13:20:47 BST 2021 armv7l GNU/Linux

pi@raspberrypi:~ $ lscpu
Architecture:        armv7l
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  4
Socket(s):           1
Vendor ID:           ARM
Model:               3
Model name:          Cortex-A72
Stepping:            r0p3
CPU max MHz:         1500.0000
CPU min MHz:         600.0000
BogoMIPS:            108.00
Flags:               half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32

pi@raspberrypi:/usr/lib $ file libmylib.so 
libmylib.so: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=97fabcbe7c7f5fd123d636430220a25c85cfcd57, with debug_info, not stripped

pi@raspberrypi:/usr/lib $ ls -l | grep libmylib.so
-rwxr-xr-x   1 root root    9924 Jun  2 11:06 libmylib.so

 

 

 

 

 

any and all help is very much appreciated!

0 Kudos
Message 1 of 2
(114 Views)
Solution
Accepted by topic author _Ronan

Well, it's been a bit of a ride, but ultimately I figured this out with some in-person help from a coworker. The documentation provided by LabVIEW and Makerspace regarding how things work on the pi leaves a lot to be desired.

 

Here's something really important that, for some reason, I never saw in basically any documentation, save for this one soon-to-be-dead link: all of the VIs are deployed to the Pi inside of a chrooted environment that basically run's NI's realtime linux distro inside of the pi. This means that when I moved compiled .so libraries to /usr/lib, they _were_ in the right place for anything running outside the chroot, but entirely invisible to anything inside the chroot. This also means that the linking done by ld at compile time to those .so libraries was no longer relevant, as anything statically linked may not even exist on the other system. To resolve this, I chrooted into the realtime system and installed a compiler toolchain (automated via the following bash script for anyone interested):

#!/bin/bash

# could also make this an alias, no real difference for this use case
function in_chroot() {
    sudo schroot -r -c lv -- sh -c "$*"
}

# install packages
in_chroot 'opkg update'
in_chroot 'opkg install packagegroup-core-buildessential'
in_chroot 'opkg install --force-depends libc6-dev'
in_chroot 'opkg install --force-depends libgcc-s-dev'
in_chroot 'opkg install libstdc++-staticdev'
in_chroot 'opkg install gcc'

# ensure gcc install exists
# yes, I'm aware that the quotes mashing is pretty horrible. I'm so sorry.
[ -z "$(sudo schroot -r -c lv -- sh -c 'command -v gcc')" ] && in_chroot 'cd /usr/bin && ln -s "$(ls /usr/bin | grep -e '"'"'.*gcc$'"'"' | head -n 1)" gcc'

# vim: syntax=sh

from there, it was a simple matter of repeating my steps on NI's system; this can be accessed from a shell via the schroot utility, with the command

sudo schroot -r -c lv

alternatively, as was my choice, you can develop outside of the chroot system, then move the files inside to compile them later; If you are using a tool such as vscode or eclipse to write your code rather than a cli editor such as vim, micro, or emacs, then you may also prefer this method. To access the files inside the chroot from outside, you need to navigate to /run/schroot/mount/lv. Modifying files within this directory will require root privileges. I would also heavily recommend using a makefile to automate this process.

 

Other than the chroot, everything else works exactly as you'd expect, and guides related to doing C interfacing on other NI realtime linux systems will work just about as well inside the chroot as they would in the full system.

 

Hope this helps someone else that finds themselves as confused as I was.

Cheers

Message 2 of 2
(72 Views)