Our Python library works on the three main OSes (Windows, macOS, and Linux). 99.9% of the time, everything works as expected and the library automatically detects the OS and the architecture of the machine. But under Linux, in rare cases, it is necessary to specify this last parameter manually. This is the job of the YAPI.SelectArchitecture() method.
Note: If you use our Python library on Windows or macOS, you can ignore this post because the architecture detection is reliable and does not cause any problem. This issue is only relevant for Linux.
Our Python library is composed of two parts:
- The Python code which contains the objects of our library
- Several dynamic libraries that handle USB and TCP communication
The part written in Python is 100% portable and runs on any Python interpreter since Python 2.7 or 3.x.
However, it is not possible to access USB ports directly from the Python language. That's why our library needs dynamic libraries specific to each architecture. At runtime, the Python code detects the OS and architecture (32 or 64 bits, Intel or ARM, and so on) of the machine and loads the corresponding dynamic library.
Supported Linux architectures are:
- Intel 32-bit(i386)
- Intel 64 bits(x86_64)
- ARM 32 bits soft float(armel)
- ARM 32 bits hard float(armhf)
- ARM 64 bits(aarch64)
As we already told you, in the vast majority of cases, the Yoctopuce library is able to detect the architecture of the machine and therefore the proper dynamic library and everything works like clockwork.
However, some cases cannot be automated. For example, ARM processors can work in "soft float" or "hard float", and it depends on how the Linux kernel of the distribution has been compiled. Unfortunately there is no universal way to determine which mode your CPU is running in. By default, the library uses the "hard float" version because 90% of ARM distributions run in this mode.
We also came across a strange Linux installation on which the Python interpreter detected the wrong type of processor. But in this last case, the kernel and the Python interpreter had been miscross compiled.
In these situations, the solution is to use the YAPI.SelectArchitecture() method. This function takes as argument a string indicating the architecture of the machine (i.e. "armhf", "armel", "aarch64", "i386", "x86_64").
Please note! This function must be the first call to the library.
In the following example, we force the library to work with the ARM soft float 32 bits version. This code could, for example, be used on an ARCHLinux distribution.
# Forces the Yoctopuce lib to use the armel architecture
YAPI.SelectArchitecture("armel")
errmsg = YRefParam()
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
sys.exit("init error: " + errmsg.value)
print('Device list')
module = YModule.FirstModule()
while module is not None:
print(module.get_serialNumber())
module = module.nextModule()
....
Note that the code in this example only works on Linux with a 32-bit ARM soft float architecture. If we run the code as is under Windows, the call to YAPI.RegisterHub returns an error because the library tries to use the loaded Linux ARM version.
A cleaner solution is to call the YAPI.SelectArchitecture() method only when necessary, for example by testing the presence of an argument on the command line.
if sys.argv[1] == 'use_armel_option':
# Forces the Yoctopuce lib to use the armel architecture
YAPI.SelectArchitecture("armel")
errmsg = YRefParam()
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
sys.exit("init error: " + errmsg.value)
print('Device list')
module = YModule.FirstModule()
while module is not None:
print(module.get_serialNumber())
module = module.nextModule()
....
This method is very rarely used, but it allows you to bypass the architecture detection and to run our library on exotic Linux installations.