pezi / dart_periphery

dart_periphery is a Dart port of the native c-periphery library
BSD 3-Clause "New" or "Revised" License
36 stars 9 forks source link

Unidentified architecture #4

Closed AlbanDurrheimer closed 2 years ago

AlbanDurrheimer commented 2 years ago

Hello,

Environment

Problem

When launch my program with dart_periphery, I have red screen with the message No pre-build c-periphery library for UNKNOWN available!.
I deduce that the integration of the system_info library in the librairy.so file fails to determine the AARCH64 architecture of my RPI.
I also notice that the system_info library is marked as discontinued.

pezi commented 2 years ago

Please try following fix

1.) Downlad the 64-bit lib: https://github.com/pezi/dart_periphery/raw/main/lib/src/native/libperiphery_aarch64.so

2) To load a custom library call setCustomLibrary(String absolutePath) before any dart_pheriphery call. This method can be helpful in any case of a problem and for a currently not supported platform.

I must replace the system_info package

AlbanDurrheimer commented 2 years ago

Hi,
I was already using the 1st solution.
I solved the problem temporarily by defining the AARCH64 on line 15 of librairy.so instead of automatic detection.

pezi commented 2 years ago

Hi! I updated the system_info package to the succesor system_info2 package. Same problem.

The reason is simple - on the Raspian OS 64-Bit cat /proc/cpuinfo used to gather the cpu infos, fails because there is no entry model name : ARMv7 Processor rev 4 (v7l) available like on Raspian OS 32-Bit

BUT this works as designed: https://github.com/raspberrypi/linux/issues/3991

UliPrantz commented 2 years ago

Currently had the same issue and made some changes to the library.

Some suggestions from my side for the library.dart file:

First I would try to remove the whole system_info package it's nice to have but shouldn't stop users from using your package. In general the whole platform check is nice but it probably should be an opt-in debug feature since all these system detection packages depend on plain simple string comparison of some typical system string. Means once this string changes nobody can use the library because it won't initialize at all. All just because some simple string changed - which will happen from time to time.

Once the system detection is an opt-in debug feature the user should already have way more control. Now to the custom libraries. I wanted to use my own customLibrary but I couldn't because these options are again pretty late in the if chain. Again the platform and library detection is a nice feature but just as a fallback. When there is a setCustomLibrary() option the user can use then it should have the highest priority otherwise there is no sense in making this public at all.

Anyways thanks for the great package :) I'm currently developing a little flutter-pi application and needed a nfc/rfid scanner for it. I wrote a PN532 driver with help of your library in dart. Once it is finished it would be cool to add it to your library. I will make a pull request then and probably have a look in the rest of the library too. When I can help with anything else let me know.

pezi commented 2 years ago

I will try to replace system_info by a system uname call - current only an experiment. Shows aarch64 on a PiOS 64 bit image. But I must clarify how robust this solutions works on different systems.

uname man page

struct utsname {
               char sysname[];    /* Operating system name (e.g., "Linux") */
               char nodename[];   /* Name within "some implementation-defined
                                     network" */
               char release[];    /* Operating system release
                                     (e.g., "2.6.28") */
               char version[];    /* Operating system version */
               char machine[];    /* Hardware identifier */
           #ifdef _GNU_SOURCE
               char domainname[]; /* NIS or YP domain name */
           #endif
};
import 'dart:ffi'; 
import 'package:ffi/ffi.dart';

typedef NativeCall = int Function(Pointer<Int8>);

final DynamicLibrary nativeAddLib = DynamicLibrary.open("libc.so.6");
NativeCall uname = nativeAddLib
    .lookup<NativeFunction<Int32 Function(Pointer<Int8>)>>("uname")
    .asFunction();

main() {
  var len = 6 * 257;
  var data = calloc<Int8>(len);
  // TODO - error checking
  uname(data);

  var utslen = 0;
  label:
  for (int i = 0; i < len; ++i) {
    if (data[i] == 0) {
      for (int j = i + 1; j < len; ++j) {
        if (data[j] != 0) {
          utslen = j;
          break label;
        }
      }
    }
  }
  print(utslen);    
  var start = utslen * 4;
  StringBuffer buf = StringBuffer();
  for (int i = start; i < len; ++i) {
    if (data[i] == 0) {
      break;
    }
    buf.write(String.fromCharCode(data[i]));
  }
  print(buf.toString());
}
UliPrantz commented 2 years ago

I understand that this is an awesome feature and probably saves some minutes debugging but why make it so complicated? Don't get me wrong meaningful error/exception messages are awesome but this solution seems to create more headaches than it solves. You only want to prevent users from using this plugin on platforms that are different from Linux (or am I missing some extremely import case here?). Keep it simple write it into your plugin description and make the plugin Linux only then this is shown on pub.dev. The error message that pops up on non Linux systems is already pretty meaningful (something along the lines "can't load a dynamic library which is compiled for ..... on a ...... system").

I don't know it just seems to introduce more errors than it actually solves. For example take this line from your solution: DynamicLibrary.open("libc.so.6"); If I'm not wrong only Linux systems use .so extension for dynamic libraries though you would have the same problem again just in a different place and who knows what else might go wrong. A simple good explanation in the installation page makes much more sense to me I guess but again maybe I miss some case here I didn't had much time to dive deeper into your whole package at this point.

moodstubos commented 2 years ago

I solved the problem temporarily by defining the AARCH64 on line 15 of librairy.so instead of automatic detection.

This works for me, thank you very much @AlbanDurrheimer

pezi commented 2 years ago

A new version of 0.8.26 is available. Changes:

Thanks to @UliPrantz Next step, I will rework the docmentation and the examples, using void setCPUarchitecture(CPU_ARCHITECTURE arch), to make clear that auto detection can fail.

AlbanDurrheimer commented 2 years ago

Thank you @pezi.

I just did a quick test just by loading the library and it seems to work.

However, since the library variable is now set to an empty string, the library is no longer loaded automatically.

Also, useSharedLibray or setCustomLibrary do not work if you use the Flutter-pi environment, because it is not the first condition checked in the getPeripheryLib function.

pezi commented 2 years ago

I reworked the libraray code (version 0.8.29) for flutter-pi and tested the code on a Pi3 unit