Error when compiling HAL component: undefined symbol: pinMode
05 Dec 2023 10:59 #287250
by MakerYang
When using wiringPi in the HAL component, it seems that the relevant functions cannot be found, even though wiringPi has been properly installed. The error message is as follows:
The source code of armcnc_driver.c is as follows:
After trying to compile using the command below, the same error occurs.
...
DISPLAY=halui
COORDINATES=XYZ
KINEMATICS=trivkins coordinates=XYZ
Starting LinuxCNC...
Starting LinuxCNC server program: linuxcncsvr
Loading Real Time OS, RTAPI, and HAL_LIB modules
Starting LinuxCNC IO program: io
linuxcnc TPMOD=tpmod HOMEMOD=homemod EMCMOT=motmod
Found file(REL): ./machine.hal
Shutting down and cleaning up LinuxCNC...
Removing HAL_LIB, RTAPI, and Real Time OS modules
Removing NML shared memory segments
Debug file information:
Can not find -sec DISPLAY -var INTRO_GRAPHIC -num 1
Can not find -sec DISPLAY -var INTRO_TIME -num 1
Note: Using POSIX realtime
armcnc_driver: dlopen: /usr/lib/linuxcnc/modules/armcnc_driver.so: undefined symbol: pinMode
./machine.hal:6: waitpid failed /usr/bin/rtapi_app armcnc_driver
./machine.hal:6: /usr/bin/rtapi_app exited without becoming ready
./machine.hal:6: insmod for armcnc_driver failed, returned -1
12046
Stopping realtime threads
Unloading hal components
Note: Using POSIX realtime
...
The source code of armcnc_driver.c is as follows:
/**
******************************************************************************
* @file armcnc_driver.c
* @author ARMCNC site:www.armcnc.net github:armcnc.github.io
******************************************************************************
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wiringPi.h>
#include "armcnc_driver.h"
#include "rtapi.h"
#include "rtapi_app.h"
#include "rtapi_math.h"
#include "hal.h"
#define MAX_PINS 40
#define MAX_INI_LINE_LENGTH 255
#define MAX_INI_VALUE_LENGTH 10
static int component_id;
hal_bit_t **port_data;
typedef struct {
char ESTOP_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
char SPINDLE_ENABLE_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
char SPINDLE_PWM_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
char X_HOME_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
char Y_HOME_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
char Z_HOME_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
char A_HOME_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
char B_HOME_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
char C_HOME_PIN[MAX_INI_VALUE_LENGTH][MAX_INI_LINE_LENGTH];
} INI_RESULT;
static INI_RESULT ini_data = {0};
#ifdef RTAPI
MODULE_AUTHOR("ARMCNC");
MODULE_DESCRIPTION("Driver for ARMCNC");
MODULE_LICENSE("GPL");
#endif
int read_ini_file(const char *filename, INI_RESULT *result) {
FILE *file = fopen(filename, "r");
if (!file) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: INI_RESULT\n");
return -1;
}
char line[MAX_INI_LINE_LENGTH];
char key[MAX_INI_LINE_LENGTH];
char val[MAX_INI_LINE_LENGTH];
while (fgets(line, MAX_INI_LINE_LENGTH, file) != NULL) {
if (line[0] == '#' || line[0] == ';' || line[0] == '\n') continue;
if (sscanf(line, "%[^=] = %s", key, val) == 2) {
if (strcmp(key, "ESTOP_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->ESTOP_PIN[i], token, MAX_INI_LINE_LENGTH);
result->ESTOP_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
if (strcmp(key, "SPINDLE_ENABLE_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->SPINDLE_ENABLE_PIN[i], token, MAX_INI_LINE_LENGTH);
result->SPINDLE_ENABLE_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
if (strcmp(key, "SPINDLE_PWM_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->SPINDLE_PWM_PIN[i], token, MAX_INI_LINE_LENGTH);
result->SPINDLE_PWM_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
if (strcmp(key, "X_HOME_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->X_HOME_PIN[i], token, MAX_INI_LINE_LENGTH);
result->X_HOME_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
if (strcmp(key, "Y_HOME_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->Y_HOME_PIN[i], token, MAX_INI_LINE_LENGTH);
result->Y_HOME_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
if (strcmp(key, "Z_HOME_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->Z_HOME_PIN[i], token, MAX_INI_LINE_LENGTH);
result->Z_HOME_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
if (strcmp(key, "A_HOME_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->A_HOME_PIN[i], token, MAX_INI_LINE_LENGTH);
result->A_HOME_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
if (strcmp(key, "B_HOME_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->B_HOME_PIN[i], token, MAX_INI_LINE_LENGTH);
result->B_HOME_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
if (strcmp(key, "C_HOME_PIN") == 0 && strcmp(val, "") != 0) {
char *token;
int i = 0;
token = strtok(val, " ");
while (token != NULL && i < MAX_INI_VALUE_LENGTH) {
strncpy(result->C_HOME_PIN[i], token, MAX_INI_LINE_LENGTH);
result->C_HOME_PIN[i][MAX_INI_LINE_LENGTH - 1] = '\0';
token = strtok(NULL, " ");
i++;
}
}
}
}
fclose(file);
return 0;
}
static void gpio_write(void *arg, long period)
{
int n;
}
static void gpio_read(void *arg, long period)
{
int n;
for (n = 0; n < MAX_PINS; n++) {
*(port_data[n]) = 0;
}
}
int rtapi_app_main(void)
{
rtapi_print_msg(RTAPI_MSG_INFO, "armcnc_driver...\n");
const char* env_var = "MACHINE_PATH";
char* env_value = getenv(env_var);
int retval = 0;
if (!env_value || strcmp(env_value, "") == 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: MACHINE_PATH\n");
return -1;
}
char filePath[1024];
snprintf(filePath, sizeof(filePath), "/opt/armcnc/configs/%s/machine.user", env_value);
if(!read_ini_file(filePath, &ini_data)){
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: read_ini_file\n");
return -1;
}
if (wiringPiSetup() == -1){
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: wiringPiSetup\n");
return -1;
}
component_id = hal_init("armcnc_driver");
if (component_id < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: component_id\n");
return -1;
}
port_data = malloc(MAX_PINS * sizeof(hal_bit_t *));
retval = hal_pin_bit_newf(ini_data.ESTOP_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.ESTOP_PIN[1])], component_id, ini_data.ESTOP_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: ESTOP_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.ESTOP_PIN[1]), ini_data.ESTOP_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_pin_bit_newf(ini_data.SPINDLE_ENABLE_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.SPINDLE_ENABLE_PIN[1])], component_id, ini_data.SPINDLE_ENABLE_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: SPINDLE_ENABLE_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.SPINDLE_ENABLE_PIN[1]), ini_data.SPINDLE_ENABLE_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_pin_bit_newf(ini_data.SPINDLE_PWM_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.SPINDLE_PWM_PIN[1])], component_id, ini_data.SPINDLE_PWM_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: SPINDLE_PWM_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.SPINDLE_PWM_PIN[1]), ini_data.SPINDLE_PWM_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_pin_bit_newf(ini_data.X_HOME_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.X_HOME_PIN[1])], component_id, ini_data.X_HOME_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: X_HOME_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.X_HOME_PIN[1]), ini_data.X_HOME_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_pin_bit_newf(ini_data.Y_HOME_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.Y_HOME_PIN[1])], component_id, ini_data.Y_HOME_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: Y_HOME_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.Y_HOME_PIN[1]), ini_data.Y_HOME_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_pin_bit_newf(ini_data.Z_HOME_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.Z_HOME_PIN[1])], component_id, ini_data.Z_HOME_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: Z_HOME_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.Z_HOME_PIN[1]), ini_data.Z_HOME_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_pin_bit_newf(ini_data.A_HOME_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.A_HOME_PIN[1])], component_id, ini_data.A_HOME_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: A_HOME_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.A_HOME_PIN[1]), ini_data.A_HOME_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_pin_bit_newf(ini_data.B_HOME_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.B_HOME_PIN[1])], component_id, ini_data.B_HOME_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: B_HOME_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.B_HOME_PIN[1]), ini_data.B_HOME_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_pin_bit_newf(ini_data.C_HOME_PIN[2] == "IN" ? HAL_IN : HAL_OUT, &port_data[atoi(ini_data.C_HOME_PIN[1])], component_id, ini_data.C_HOME_PIN[0]);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: C_HOME_PIN\n");
hal_exit(component_id);
return -1;
}
pinMode(atoi(ini_data.C_HOME_PIN[1]), ini_data.C_HOME_PIN[2] == "IN" ? INPUT : OUTPUT);
retval = hal_export_funct("gpio.write", gpio_write, 0, 0, 0, component_id);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: gpio.write\n");
hal_exit(component_id);
return -1;
}
retval = hal_export_funct("gpio.read", gpio_read, 0, 0, 0, component_id);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR, "[error]: gpio.read\n");
hal_exit(component_id);
return -1;
}
hal_ready(component_id);
return 0;
}
void rtapi_app_exit(void)
{
hal_exit(component_id);
}
After trying to compile using the command below, the same error occurs.
sudo halcompile --install --userspace armcnc_driver.c --extra-compile-args="-I/usr/local/include" --extra-link-args="-L/usr/local/lib -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt"
Please Log in or Create an account to join the conversation.
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 677
- Thank you received: 117
05 Dec 2023 23:22 #287323
by smc.collins
Replied by smc.collins on topic Error when compiling HAL component: undefined symbol: pinMode
AFAIK , you don't use halcompile to build core components of linuxcnc. Halcompile is specifically meant for build hal components afaik. I could be wrong.
linuxcnc.org/docs/html/man/man1/halcompile.1.html
linuxcnc.org/docs/html/man/man1/halcompile.1.html
The following user(s) said Thank You: MakerYang
Please Log in or Create an account to join the conversation.
06 Dec 2023 02:20 #287326
by MakerYang
Replied by MakerYang on topic Error when compiling HAL component: undefined symbol: pinMode
My mistake occurred when compiling a custom HAL real-time component, and the link you provided also indicates that it supports C files.
Please Log in or Create an account to join the conversation.
06 Dec 2023 06:56 #287333
by rodw
Replied by rodw on topic Error when compiling HAL component: undefined symbol: pinMode
What it says is it preprocesses .comp files to .c files.
Comp files are a mix of C and Python to allow documents (man files) to be created in the one file. Plus it simplifies creating the C files for a component via some scripting.
Halcomp is used to create some modules (eg. see homecomp.comp which allows building a custom homing module) but there is support built into the core to allow this to be done.
Comp files are a mix of C and Python to allow documents (man files) to be created in the one file. Plus it simplifies creating the C files for a component via some scripting.
Halcomp is used to create some modules (eg. see homecomp.comp which allows building a custom homing module) but there is support built into the core to allow this to be done.
Please Log in or Create an account to join the conversation.
Time to create page: 0.072 seconds