1

I use a USB Device wit a single Button and LED inside.

I tested software to change color of the device, API for the hardware is only implemented in c: https://github.com/katie-snow/Ultimarc-linux

To run it at golang, the c-code was embedded in go-code (above import "C") The c-library "libultimarc" of the USB-Button was provided to the sw as static c lib: libultimarc.a Also the lib for USB is static: libusb-1.0.a Other libs are dynamic. (see ldd below)

I use Linux and x86_64 computers. Build-host is ubuntu, test Host is debian.

The program compiles and works nice, the color of the USB Device is changing as intended. But only at the build system.

If I try to run the executable from the compile-host at other x86_64 linux machines (test-host) it is doing nothing, just waiting without any response.

Golang code with embedded c-code goC-LedButton.go :

package main
/*
// Everything in comments above the import "C" is C code and will be compiled with GCC. 
#cgo LDFLAGS: "/home/user/BUTTON/Ultimarc-linux/src/libs/.libs/libultimarc.a"  "/home/user/BUTTON/libusb-1.0.26/libusb/.libs/libusb-1.0.a" "-ludev" "-ljson-c" 
// path of json.h
#cgo CFLAGS: "-I/usr/local/include/json-c/" 

#include "Ultimarc-linux/src/libs/ulboard.h"
#include "Ultimarc-linux/src/libs/common.h"
#include "Ultimarc-linux/src/libs/usbbutton.h"
#include "Ultimarc-linux/src/libs/ipacseries.h"

#include <json.h>

int changeColor(char *str) {
    ulboard myboard;
    myboard.type = ulboard_type_usbbutton;
    myboard.version = ulboard_version_null;
    struct json_object *parsed_json_color;
    _Bool ret;
    parsed_json_color = json_tokener_parse(str);
    ret = updateBoardUSBButtonColor(parsed_json_color, &myboard);
    return ret;
}

int toRed(void) {
    _Bool ret;
    char *str = "{ \"red\" : 255,  \"green\" : 0, \"blue\" : 0 }";
    ret = changeColor(str);
    return ret;
}

int toGreen(void) {
    _Bool ret;
    char *str = "{ \"red\" : 0,  \"green\" : 255, \"blue\" : 0 }";
    ret = changeColor(str);
    return ret;
}

int toBlue(void) {
    _Bool ret;
    char *str = "{ \"red\" : 0,  \"green\" : 0, \"blue\" : 255 }";
    ret = changeColor(str);
    return ret;
}
 */
import "C"
import "fmt"

func main() {


       c := C.toRed()
       fmt.Println("Changing Color to Red ", c )
       
       c = C.toGreen()
       fmt.Println("Changing Color to Green ", c )

       c = C.toBlue()
       fmt.Println("Changing Color to Blue ", c )

}

Used libraries of binary:

ldd goC-LedButton
        linux-vdso.so.1 (0x00007ffe9fafa000)
        libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007ff9cbd49000)
        libjson-c.so.3 => /lib/x86_64-linux-gnu/libjson-c.so.3 (0x00007ff9cbd3b000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff9cbd18000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff9cbb26000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff9cbd9c000)

The lib /lib/x86_64-linux-gnu/libjson-c.so.3 is on both machines installed.

The problem is that the sw is not running on other machines, and I don't understand why. The behavior is, that at the test-host it is not responding at all after start, but can be stopped with [str]+[c].

I will be very thankful for hints about how to get the sw also running on the test-host. It's most probable a lib problem?

All the best, Alex

  • 2
    What about doing the very basic debugging step and adding debug printouts before/after each call to `changeColor`, and also maybe in `changeColor`, too, and see where it appears to hang? – kostix Dec 21 '22 at 13:48
  • 2
    I'm also curious, as to why it's done so complicated: you parse a string literal containing a JSON object to basically parse a three `uint8` values, and do this using a JSON parsing library written in C? To me, this looks like a radical overengineering. – kostix Dec 21 '22 at 13:50
  • The lib is unfortunately only accepting json objects, and in my opinion the code is just straight forward.. How should I do it simpler and shorter to create a json object as done? bool updateBoardUSBButtonColor(json_object* bcfg, ulboard* board); – TrailSurfer Dec 21 '22 at 14:52
  • @kostix : I added some printf debug output lines, it seems that it is hanging at execution of updateBoardUSBButtonColor https://go.dev/play/p/CQBDh5pCQDo But why there is no error message poping up ?? – TrailSurfer Dec 21 '22 at 15:25
  • And: I separated the c-part into a .c file, build the same way , and its hanging at the exact same point , at updateBoardUSBButtonColor – TrailSurfer Dec 21 '22 at 15:53
  • 1
    so, `updateBoardUSBButtonColor` is a function provided by `github.com/katie-snow/Ultimarc-linux`, right? As to «How should I do it simpler and shorter to create a json object as done?»—I think the answer is "allocate a `json_object`, fill it up and pass a pointer to it to the call; after the call returns, deallocate the object". – kostix Dec 21 '22 at 16:26
  • 1
    A couple more points: 1) The library [uses the `debug` macro to enable debug printouts](https://github.com/katie-snow/Ultimarc-linux/search?q=debug); it's enabled when building the lib with the `DEBUG` symbol defined, so you could just do this to see whether it improves the debugging. 2) I would say, the library does not do something very complicated with the device to set the LEDs—for instance, see [this](https://github.com/katie-snow/Ultimarc-linux/blob/540d40303d1414f9fe17fbaf178b6aa6e5feb888/src/libs/usbbutton.c#L316): the code merely creates a message and sends it via `libusb`… – kostix Dec 21 '22 at 16:35
  • 1
    …so you could possibly take any suitable [Go library implementing USB](https://pkg.go.dev/search?q=usb) and try to transtale what the lib does into pure Go. – kostix Dec 21 '22 at 16:36

0 Answers0