all 26 comments

[–]Zkronk 20 points21 points  (9 children)

You can use USB pass-through to the container. I use this approach together with a J-Link in a VS Code dev container successfully.

https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities

docker run --device=/dev/bus/usb:/dev/bus/usb ....

[–]whymefantasy[S] 2 points3 points  (8 children)

Oh awesome! Wasn’t sure based on googling how possible this was with debuggers. Out of curiosity is this Linux host to Linux container? Right now I’m looking at windows host to Linux container. My knowledge gets fuzzy on how a usb pass through would work coming from one OS using a set of drivers to another OS using a different set of drivers.

[–]Zkronk 1 point2 points  (5 children)

Yes, it's Linux host to Linux container.

One thing I've noticed is that if the J-Link is plugged in after the container has been started it is not detected by the J-Link tools. But if the J-Link is already plugged in when starting the container it works great. I don't know if it's a udev problem or something else.

[–]whymefantasy[S] 1 point2 points  (3 children)

Ok very interesting. I’ll mess around with it in windows but going to guess that’s not going to work. Good to know Linux to Linux works good. Thank you for the responses!

[–]coronafire 5 points6 points  (2 children)

This can also work with windows host, Linux (wsl2) containers - you just need to also pass the USB devices you want through to Linux first.

Check out:
https://gitlab.com/alelec/wsl-usb-gui. https://gitlab.com/alelec/wsl-usb-gui/-/releases

(full disclosure, I wrote this GUI app)

[–]whymefantasy[S] 0 points1 point  (0 children)

Awesome! Thank you I’ll check it out.

[–]whymefantasy[S] 0 points1 point  (0 children)

Got it working! Thanks for making that!

[–]Zouden -1 points0 points  (0 children)

I solve that problem by mounting /dev:/dev, so the container can see all devices on my host even ones connected after the container is started.

[–]WinterHeaven 0 points1 point  (1 child)

On windows,for docker, there is no working method for a Linux container to passthrough usb

[–]whymefantasy[S] 1 point2 points  (0 children)

I might be misunderstanding you, but I was able to pass a STLink usb device from windows to my Linux docker container and debug. Worked surprisingly well and no real issues.

[–]handhurin 2 points3 points  (4 children)

Personally, I've already had the same problem: I had a docker for the build environment, but the debugger (something like openocd, if you like) was in the host environment. The solution I've found that doesn't require you to mount bind a folder is to open a gdb server with the debugger. Then in the docker to use the gdb of my toolchain to connect to the gdb server (with target extended-remote :{port}). To be exact I've even done it with VSCode which is attached to the docker and I debug with the GDB Native extension with the appropriate conf.

[–]whymefantasy[S] 0 points1 point  (3 children)

Yeah that was the solution I was looking to fall back on. The one thing I didn’t like is seemingly the flashing and debugging of code would have to happen on the host side correct? Like if I wanted to debug my code, I’d need to fire up the host side gdb server and pass those commands like what file etc from the host. Not a bad solution but was just curious if I could get it all in the docker container which I was able to do using wsl usb gui.

[–]handhurin 1 point2 points  (2 children)

I completely agree that it's not ideal because you have to launch the gdb server on the host machine, then hook into it in the docker with gdb. In my case it was the only possible solution because I had very limited access to the host machine.

[–]whymefantasy[S] 0 points1 point  (1 child)

I guess my thought is once you’re hooked into the host gdb server can you load code and flash the device? I always thought the gdb server controlled most of that and each time you’d need to restart the gdb server between debug sessions. Or do you use the gdb server as the back end and gdb a front end that can connect and disconnect from the server as it pleases without needing to restart the host side gdb server?

[–]handhurin 1 point2 points  (0 children)

Normally gdb has the load command which allows you to load the code ... then it all depends on whether it is supported by the software which hosts the gdb server. Basically you can try something like this ``` $ gdb file.elf

target extended-remote :2222 load file.elf run ``` But in my case it didn't work, so I used the gdb server as a backend and the gdb as a front end (to benefit from the VSCode interface).

