Welcome, Guest
Username: Password: Remember me

TOPIC: IoUserMethod link error

IoUserMethod link error 1 year 7 months ago #11706

  • Snarf77
  • Snarf77's Avatar
  • OFFLINE
  • Platinum Boarder
  • Posts: 847
  • Thank you received: 2
  • Karma: 5
Hi Claes,

I'm currently writing a driver to read DHT22 temp and humidity module for rpi and I'm stuck with my module starting in the linker step.
If you could give me a help because I'm running out of idea.

What I did so far is:
- writing my IO method (IORackInit / IOCardInit....) in a C file named rt_io_m_dht22.c
- Create two module in my class volume library name DHT22 (rack level) and DHT22_Module (card level)
- Created a makefile in $pwrp_appl with following content:
snarf_top : snarf

include $(pwr_exe)/pwrp_rules.mk

snarf_modules = $(pwrp_obj)/rt_io_m_dht22.o \
		$(pwrp_obj)/rt_io_user.o
		
# Main rule 
snarf : $(snarf_modules)
	@ echo "****** Snarf modules built ******"
	
# Modules
$(pwrp_obj)/ra_io_m_dht22.o : \
	$(pwrp_appl)/rt_io_m_dht22.c \
	$(pwrp_inc)/bcm2835.h \
	$(pwrp_inc)/pwr_cvoltnvclasses.h \

$(pwrp_obj)/rt_io_user.o : $(pwrp_appl)/rt_io_user.c

- Created a rt_io_user.c in $pwrp_appl with following content:
#include "rt_io_base.h"

pwr_dImport pwr_BindIoUserMethods(DHT22);			

pwr_BindIoUserClasses(User) = {					
	pwr_BindIoUserClass(DHT22), 
 	pwr_NullClass							
 };
- In my directory volume I added a BuildOptions object with the following arguments:
PlcProcess = iothread //name of my thread
SystemModules = 1 (io_user)
ObjectModules[0] = $pwrp_obj/rt_io_m_dht22.o

Building my classvolume went smoothly as the "make" command in $pwrp_appl
Building my rootvolume in force mode went well but the build node command failed with the following error:
collect2: error: ld returned 1 exit status
%GSX-F-CCERROR, Error from c compiler or linker
-- Build node greenhouse
-- Creating bootfile for node greenhouse
-- Plc thread generated priority 22, scantime   0.10000 s, 1 plcpgm's 
-- Plc process compiled for arm_linux optimized -O3 -
-- Plc program linked for arm_linux  plc_greenhouse_0001_plcthread
-- Plc thread generated priority 22, scantime   5.00000 s, 0 plcpgm's 
-- Plc thread generated priority 22, scantime   2.00000 s, 0 plcpgm's 
-- Plc process compiled for arm_linux optimized -O3 -
-- Using local option-file plc_greenhouse_0001_iothread.opt
** Plc program link errors for arm_linux node plc_greenhouse_0001_iothread
/usr/bin/ld: /usr/local/pwrp/greenhouse/bld/arm_linux/obj/rt_io_user.o:(.data+0x20): undefined reference to `pwr_gDHT22_IoUserMethods'
collect2: error: ld returned 1 exit status
%GSX-F-CCERROR, Error from c compiler or linker

the .opt file is showing correctly :
: Autogenerated options file, Do not edit !!` $pwrp_obj/rt_io_m_dht22.o $pwrp_obj/rt_io_user.o -lpwr_rt -lpwr_pnak_dummy -lpwr_cifx_dummy -lpwr_usb_dummy -lpwr_usbio_dummy -lpwr_nodave_dummy -lpwr_mqtt_dummy -lpwr_epl_dummy

What am I missing in the process ?
I can't find out my mistake
Thanks for your help
Snarf
The administrator has disabled public write access.

IoUserMethod link error 1 year 7 months ago #11713

  • claes
  • claes's Avatar
  • OFFLINE
  • Platinum Boarder
  • Posts: 3179
  • Thank you received: 502
  • Karma: 133
Hi Snarf,

It's pwr_BindIoUserMethods() that should define the missing definition. Have you put this in the methods file? Note that you should use pwr_BindIoUserMethods and not pwr_BindIoMethods.
pwr_dExport pwr_BindIoUserMethods(DHT22) = {
 pwr_BindIoUserMethod(IoCardInit),
 pwr_BindIoUserMethod(IoCardClose),
 pwr_BindIoUserMethod(IoCardRead),
 pwr_BindIoUserMethod(IoCardWrite),
 pwr_NullMethod
};

