Usage of an external library (bcm2835) with halcompile
24 Jul 2019 07:43 #140401
by wicki
Usage of an external library (bcm2835) with halcompile was created by wicki
I try to use the rapsberry-bcm2835-library inside of my
ethraw.comp.
Even if compiled with oder without
option extra_link_args "-lbcm2835";
I get a "ethraw.so" without any errors or warnings - but every time
I try to load the component, I get this error:
ethraw: dlopen: /home/pi/linuxcnc/rtlib/ethraw.so: undefined symbol: bcm2835_gpio_write
How is it possible to use an external library inside such a component?
ethraw.comp.
Even if compiled with oder without
option extra_link_args "-lbcm2835";
I get a "ethraw.so" without any errors or warnings - but every time
I try to load the component, I get this error:
ethraw: dlopen: /home/pi/linuxcnc/rtlib/ethraw.so: undefined symbol: bcm2835_gpio_write
How is it possible to use an external library inside such a component?
Please Log in or Create an account to join the conversation.
- tommylight
- Away
- Moderator
Less
More
- Posts: 19219
- Thank you received: 6440
25 Jul 2019 17:22 #140549
by tommylight
Replied by tommylight on topic Usage of an external library (bcm2835) with halcompile
I can not help, but replied so it moves to the top of "recent posts", makes it easier for others to see it.
Please Log in or Create an account to join the conversation.
25 Jul 2019 17:46 #140551
by wicki
Replied by wicki on topic Usage of an external library (bcm2835) with halcompile
My plan was to set a GPIO-pin before sending the eth-packet.
I have bypassed the problem by direct IO (see below - shamelessly stolen from here: www.pieter-jan.com/node/15).
Now I can measure the time difference between send and reaction to the reception.
The last image here is the result.
erste.de/timing-tests.PI4.html
license "GPL";
;;
#define BCM2708_PERI_BASE 0xfe000000 /* 0x20000000 */
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#define PIN 22 // GPIO3 // 27 GPIO2 17 // GPIO0
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
int mem_fd;
void *gpio_map;
// I/O access
volatile unsigned *gpio;
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
void flash() {
int f1=0;
GPIO_CLR = (1 << PIN);
GPIO_SET = (1 << PIN);
usleep(1);
GPIO_CLR = (1 << PIN);
return;
}
//
// Set up a memory regions to access GPIO
//
void setup_io()
{
/* open /dev/mem */
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("can't open /dev/mem \n");
exit(-1);
}
/* mmap GPIO */
gpio_map = mmap(
NULL, //Any adddress in our space will do
BLOCK_SIZE, //Map length
PROT_READ|PROT_WRITE, // Enable reading & writting to mapped memory
MAP_SHARED, //Shared with other processes
mem_fd, //File to map
GPIO_BASE //Offset to GPIO peripheral
);
close(mem_fd); //No need to keep mem_fd open after mmap
if (gpio_map == MAP_FAILED) {
printf("mmap error %d\n", (int)gpio_map); //errno also set!
exit(-1);
}
// Always use volatile pointer!
gpio = (volatile unsigned *)gpio_map;
int g,rep;
// Set up gpi pointer for direct register access
INP_GPIO(PIN); // must use INP_GPIO before we can use OUT_GPIO
OUT_GPIO(PIN);
return;
} // setup_io
I have bypassed the problem by direct IO (see below - shamelessly stolen from here: www.pieter-jan.com/node/15).
Now I can measure the time difference between send and reaction to the reception.
The last image here is the result.
erste.de/timing-tests.PI4.html
license "GPL";
;;
#define BCM2708_PERI_BASE 0xfe000000 /* 0x20000000 */
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#define PIN 22 // GPIO3 // 27 GPIO2 17 // GPIO0
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
int mem_fd;
void *gpio_map;
// I/O access
volatile unsigned *gpio;
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
void flash() {
int f1=0;
GPIO_CLR = (1 << PIN);
GPIO_SET = (1 << PIN);
usleep(1);
GPIO_CLR = (1 << PIN);
return;
}
//
// Set up a memory regions to access GPIO
//
void setup_io()
{
/* open /dev/mem */
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("can't open /dev/mem \n");
exit(-1);
}
/* mmap GPIO */
gpio_map = mmap(
NULL, //Any adddress in our space will do
BLOCK_SIZE, //Map length
PROT_READ|PROT_WRITE, // Enable reading & writting to mapped memory
MAP_SHARED, //Shared with other processes
mem_fd, //File to map
GPIO_BASE //Offset to GPIO peripheral
);
close(mem_fd); //No need to keep mem_fd open after mmap
if (gpio_map == MAP_FAILED) {
printf("mmap error %d\n", (int)gpio_map); //errno also set!
exit(-1);
}
// Always use volatile pointer!
gpio = (volatile unsigned *)gpio_map;
int g,rep;
// Set up gpi pointer for direct register access
INP_GPIO(PIN); // must use INP_GPIO before we can use OUT_GPIO
OUT_GPIO(PIN);
return;
} // setup_io
Please Log in or Create an account to join the conversation.
25 Jul 2019 21:11 #140569
by Grotius
Replied by Grotius on topic Usage of an external library (bcm2835) with halcompile
Hi,
undefined symbol: bcm2835_gpio_write
You are almost where you want to be.
Where is this symbol declared in your component file? And is it defined as int, bool, double etc?
Or is it a stream?
undefined symbol: bcm2835_gpio_write
You are almost where you want to be.
Where is this symbol declared in your component file? And is it defined as int, bool, double etc?
Or is it a stream?
Please Log in or Create an account to join the conversation.
26 Jul 2019 03:48 #140607
by wicki
Replied by wicki on topic Usage of an external library (bcm2835) with halcompile
> Where is this symbol declared in your component file
bcm2835_gpio_write is part of the library I want to use.
www.airspayce.com/mikem/bcm2835/
bcm2835_gpio_write()
void bcm2835_gpio_write ( uint8_t pin,
uint8_t on
)
bcm2835_gpio_write is part of the library I want to use.
www.airspayce.com/mikem/bcm2835/
bcm2835_gpio_write()
void bcm2835_gpio_write ( uint8_t pin,
uint8_t on
)
Please Log in or Create an account to join the conversation.
26 Jul 2019 05:10 #140610
by rodw
Replied by rodw on topic Usage of an external library (bcm2835) with halcompile
I might be way off but
Provided the object file is being linked or loaded dynamically, I would think you need to add a prototype as an extern. eg
I've never tried this from halcompile
Provided the object file is being linked or loaded dynamically, I would think you need to add a prototype as an extern. eg
extern void bcm2835_gpio_write ( uint8_t pin, uint8_t on);
I've never tried this from halcompile
The following user(s) said Thank You: wicki
Please Log in or Create an account to join the conversation.
26 Jul 2019 06:13 - 26 Jul 2019 06:13 #140617
by wicki
Replied by wicki on topic Usage of an external library (bcm2835) with halcompile
> I would think you need to add a prototype as an extern. eg
nice idea...
but it does not solve this problem:
option extra_link_args "-lbcm2835";
option extra_compiler_args "-lbcm2835";
;;
#include <bcm2835.h>
extern void bcm2835_gpio_write( uint8_t pin, uint8_t on);
extern int bcm2835_init(void);
compils without error - but if I call
bcm2835_init()
I get this:
ethraw: dlopen: /home/pi/linuxcnc/rtlib/ethraw.so: undefined symbol: bcm2835_init
btw: its a .a-library
nice idea...
but it does not solve this problem:
option extra_link_args "-lbcm2835";
option extra_compiler_args "-lbcm2835";
;;
#include <bcm2835.h>
extern void bcm2835_gpio_write( uint8_t pin, uint8_t on);
extern int bcm2835_init(void);
compils without error - but if I call
bcm2835_init()
I get this:
ethraw: dlopen: /home/pi/linuxcnc/rtlib/ethraw.so: undefined symbol: bcm2835_init
btw: its a .a-library
Last edit: 26 Jul 2019 06:13 by wicki.
Please Log in or Create an account to join the conversation.
26 Jul 2019 07:03 #140620
by rodw
Replied by rodw on topic Usage of an external library (bcm2835) with halcompile
I've never done any linux c coding so can't really help. But it looks like its looking in the right spot and coming up empty handed. I wonder if its written as a class?
Please Log in or Create an account to join the conversation.
26 Jul 2019 23:02 - 26 Jul 2019 23:17 #140697
by Grotius
Replied by Grotius on topic Usage of an external library (bcm2835) with halcompile
The preprocess will help him to dig more into the comp code...
Preprocess .comp files into .c files (the --preprocess flag)
how to :
linuxcnc.org/docs/2.5/html/man/man1/comp.1.html
The preprocess option is very nice. It translate's the comp code into a fully c code.
What is your include name for the library where bcm2835_gpio_write lives?
To files attached. The abs.comp is preprocessed into abc.c
Very nice !!
You see, much more code to dig in. When you are done, halcompile the c back into comp.
Preprocess .comp files into .c files (the --preprocess flag)
how to :
linuxcnc.org/docs/2.5/html/man/man1/comp.1.html
The preprocess option is very nice. It translate's the comp code into a fully c code.
What is your include name for the library where bcm2835_gpio_write lives?
To files attached. The abs.comp is preprocessed into abc.c
Very nice !!
Warning: Spoiler!
// This is a component for EMC2 HAL
// Copyright 2006 John Kasunich <jmkasunich at sourceforge dot net>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General
// Public License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
component abs "Compute the absolute value and sign of the input signal";
pin in float in "Analog input value" ;
pin out float out "Analog output value, always positive";
pin out bit sign "Sign of input, false for positive, true for negative" ;
pin out bit is_positive "TRUE if input is positive, FALSE if input is 0 or negative";
pin out bit is_negative "TRUE if input is negative, FALSE if input is 0 or positive";
function _;
license "GPL";
;;
FUNCTION(_) {
double tmp = in;
if ( tmp >= 0.0 ) {
sign = 0;
out = tmp;
} else {
sign = 1;
out = -tmp;
}
if (tmp > 0.000001) is_positive = 1;
else is_positive = 0;
if (tmp < -0.000001) is_negative = 1;
else is_negative = 0;
}
Warning: Spoiler!
/* Autogenerated by /usr/bin/halcompile on Sat Jul 27 00:13:37 2019 -- do not edit */
#include "rtapi.h"
#ifdef RTAPI
#include "rtapi_app.h"
#endif
#include "rtapi_string.h"
#include "rtapi_errno.h"
#include "hal.h"
#include "rtapi_math64.h"
static int comp_id;
#ifdef MODULE_INFO
MODULE_INFO(linuxcnc, "component:abs:Compute the absolute value and sign of the input signal");
MODULE_INFO(linuxcnc, "pin:in:float:0:in:Analog input value:None:None");
MODULE_INFO(linuxcnc, "pin:out:float:0:out:Analog output value, always positive:None:None");
MODULE_INFO(linuxcnc, "pin:sign:bit:0:out:Sign of input, false for positive, true for negative:None:None");
MODULE_INFO(linuxcnc, "pin:is_positive:bit:0:out:TRUE if input is positive, FALSE if input is 0 or negative:None:None");
MODULE_INFO(linuxcnc, "pin:is_negative:bit:0:out:TRUE if input is negative, FALSE if input is 0 or positive:None:None");
MODULE_INFO(linuxcnc, "funct:_:1:");
MODULE_INFO(linuxcnc, "license:GPL");
MODULE_LICENSE("GPL");
#endif // MODULE_INFO
struct __comp_state {
struct __comp_state *_next;
hal_float_t *in;
hal_float_t *out;
hal_bit_t *sign;
hal_bit_t *is_positive;
hal_bit_t *is_negative;
};
struct __comp_state *__comp_first_inst=0, *__comp_last_inst=0;
static void _(struct __comp_state *__comp_inst, long period);
static int __comp_get_data_size(void);
#undef TRUE
#define TRUE (1)
#undef FALSE
#define FALSE (0)
#undef true
#define true (1)
#undef false
#define false (0)
static int export(char *prefix, long extra_arg) {
char buf[HAL_NAME_LEN + 1];
int r = 0;
int sz = sizeof(struct __comp_state) + __comp_get_data_size();
struct __comp_state *inst = hal_malloc(sz);
memset(inst, 0, sz);
r = hal_pin_float_newf(HAL_IN, &(inst->in), comp_id,
"%s.in", prefix);
if(r != 0) return r;
r = hal_pin_float_newf(HAL_OUT, &(inst->out), comp_id,
"%s.out", prefix);
if(r != 0) return r;
r = hal_pin_bit_newf(HAL_OUT, &(inst->sign), comp_id,
"%s.sign", prefix);
if(r != 0) return r;
r = hal_pin_bit_newf(HAL_OUT, &(inst->is_positive), comp_id,
"%s.is-positive", prefix);
if(r != 0) return r;
r = hal_pin_bit_newf(HAL_OUT, &(inst->is_negative), comp_id,
"%s.is-negative", prefix);
if(r != 0) return r;
rtapi_snprintf(buf, sizeof(buf), "%s", prefix);
r = hal_export_funct(buf, (void(*)(void *inst, long))_, inst, 1, 0, comp_id);
if(r != 0) return r;
if(__comp_last_inst) __comp_last_inst->_next = inst;
__comp_last_inst = inst;
if(!__comp_first_inst) __comp_first_inst = inst;
return 0;
}
static int default_count=1, count=0;
char *names[16] = {0,};
RTAPI_MP_INT(count, "number of abs");
RTAPI_MP_ARRAY_STRING(names, 16, "names of abs");
int rtapi_app_main(void) {
int r = 0;
int i;
comp_id = hal_init("abs");
if(comp_id < 0) return comp_id;
if(count && names[0]) {
rtapi_print_msg(RTAPI_MSG_ERR,"count= and names= are mutually exclusive\n");
return -EINVAL;
}
if(!count && !names[0]) count = default_count;
if(count) {
for(i=0; i<count; i++) {
char buf[HAL_NAME_LEN + 1];
rtapi_snprintf(buf, sizeof(buf), "abs.%d", i);
r = export(buf, i);
if(r != 0) break;
}
} else {
int max_names = sizeof(names)/sizeof(names[0]);
for(i=0; (i < max_names) && names[i]; i++) {
if (strlen(names[i]) < 1) {
rtapi_print_msg(RTAPI_MSG_ERR, "names[%d] is invalid (empty string)\n", i);
r = -EINVAL;
break;
}
r = export(names[i], i);
if(r != 0) break;
}
}
if(r) {
hal_exit(comp_id);
} else {
hal_ready(comp_id);
}
return r;
}
void rtapi_app_exit(void) {
hal_exit(comp_id);
}
#undef FUNCTION
#define FUNCTION(name) static void name(struct __comp_state *__comp_inst, long period)
#undef EXTRA_SETUP
#define EXTRA_SETUP() static int extra_setup(struct __comp_state *__comp_inst, char *prefix, long extra_arg)
#undef EXTRA_CLEANUP
#define EXTRA_CLEANUP() static void extra_cleanup(void)
#undef fperiod
#define fperiod (period * 1e-9)
#undef in
#define in (0+*__comp_inst->in)
#undef out
#define out (*__comp_inst->out)
#undef sign
#define sign (*__comp_inst->sign)
#undef is_positive
#define is_positive (*__comp_inst->is_positive)
#undef is_negative
#define is_negative (*__comp_inst->is_negative)
#line 27 "abs.comp"
FUNCTION(_) {
double tmp = in;
if ( tmp >= 0.0 ) {
sign = 0;
out = tmp;
} else {
sign = 1;
out = -tmp;
}
if (tmp > 0.000001) is_positive = 1;
else is_positive = 0;
if (tmp < -0.000001) is_negative = 1;
else is_negative = 0;
}
static int __comp_get_data_size(void) { return 0; }
You see, much more code to dig in. When you are done, halcompile the c back into comp.
Attachments:
Last edit: 26 Jul 2019 23:17 by Grotius.
Please Log in or Create an account to join the conversation.
Time to create page: 0.105 seconds