diff --git a/Firmware/Makefile b/Firmware/Makefile index 97ffbad2..65eed722 100644 --- a/Firmware/Makefile +++ b/Firmware/Makefile @@ -31,13 +31,24 @@ all: @tup --quiet --no-environ-check @$(PY_CMD) interface_generator_stub.py --definitions odrive-interface.yaml --template ../tools/enums_template.j2 --output ../tools/odrive/enums.py -fibre: - (cd fibre-cpp && tup --no-environ-check) - ! ls fibre-cpp/*.so 2>&1 > /dev/null || cp fibre-cpp/build-local/*.so ../tools/odrive/pyfibre/fibre/ - ! ls fibre-cpp/*.dylib 2>&1 > /dev/null || cp fibre-cpp/build-local/*.dylib ../tools/odrive/pyfibre/fibre/ - ! ls fibre-cpp/*.dll 2>&1 > /dev/null || cp fibre-cpp/build-local/*.dll ../tools/odrive/pyfibre/fibre/ - #(cd fibre-cpp && tup --no-environ-check build-linux-armhf) - #cp fibre-cpp/build-linux-armhf/libfibre-linux-armhf.so ../tools/odrive/pyfibre/fibre/ +# Copy libfibre files to odrivetool if they were built + @ ! compgen -G "fibre-cpp/build/libfibre-*.so" > /dev/null || cp fibre-cpp/build/libfibre-*.so ../tools/odrive/pyfibre/fibre/ + @ ! compgen -G "fibre-cpp/build/libfibre-*.dylib" > /dev/null || cp fibre-cpp/build/libfibre-*.dylib ../tools/odrive/pyfibre/fibre/ + @ ! compgen -G "fibre-cpp/build/libfibre-*.dll" > /dev/null || cp fibre-cpp/build/libfibre-*.dll ../tools/odrive/pyfibre/fibre/ + +libfibre-linux-armhf: + docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/fibre-linux-armhf-build:/build/build -w /build fibre-compiler configs/linux-armhf.config + cp /tmp/fibre-linux-armhf-build/libfibre-*.so ../tools/odrive/pyfibre/fibre/ + +libfibre-all: + docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/linux-amd64.config + cp /tmp/libfibre-build/libfibre-linux-amd64.so ../tools/odrive/pyfibre/fibre/ + docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/linux-armhf.config + cp /tmp/libfibre-build/libfibre-linux-armhf.so ../tools/odrive/pyfibre/fibre/ + docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/macos-x86.config + cp /tmp/libfibre-build/libfibre-macos-x86.dylib ../tools/odrive/pyfibre/fibre/ + docker run -it -v "`pwd`/fibre-cpp":/build -v /tmp/libfibre-build:/build/build -w /build fibre-compiler configs/windows-amd64.config + cp /tmp/libfibre-build/libfibre-windows-amd64.dll ../tools/odrive/pyfibre/fibre/ clean: -rm -fR .dep $(BUILD_DIR) diff --git a/Firmware/Tuprules.lua b/Firmware/Tuprules.lua index 0cc74918..11c980d2 100644 --- a/Firmware/Tuprules.lua +++ b/Firmware/Tuprules.lua @@ -1,4 +1,4 @@ -- Prevent tup from running `Firmware/fibre-cpp/Tupfile.lua` when we run it in -- the `Firmware` folder. -no_libfibre = true +no_libfibre = tup.getconfig("BUILD_LIBFIBRE") != "true" diff --git a/docs/developer-guide.md b/docs/developer-guide.md index 8e9aa14e..9e88156d 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -284,11 +284,14 @@ On Ubuntu 18.04, prerequisites are: `ruby ruby-dev zlib1g-dev`. ## Modifying libfibre -If you need to modify libfibre run `make fibre` in the `Firmware` directory. If -you now run odrivetool from the repository it should use the new libfibre binary. +If you need to modify libfibre add `CONFIG_BUILD_LIBFIBRE=true` to your tup.config and rerun `make`. After this you can start `odrivetool` (on your local PC) and it will use the updated libfibre. + +To cross-compile libfibre for the Raspberry Pi, run `make libfibre-linux-armhf` or `make libfibre-all`. This will require a docker container. See [fibre-cpp readme](../Firmware/fibre-cpp/README.md) for details. + +docker run -it -v "$(pwd)":/build -v /tmp/build:/build/build -w /build fibre-compiler configs/linux-armhf.config If you're satisfied with the changes don't forget to generate binaries for all -supported systems. See [Releases](#releases) for more info. +supported systems using `make libfibre-all`. ## Releases @@ -297,7 +300,7 @@ We use GitHub Releases to provide firmware releases. 1. Cut off the changelog to reflect the new release 2. Merge the release candidate into master. 3. Push a (lightweight) tag to the master branch. Follow the existing naming convention. -4. If you changed something in libfibre, regenerate the binaries using `Firmware/fibre-cpp/compile_for_all_platforms.sh` and then copy all resulting `*.so`, `*.dll` and `*.dylib` files to `tools/odrive/pyfibre/fibre/`. +4. If you changed something in libfibre, regenerate the binaries using `make libfibre-all`. See [Modifying libfibre](#modifying-libfibre) for details. 5. Push the python tools to PyPI (see setup.py for details). 6. Edit the release on GitHub to add a title and description (copy&paste from changelog). diff --git a/tools/fibre-tools/fibre-shell b/tools/fibre-tools/fibre-shell index b6765452..19559165 100755 --- a/tools/fibre-tools/fibre-shell +++ b/tools/fibre-tools/fibre-shell @@ -45,7 +45,6 @@ parser.set_defaults(path="usb,tcp:localhost:9910") args = parser.parse_args() logger = Logger(verbose=args.verbose) -app_shutdown_token = Event() def print_banner(): pass @@ -54,4 +53,4 @@ def print_help(args, have_devices): pass import fibre -fibre.launch_shell(args, {}, print_banner, print_help, logger, app_shutdown_token) +fibre.launch_shell(args, {}, print_banner, print_help, logger) diff --git a/tools/odrive/__init__.py b/tools/odrive/__init__.py index a8841c33..0746ab39 100644 --- a/tools/odrive/__init__.py +++ b/tools/odrive/__init__.py @@ -14,41 +14,42 @@ __version__ = get_version_str() del get_version_str from .utils import get_serial_number_str +import threading default_search_path = 'usb:idVendor=0x1209,idProduct=0x0D32,bInterfaceClass=0,bInterfaceSubClass=1,bInterfaceProtocol=0' def find_any(path=default_search_path, serial_number=None, search_cancellation_token=None, channel_termination_token=None, - timeout=None, logger=fibre.Logger(verbose=False), find_multiple=False): + timeout=None, logger=fibre.Logger(verbose=False)): """ Blocks until the first matching ODrive object is connected and then returns that object """ + result = [] + done_signal = fibre.Event(search_cancellation_token) - def did_discover_object(obj): + channel_termination_token = fibre.Event(channel_termination_token) + + async def discovered_object(obj): + if not (serial_number is None) and ((await get_serial_number_str(obj)) != serial_number): + return # ignore this device + + obj._on_lost.add_done_callback(lambda x: channel_termination_token.set()) result.append(obj) - if find_multiple: - if len(result) >= int(find_multiple): - done_signal.set() - else: - done_signal.set() + done_signal.set() - async def obj_filter(obj): - return (serial_number is None or - (await get_serial_number_str(obj)) == serial_number) - - fibre.start_discovery(path, obj_filter, did_discover_object, - done_signal, channel_termination_token, logger) + def domain_thread(): + with fibre.Domain(path) as domain: + discovery = domain.run_discovery(discovered_object) + channel_termination_token.wait() + discovery.stop() + + threading.Thread(target=domain_thread).start() try: done_signal.wait(timeout=timeout) - except TimeoutError: - if not find_multiple: - return None - finally: - done_signal.set() # terminate find_all + except: + channel_termination_token.set() + raise - if find_multiple: - return result - else: - return result[0] if len(result) > 0 else None + return result[0] diff --git a/tools/odrive/pyfibre/fibre/libfibre-linux-amd64.so b/tools/odrive/pyfibre/fibre/libfibre-linux-amd64.so old mode 100644 new mode 100755 index 6ad60c5c..9b5b113a --- a/tools/odrive/pyfibre/fibre/libfibre-linux-amd64.so +++ b/tools/odrive/pyfibre/fibre/libfibre-linux-amd64.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6286122181cecebe86d15eb373fec0f8dd4820338162d5449a7b58d0f2f8f80 +oid sha256:12ed07bd036b1934373c6b28faa7f4d56a30113d02c1233b1889e16f74a977d6 size 748904 diff --git a/tools/odrive/pyfibre/fibre/libfibre-linux-armhf.so b/tools/odrive/pyfibre/fibre/libfibre-linux-armhf.so index 2f3e9eb2..8583dd16 100755 --- a/tools/odrive/pyfibre/fibre/libfibre-linux-armhf.so +++ b/tools/odrive/pyfibre/fibre/libfibre-linux-armhf.so @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:528c680e0417085e7187a231c05fc200ff03b9d903cb8418fbe63e9fbd66ac3d -size 750616 +oid sha256:9b0caf83a5d0247cc7001d92994d1a73feb5ced9313beafd67ea300046d2ff6e +size 778848 diff --git a/tools/odrive/pyfibre/fibre/libfibre-macos-x86.dylib b/tools/odrive/pyfibre/fibre/libfibre-macos-x86.dylib index 2af09dec..0434647e 100644 --- a/tools/odrive/pyfibre/fibre/libfibre-macos-x86.dylib +++ b/tools/odrive/pyfibre/fibre/libfibre-macos-x86.dylib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf5105038e2787b8e3e05600a8d303a24dae6052364201c6ecb3233e3a947ddb -size 657528 +oid sha256:85a376e0d466a2c30e09d61decbcc02098b347abc5fa6147b4609b6380d81ee8 +size 662308 diff --git a/tools/odrive/pyfibre/fibre/libfibre-windows-amd64.dll b/tools/odrive/pyfibre/fibre/libfibre-windows-amd64.dll index 868fc1e2..2e1b9b41 100755 --- a/tools/odrive/pyfibre/fibre/libfibre-windows-amd64.dll +++ b/tools/odrive/pyfibre/fibre/libfibre-windows-amd64.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:727e24428ad48184b891a57e27763e3cd9be8e98a38befc5279d3fb11f11566d -size 1239566 +oid sha256:6257e37d0729bcbf2cb1e08cbc593a151c4e029f8623fe81ce995a978378b05f +size 1229838 diff --git a/tools/odrive/shell.py b/tools/odrive/shell.py index b979d904..d6f6ce7d 100644 --- a/tools/odrive/shell.py +++ b/tools/odrive/shell.py @@ -53,7 +53,7 @@ def benchmark(odrv): fibre.libfibre.libfibre.loop.call_soon_threadsafe(lambda: asyncio.ensure_future(measure_async())) -def launch_shell(args, logger, app_shutdown_token): +def launch_shell(args, logger): """ Launches an interactive python or IPython command line interface. @@ -79,12 +79,13 @@ def launch_shell(args, logger, app_shutdown_token): # Expose all enums from odrive.enums interactive_variables.update({k: v for (k, v) in odrive.enums.__dict__.items() if not k.startswith("_")}) - async def obj_filter(obj): - return (args.serial_number is None or - (await odrive.utils.get_serial_number_str(obj)) == args.serial_number) + async def mount(obj): + serial_number_str = await odrive.utils.get_serial_number_str(obj) + if ((not args.serial_number is None) and (serial_number_str != args.serial_number)): + return None # reject this object + return ("ODrive " + serial_number_str, "odrv") - fibre.launch_shell(args, obj_filter, + fibre.launch_shell(args, mount, interactive_variables, print_banner, print_help, - logger, app_shutdown_token, - branding_short="odrv", branding_long="ODrive") + logger) diff --git a/tools/odrivetool b/tools/odrivetool index d6a78148..5d0e9776 100755 --- a/tools/odrivetool +++ b/tools/odrivetool @@ -140,7 +140,7 @@ try: print(" or better yet, submit a pull request to fix it.") print("") import odrive.shell - odrive.shell.launch_shell(args, logger, app_shutdown_token) + odrive.shell.launch_shell(args, logger) elif args.command == 'dfu': print_version()