/Claes
The administrator has disabled public write access.

IoUserMethod link error 1 year 7 months ago #11716

  • Snarf77
  • Snarf77's Avatar
  • OFFLINE
  • Platinum Boarder
  • Posts: 847
  • Thank you received: 2
  • Karma: 5
Thank you very much Claes,
Rather than started from scratch, I started from a gpio module C source code from proview source code. I replaced the C code of the IO method but I kept the BindIOMethod export at the end of the file.
I even didn't notice it wasnt a IoUser and there was a mismatch there. Stupid me !!

Thanks, everything is working now
Snarf
The administrator has disabled public write access.

IoUserMethod link error 1 year 7 months ago #11717

  • Snarf77
  • Snarf77's Avatar
  • OFFLINE
  • Platinum Boarder
  • Posts: 847
  • Thank you received: 2
  • Karma: 5
..and what is the proper way in proview to build against a shared library ?
For the moment I have added it in ObjectModules of my BuildOption object but is there any other way without need to add it specifically here ? I mean can I simply insert it in the .opt of the project of in my makefile (how in this case) of my driver ?
Thanks for information
Snarf
The administrator has disabled public write access.

IoUserMethod link error 1 year 7 months ago #11718

  • claes
  • claes's Avatar
  • OFFLINE
  • Platinum Boarder
  • Posts: 3179
  • Thank you received: 502
  • Karma: 133
Hi Snarf,

No, there is no other way. The makefile only performs the compilation of the c modules. The library is used when the plc executable is linked, and this can only be done when the node is built, with the option-file generated from the BuildOptions object.

/Claes
The administrator has disabled public write access.

IoUserMethod link error 1 year 6 months ago #11731

  • Snarf77
  • Snarf77's Avatar
  • OFFLINE
  • Platinum Boarder
  • Posts: 847
  • Thank you received: 2
  • Karma: 5
Hi CLaes,
I'm one step further but not done yet.
Indeed using the library bcm2835 requires some root privileges to map /dev/mem correctly apparently
In my C file that I used as base (outside proview) I have used the cap_set_flag and cap_set_proc method (linux capability flag bit) in order to authorize CAP_SYS_RAWIO and CAP_DAC_OVERRIDE for my executable file.
Doing this is working fine and I can read my sensor as pwrp user on my pi.

When I insert this piece of code in my rt_io_m_dht22.c source file for proview io, my thread exits with status 11 each time I execute :
if (cap_set_flag(caps, CAP_EFFECTIVE, 3, cap_list, CAP_SET) == -1) {
          errh_Warning("cap_set_flag error\n");          
    }

Don't know if this could be proview related or any other root cause but I can't find out what could be missing as the same code is running outside of proview.

Buiding of the io method source file is OK, build node in force mode is OK and pacakge build returns no issues but as soon as the init method occurs for my sensor proview exits due to this line of code.

Would you have any idea or guideline to provide.

Here is the whole io_rack_init method in case it helps:
static pwr_tStatus IoRackInit(io_tCtx ctx, io_sAgent* ap, io_sRack* rp)
{
  pwr_sClass_DHT22* op;
  cap_t caps;
  cap_value_t cap_list[2];
  op = (pwr_sClass_DHT22*)rp->op;
  
  // Give capability to the program to access /dev/mem with root privilege. 
  // Else bcm2835 get timer will fail and reading of DHT will fail
  // for this capabilities to be effective, one need also to set the flag bit on the binary:
  // sudo setcap cap_dac_override,cap_sys_rawio+ep plc_greenhouse_0001_iothread
   
    caps = cap_get_proc();
    
    cap_list[0] = CAP_SYS_RAWIO;
    cap_list[1] = CAP_DAC_OVERRIDE;
    cap_list[2] = CAP_SYS_NICE;  // to set thread priority

    if (cap_set_flag(caps, CAP_EFFECTIVE, 3, cap_list, CAP_SET) == -1) {
          errh_Warning("cap_set_flag error\n");          
    }

    //~ if (cap_set_proc(caps) != 0) {
        //~ errh_Warning("cap_set_proc error\n");        
    //~ }
  
  // Initialize IO
  if (!bcm2835_init())
  {
    return IO__INITFAIL;;
  }
  
  errh_Info("Init of DHT22 '%s'", rp->Name);
  op->Status = IO__SUCCESS;

  return IO__SUCCESS;
}

Thanks for your help
Snarf
The administrator has disabled public write access.
Time to create page: 8.529 seconds