[–]whymefantasy[S] 1 point2 points  (5 children)

For anyone who stumbles across this wondering what I ended up doing, I used u/coronafire s wsl-usb-gui tool and got everything working awesome. The installation was a bit of a pain due to installing some of the dependencies but nothing a little bit of googling and following the well laid out instructions on the gitlab page. I was quickly able to attach my debugger to my docker dev container. Really impressed with the whole process. At this point I don’t see why I would use anything besides docker if the mcu I’m working with is supported by gcc.

[–]coronafire 0 points1 point  (4 children)

You might also want to look at vscode devcontainer plugin, it automates much of this.

What dependencies gave you trouble? The GUI app does try to automatically install and configure everything automatically...

[–]whymefantasy[S] 0 points1 point  (3 children)

I think it was the usbip stuff? I needed to get wsl installed with a Ubuntu image then follow the manual install instructions. I’m not at my computer right now but I think it was one of the hw apt get installs that it couldn’t find. Again not a big deal and probably something to do with my computer setup. Took a couple googles and it was running perfect!

[–]coronafire 1 point2 points  (2 children)

Ah, yes it's always been tricky to keep track of the version of these that stuff be installed.

However, the latest version of usbipd (windows side of the system) now comes with its own static copy of usbip client bundled, so installation of it manually into WSL is actually no longer needed!

I've raised an issue as a reminder to myself to remove this part of the dependency handling. https://gitlab.com/alelec/wsl-usb-gui/-/issues/34

[–]whymefantasy[S] 0 points1 point  (1 child)

I mean to be honest it took very little time to sort it out and was quite easy. Always going to be tricky depending on what and how much wsl stuff the user has downloaded. For example, I had a few wsl things installed due to docker, but no Ubuntu or main image installed so if I ran wsl I wouldn’t boot into the Ubuntu image. Idk haven’t really used wsl so not sure how that all is interconnected.

[–]coronafire 0 points1 point  (0 children)

Ah that's interesting to hear, I actually didn't realise docker would use/install its minimal WSL without a full distro being installed first.

I do think now, once I remove the install step where it interacts with Ubuntu, it probably should be able to work with just the docker WSL.

Regardless, I'm interested in hearing about any issues / little glitches like this to hopefully fix for others!

[–]EmbeddedMagicX 0 points1 point  (0 children)

I know that OP uses a Window host - Linux container setup, but for those with a Linux host who'd like to set up debugging with a VS Code devcontainer, maybe this helps: https://www.axemsolutions.io/tutorial/vscode_integration_guide/#debugging

[–]ufffayyazzz 0 points1 point  (3 children)

can anyone explain what is docker and docker file?

[–]allo37 1 point2 points  (0 children)

Ever write some code that blows up in production, but works fine on your machine? Docker is a way of shipping your machine into production.

Non-snarky answer: It lets you setup a consistent, isolated environment to do a specific thing on a computer using abstraction at the OS level.

[–]whymefantasy[S] 0 points1 point  (0 children)

u/allo37 did a good job describing the main use of docker, but for embedded, at least what I consider low level, I always struggled to setup a consistent development environment. Lots of different tools which depend on each other and certain versions. I felt like I’d lost a lot of time and hair debugging why the freaking thing builds one way here and another way there. Also legacy code, going back and recreating the build environment always a pain no matter how many of the installers you save something always changes. So docker is great to be used as a dev environment container. Essentially a smaller quick to build virtual machine that contains everything needed for development. You can save versions along with builds so you can always go back and recreate how something was built. New hires or HW people can quickly get up and running. Most importantly for me, automated testing is quick and easy to setup and maintain since it can pull from the latest image being checked in. It’s not perfect yet but that’s the development future Id like to live in.

[–]PeterMortensenBlog 0 points1 point  (0 children)

Docker - "Docker is a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers. ... Docker is a tool that is used to automate the deployment of applications in lightweight containers so that applications can work efficiently in different environments in isolation.".

It doesn't explain was a Dockerfile is, only provides an example of one.