Closed lutzbickhardt closed 2 years ago
Thanks, @lutzbickhardt! This is a good idea. The WiFi credentials are stored in the flashed image using ubjson, so it should be possible to extend this with more keys and values quite easily.
The code that creates the ubjson blob uses this struct: https://github.com/toitlang/jaguar/blob/4f711a8fac8cb8f2c7a7aeac2948bb165402ac3c/cmd/jag/commands/flash.go#L21
and it is accessed from the device here: https://github.com/toitlang/jaguar/blob/4f711a8fac8cb8f2c7a7aeac2948bb165402ac3c/src/jaguar.toit#L34 https://github.com/toitlang/jaguar/blob/4f711a8fac8cb8f2c7a7aeac2948bb165402ac3c/src/jaguar.toit#L48
hmm, I was trying to build jaguar for myself and followed the instructions ... [Ubuntu 20.04]
problem 1: when trying to build toit from jaguar/third_party/toit: make tools GOBIN="/home/lutz/jaguar/third_party/toit"/build/host/sdk/bin/ go install github.com/toitlang/tpkg/cmd/toitpkg@v0.0.0-20211126161923-c00da039da00 can't load package: package github.com/toitlang/tpkg/cmd/toitpkg@v0.0.0-20211126161923-c00da039da00: can only use path@version syntax with 'go get' make: *** [Makefile:94: build/host/sdk/bin/toitpkg] Error 1
solution 1: omit version in GOBIN="$(CURDIR)"/$(dir $@) go install github.com/toitlang/tpkg/cmd/toitpkg (20.04 only comes with golang 1.13)
problem 2: .... cd tools/toitlsp; CGO_ENABLED=1 GODEBUG=netdns=go go build -ldflags " -X main.date=2022-01-04T09:19:49Z" -tags 'netgo osusergo' -o "/home/lutz/jaguar/third_party/toit"/build/host/sdk/bin/toitlsp . (cd build/host && cmake ../.. -G Ninja -DCMAKE_BUILD_TYPE=Release) CMake Error at CMakeLists.txt:16 (cmake_minimum_required): CMake 3.19.0 or higher is required. You are running version 3.16.3
solution 2 lutz@HONOR:~/jaguar/third_party/toit$ sudo apt remove cmake lutz@HONOR:~/jaguar/third_party/toit$ snap install cmake --classic cmake 3.22.1 from Crascit✓ installed
problem 3:
make esp32
mkdir -p build/esp32/
mkdir -p build/host/
(cd build/host && cmake ../.. -G Ninja -DCMAKE_BUILD_TYPE=Release)
...
[342/342] Generating ../sdk/bin/toitvm_boot.snapshot
build/host/sdk/bin/toitc -w build/snapshot examples/hello.toit
/home/lutz/jaguar/package.lock:5:10: error: Package 'github.com/toitlang/pkg-http-1.4.1' not found
url: github.com/toitlang/pkg-http
^~~~~~~~
Compilation failed.
@lutzbickhardt: Looks like you might need to run toit.pkg install
in /home/lutz/jaguar
to fetch dependencies.
well, I updated to golang to 1.16 (not from apt but with wget), ran again according to the recently updated instructions to build toit and then continued with the instructions to build jaguar and it WORKED. I changed some text in jaguar/cmd/jag/commands/flash.go, rebuilt jag and voila! thanks for the tips!
getting more adventurous I tried to include the serial number along with the wifi credentials. There is a libusb module (https://github.com/gotmc/libusb) with some examples and a code snipped that should do the trick (https://stackoverflow.com/questions/35450288/how-to-get-the-serial-number-of-usb-device-with-golang), but only .../examples/get_sn/get_sn.go worked to a point(access denied) and the others yielded runtime errors. Since I haven't ever used go, it is probably easy to solve for others.
One other question: I have understood that jag installs a kind of wrapper around the toit-program that is uploaded to the esp32. Is there some plain language (other than source code) info, how that is done? And can you access the wrapper code from within the toit program?
@lutzbickhardt The wrapper is written in Toit and it isn't much code. Here is where we get an http request to install a new program: https://github.com/toitlang/jaguar/blob/main/src/jaguar.toit#L84.
fyi, solved the serial number thing
package commands
import ( "fmt" "os/exec" "regexp" )
func GetSerialNumber(port string) (string, error) {
//get serial number of USB connection (CP2104)
//$ ls -l /sys/class/tty/ttyUSB0
//lrwxrwxrwx 1 root root 0 Jan 6 13:27 /sys/class/tty/ttyUSB0 -> ../../devices/pci0000:00/0000:00:08.1/0000:03:00.4/usb3/3-1/3-1:1.0/ttyUSB0/tty/ttyUSB0/
ttyStr := "/sys/class/tty" + port[4:] //skip /dev/
out, := exec.Command("ls", "-l", ttyStr).Output()
match, := regexp.MatchString("usb", string(out))
if match {
re := regexp.MustCompile(usb(?P<b>\d{1})/\d{1}-(?P<p>\d{1})
)
matches := re.FindStringSubmatch(string(out))
bIndx := re.SubexpIndex("b")
pIndx := re.SubexpIndex("p")
bpStr1 := "/sys/bus/usb/devices/usb" + matches[bIndx]
bpStr2 := matches[bIndx] + "-" + matches[pIndx]
bpStr := bpStr1 + "/" + bpStr2 + "/serial"
out, _ = exec.Command("cat", bpStr).Output()
//fmt.Printf("%s -> s/n: %s\n", port, string(out))
rere := regexp.MustCompile(`\r?\n`)
outStripped := rere.ReplaceAllString(string(out), " ")
return outStripped, nil
} else {
return "", fmt.Errorf("no corresponding USB port found with ls -l /sys/class/tty/ttyUSBn")
}
}
Question: how can I access/print the s/n from a flashed pgm (that is run under the vm). Do I have to communicate with jaguar.toit through http? or is there a vm import or global or built-in keyword? like: print vm.sn
Cool stuff, @lutzbickhardt! I think the code you have for reading the config file (https://github.com/toitlang/jaguar/blob/main/src/jaguar.toit#L32) should also work from an application, so if the serial number is stored in the image_config
, it might be easy to read it also from another app.
voila! after adding import esp32 it works! image_config := {:} sn := "?s/n?" if platform == PLATFORM_FREERTOS: print "$PGM_ID accessing config ..."
image_config = esp32.image_config or {:}
print "$PGM_ID config found"
sn = image_config.get "sn" --if_absent=: sn
print "$PGM_ID s/n: $sn"
=> ... [WS_C_D] accessing config ... [WS_C_D] config found [WS_C_D] s/n: 0225F061 ...
Starting with Jaguar v1.5.2, this is now possible using:
jag run -D my.value=42 examples/hello.toit
or for installed containers:
jag container install -D broker.host=test.mosquitto.org mqtt-service examples/mqtt.toit
The -D
arguments show up as an arguments Map
to main in the programs:
main arguments:
print "arguments = $arguments
value := arguments.get "my.value"
print "my.value = $value"
Thanks for filing this issue @lutzbickhardt!
(this might impact the toit language as such not only jaguar)
Imagine you want to write (more or less) portable code for different versions of hardware (such as M5stackCore2 or M5StackBasic) with different sensors built in. Those sensors might even perform the same functions but are programmed differently. Rather than writing a separate program for each configuration one might identify the device at runtime and act accordingly (think: switch (hw) or #ifdef hw1 in c/c++).
It would thus be beneficial to "know" what particular device a program runs on. Name and ip address are configurable/change, USB serial number is fix.
(By the way: can I access ip and name in toit as supplied by flash?)
Since the USB device description is not available inside the esp32 itself (since this is handled by the CP... which can only be accessed from outside) it would be helpful to supply this when "jag flash"ing (like the wifi credentials) AND make it available from inside a toit program (or write it to EEPROM, but does toit support EEPROM?). Candidates are serial number (on a Mac /dev/ttyXXXXXX) and maybe vendor/manufacturer/product id as given by the USB device descriptor (lsusb -v in Linux).
Thinking this a little further, could we supply a "configuration key" by using "flash" (or any other means) which can be used at runtime in a toit program for such config purposes?