4

My question is specific to the library libMPSSE from FTDI to work with USB to serial port (SPI, I2C, etc) adapters on Linux.

When I execute any program linked with the library, the method Init_libMPSSE() is called (without explicit invocation) and throws the following message.

../../Infra/src/ftdi_infra.c:243:Init_libMPSSE(): NULL expression encountered

Has anybody experienced this issue and found a workaround?.

Thanks.

Ferite
  • 131
  • 1
  • 3
  • 10

2 Answers2

4

You get this error when libMPSSE can't open the libftd2xx.so shared library. You need to set LD_LIBRARY_PATH to the path where this library was installed. For example if the library is in /usr/local/lib you would run the SPI static example like this:

sudo LD_LIBRARY_PATH=/usr/local/lib ./sample-static.o
  • My workaround is to call dlopen and dlclose for libftd2xx.so to ensure that this shared library is available before calling Init_libMPSSE(). This is important for me because Init_libMPSSE() calls exit(1) to end the program if the shared library cannot be loaded and I do not want this to happen. You can download the LibMPSSE-I2C source code from here to see how Init_libMPSSE() works: http://www.ftdichip.com/Support/SoftwareExamples/MPSSE/LibMPSSE-I2C.htm – Simon C Jul 23 '16 at 20:16
0

A:

Using:

sudo LD_LIBRARY_PATH=/usr/local/lib ./your_application

is only one of the important steps!

Important: not using sudo can result in a failure like described here!

B:

But on Linux make sure that before you execute the command above, you disable the FTDI's VCP drivers that are already included in the Linux kernel. VCP drivers and libftd2xx drivers cant coexist! So, even before you execute the command above, you have to (a) plug in the device and (b) dissable the VCP drivers:

┌───┐
│ $ │ ziga > ziga--workstation > Downloads
└─┬─┘ /dev/pts/3
  └─> sudo rmmod ftdi_sio
┌───┐
│ $ │ ziga > ziga--workstation > Downloads
└─┬─┘ /dev/pts/3
  └─> sudo rmmod usbserial

Now, your application will be able to talk with libftd2xx drivers because VCP drivers will not interfere. So now you can execute the command in A:.

C:

Pay attention that bitness of the libMPSSE (& therefore your application) and libftd2xx have to also be the same! 32-bit or 64 bit!

For Linux, FTDI only provides 32-bit precompiled libMPSSE library here, but they provide 32-bit and 64-bit libftd2xx drivers here. So if you installed 64-bit libftd2xx, you need to compile the 64-bit libMPSSE library yourself! Sources are available here.

If we are on 64-bit system, we download the sources and we will get the compressed file libMPSSE_Source.zip. We extract it:

┌───┐
│ $ │ ziga > ziga--workstation > Downloads
└─┬─┘ /dev/pts/4
  └─> unzip libMPSSE_Source.zip

and we will get a folder libMPSSE__0-6_Source. We move inside and try to build the library!

┌───┐
│ $ │ ziga > ziga--workstation > Downloads
└─┬─┘ /dev/pts/4
  └─> cd ./libMPSSE__0-6_Source/LibMPSSE/
  
┌───┐
│ $ │ ziga > ziga--workstation > LibMPSSE
└─┬─┘ /dev/pts/4
  └─> cp ../External/Linux/libftd2xx1.1.12/release/ftd2xx.h .

┌───┐
│ $ │ ziga > ziga--workstation > LibMPSSE
└─┬─┘ /dev/pts/4
  └─> cp ../External/Linux/libftd2xx1.1.12/release/WinTypes.h .
  
┌───┐
│ $ │ ziga > ziga--workstation > LibMPSSE
└─┬─┘ /dev/pts/4
  └─> gcc -Wall -c *.c
ftdi_mid.c: In function ‘Mid_CheckMPSSEAvailable’:
ftdi_mid.c:653:2: error: unknown type name ‘byte’
  653 |  byte los = strlen(devList.Description);
      |  ^~~~

We will see that there is an error but it is fixable. We just open a file ftdi_mid.h and move to the line 653 which we edit like this:

unsigned char los = strlen(devList.Description);

Now we compile .h files to .o files and create an archive i.e. static library libMPSSE.a:

┌───┐
│ $ │ ziga > ziga--workstation > LibMPSSE
└─┬─┘ /dev/pts/4
  └─> gcc -Wall -c *.c

┌───┐
│ $ │ ziga > ziga--workstation > LibMPSSE
└─┬─┘ /dev/pts/4
  └─> ar -cvq libMPSSE.a *.o 
a - ftdi_common.o
a - ftdi_i2c.o
a - ftdi_infra.o
a - ftdi_mid.o
a - ftdi_spi.o

We can now also move this 64-bit library in our project's folder and we can use this one, but doing this would demand us to remove or rename the 32-bit libraries that are already there.

D:

To compile my application with 32-bit libraries, I used:

gcc -Wall -Wpedantic -g -gdwarf-2 -m32 -L. -o main.elf main.c -lMPSSE -ldl

Note that I am on Debian 11 and in order to crosscompile with -m32 flag, you need to install the package gcc-multiarch.

But to compile my application with 64-bit libraries, I used:

gcc -Wall -Wpedantic -g -gdwarf-2 -L. -o main.elf main.c -lMPSSE -ldl
71GA
  • 1,132
  • 6
  • 36
  • 69