CDC ACM USB Serial Device doesn't show up on ls /dev/tty*, can't access it

Hello,

I’m trying to access a VESC motor controller over serial comm plugged into my Jetson TX2 via USB. However, when I run ls /dev/tty* it should show up as ACM0 but nothing is detected. However it does show up when I run lsusb, so it is detected by the system.

I also ran a command which monitors system diagnostics and this is what I got:
[ 942.718768] usb 1-2.1.4: USB disconnect, device number 7
[ 949.097375] usb 1-2.1.4: new full-speed USB device number 9 using tegra-xusb
[ 949.118797] usb 1-2.1.4: New USB device found, idVendor=0483, idProduct=5740
[ 949.118804] usb 1-2.1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 949.118809] usb 1-2.1.4: Product: ChibiOS/RT Virtual COM Port
[ 949.118813] usb 1-2.1.4: Manufacturer: STMicroelectronics
[ 949.118817] usb 1-2.1.4: SerialNumber: 301

I also tried installing a ttyACM Module, as per this guide but it’s for an older kernel version (4.4.38).

Any suggestions?

Thanks.

Hi,
You may need to enable related configs and rebuild kernel. Please refer to

What do you see on your running system from “zcat /proc/config.gz | grep ACM” (these are various ACM features the kernel was or was not configured for)?

Actual procedure for building a 4.9 kernel shouldn’t be much different than building for a 4.4 kernel. The problem is that the article you saw has custom scripts for the older kernel. Learning to build a kernel module without a script seems complicated at first, but in reality is not as bad as it looks, and is worth knowing. The official documentation for your particular L4T release gives that information, but you can also ask here since some of the details may not always be clear.

Official documents explain cross compile of a kernel from a host PC (and kernel modules), but you can do a native compile from the Jetson and not worry about cross compilers.

This is also for an older kernel (to compile natively on a Jetson), but details shouldn’t be much different:
https://forums.developer.nvidia.com/t/tx2i-wifi-support/63839/2
…however, the tag used for “source_sync.sh” will need to be adjusted for your release. If your release is R32.3.1 (the latest release, verify with “head -n 1 /etc/nv_tegra_release”), then downloading full kernel source using source_sync.sh would use tag “tegra-l4t-r32.3.1”.

You only need a module, but I always advise that you try building a full kernel once just for sanity checking (the configuration matters, and you are more likely to find out about bad configurations from a full kernel build…but only install the module with a file copy, don’t bother installing the full kernel).

Note: When the module is inserted, and if the hardware is detected, then this will create the file in “/dev/”. Sometimes the expected file name is changed by udev, so if the device special file is missing, you might want to insmod while monitoring “dmesg --follow” to see if a rename has occurred.

Thanks for the help @linuxdev.

When I runzcat /proc/config.gz | grep ACM I get:
# CONFIG_FB_MACMODES is not set
CONFIG_USB_ACM=m
CONFIG_USB_F_ACM=y
CONFIG_USB_CONFIGFS_ACM=y

I proceeded to rebuild the 4.9 kernel, and found another guide from Jetsonhacks. I specified my L4t target (32.2.0) and ran the script. It asked if I wanted to use a certain realtek wifi related driver/card (can’t get the specific line anyone), I tried to indicate Yes but it wouldn’t take it so I put M.

Then I ran makeKernel.shbut got these errors:
Makefile:1104: recipe for target 'drivers' failed
make: *** [drivers] Error 2

real	0m26.202s
user	0m54.240s
sys	0m35.948s

And then this error:

drivers/net/wireless/realtek/rtl8814au/built-in.o: In function `survey_done_set_ch_bw':
rtw_mp.c:(.text+0x3823c): multiple definition of `survey_done_set_ch_bw'
drivers/net/wireless/realtek/rtl8812au/built-in.o:rtw_mp.c:(.text+0x37630): first defined here
drivers/net/wireless/realtek/rtl8814au/built-in.o: In function `phydm_clear_kfree_to_rf_8198f':
rtw_mp.c:(.text+0x1162c4): multiple definition of `phydm_clear_kfree_to_rf_8198f'
drivers/net/wireless/realtek/rtl8812au/built-in.o:rtw_mp.c:(.text+0x10adc8): first defined here
drivers/net/wireless/realtek/rtl8814au/built-in.o: In function `issue_probereq_p2p':
rtw_mp.c:(.text+0x292d0): multiple definition of `issue_probereq_p2p'
drivers/net/wireless/realtek/rtl8812au/built-in.o:rtw_mp.c:(.text+0x282cc): first defined here
scripts/Makefile.build:509: recipe for target 'drivers/net/wireless/built-in.o' failed
make[3]: *** [drivers/net/wireless/built-in.o] Error 1
scripts/Makefile.build:649: recipe for target 'drivers/net/wireless' failed
make[2]: *** [drivers/net/wireless] Error 2
scripts/Makefile.build:649: recipe for target 'drivers/net' failed
make[1]: *** [drivers/net] Error 2
Makefile:1104: recipe for target 'drivers' failed
make: *** [drivers] Error 2
Make did not successfully build
Please fix issues and retry build

So I went to /lib/modules/4.9.140-tegra/kernel/drivers/net/wireless/realtekbut there’s multiple libraries rtl818x rtl8xxxu rtlwifiand in each is .ko kernel files. So I’m not sure what to do.

Any suggestions?
Thanks again.

That script is for the R28.x series, you’re in R32.x. I’m not sure what the differences would be, but unless a script is specifically for your release expect that there may be errors.

FYI, the earlier content shows you don’t need a new kernel:

When you run the command “uname -r”, do you see “4.9.140-tegra”? Modules are searched for at “/lib/modules/$(uname -r)/kernel/”, and if you’ve modified the kernel Image, then this has to be set correctly through CONFIG_LOCALVERSION="-tegra". Without this anything in module format will fail. Regardless, it looks like the modules are already there and not in need of creation.

Note that Realtek (RTL) drivers are used for the wired ethernet, and are rather commonly used in Linux, and so it doesn’t hurt to just leave these in place. I am suggesting you do not need to build a kernel, but if you did, then you’d start with either a “_defconfig” or “/proc/config.gz” (after editing CONFIG_LOCALVERSION), and this would already have both the ACM and RTL drivers selected (sometimes in integrated format, and in some cases in module format).

The drivers for these two features are integrated and thus there will not be a module file:

(and thus you cannot use insmod…these are always present)

The key to solving this is knowing which driver should handle the particular USB serial UART. If that driver is present, then upon plugin of the USB connector the broadcast of what was plugged in should resort into the driver taking ownership…and this is what triggers the existence of the “/dev/ttyACM#” file. Monitoring “dmesg --follow” should show a plugin event, and in turn this should log whenever a driver takes ownership based on that plugin event.

Can I also verify the USB half of the cable is connected to the Jetson and not the other device? The non-USB side does not need an ACM driver…it connects to other hardware which has its own independent driver.

Thanks @linuxdev.

Running “uname -r”, does give me “4.9.140-tegra".

This is what I got when I ran dmesg --follow:

[  486.586535] usb 1-2.1.4: new full-speed USB device number 7 using tegra-xusb
[  486.607763] usb 1-2.1.4: New USB device found, idVendor=0483, idProduct=5740
[  486.607767] usb 1-2.1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  486.607770] usb 1-2.1.4: Product: ChibiOS/RT Virtual COM Port
[  486.607772] usb 1-2.1.4: Manufacturer: STMicroelectronics
[  486.607775] usb 1-2.1.4: SerialNumber: 301
[  487.573349] nvgpu: 17000000.gp10b             railgate_enable_store:283  [INFO]  railgate is disabled.

Looks like some kind of COM port is detected with “ChibiOS/RT Virtual COM Port”. But it still doesn’t show up when I run ls /dev/tty*.

And yes, one half is plugged into the Jetson via powered usb 3 hub, and the other mini usb side goes to my VESC motor controller.

Also just to verify, when I plug the device into my laptop running Ubuntu ACM0 shows up fine in /dev/tty.

From this it seems USB is working as expected. Some comments on USB manufacturing before I say what seems to be the issue…

Each USB device has a manufacturer/vendor ID (yours is 0x0483). Within that manufacturer are a number of device IDs possible (yours is 0x5740). This is what hotplug broadcasts upon plugin, and the part which drivers listen for.

A given USB chipset is often used generically, e.g., a manufacturer of a given brand can use a USB chip by FTDI and the device will identify with this, and the generic driver out in the wild will know it can attach to this device. There is no need for any adjustments, and this will “just work” right out of the box.

On the other hand, sometimes a custom device with an otherwise generic FTDI chipset (I use this because it is by far the most common generic serial UART and most everything has the driver for this out of the box) could have new IDs programmed in to differentiate it from a mass market product (the hardware and software does not change, but naming would not mention the generic chipset)…even if this is the same FTDI chipset and the same driver works for it, then the change in IDs means the drivers won’t realize they can succeed and will never attach.

When a company has paid USB.org to register themselves, they have a registered vendor ID (NVIDIA’s is 0x0955). Individual devices can be registered as well, but this is not mandatory. See http://www.linux-usb.org/usb.ids.

I am not familiar with the particular device, but what a manufacture with new IDs will often do is just create a udev entry to map its custom device to a generic driver, and perhaps provide a custom “/dev/” file name (or a non-custom “/dev/” file name). “udev” has the advantage that an end user can install the rule if the manufacturer provides this, and this will more or less be host side hardware independent without any modification of device tree or kernel.

Sometimes such devices truly are custom, and there are no generic drivers. Such devices mandate a driver directly from the manufacturer, or some new configuration in a kernel module. I do not know which type you have…generic with a new ID of an old chipset, or truly custom. If you can find out what driver this company lists for this device, then you can go from there.

Looking at the registry for idVendor=0483 and idProduct=5740, we first go to the STMicroelectronics block, and then look for device 0483. No such device is listed, and so we would need to know from STMicroelectronics what driver is used. Perhaps the driver is nothing more than a udev entry to map to FTDI or CDM chipsets. Perhaps the driver is only a udev entry to map to a generic driver. Perhaps the driver is available in source code and needs to be compiled against your current kernel. Perhaps the driver is proprietary and available only in binary format. Whatever you can find out the Linux driver or the chipset would help.

Thanks @linuxdev

I’m a bit confused on where I should look for these drivers. However I did find this guide for setting up the VESC dev environment, I followed it up to the part where they plug in a stlink v2 programmer. Commands ran successfully but the device still wouldn’t show up as a COM port.

Also, if it helps, here is a link to the VESC I purchased.

Any suggestions? Thanks again

The driver is probably just a udev entry and not really a driver (a pointer to tell the system that this custom name is really just some other driver name). This is usually supplied by the manufacturer, and I do not have one of these boards, but here are some notes from that URL…

This URL installs “libudev-dev”, which is support for creating udev modifications. This might be for other uses, but this might also be for creating a custom udev entry. Technically you won’t need this to add a udev entry, but something else might find this useful.

A new repo (target for “apt” to search for packages) was added in that URL, and I’m not sure what this makes available, but possibly some packages won’t be found without this repo. On the other hand, this is all on the host PC side, and that URL is likely assuming an ordinary x86_64/amd64 host PC, not an arm64/aarch64 PC. I don’t know how much of what is there applies, but even if you install this on a regular PC it might help for what ends up being copied to the Jetson.

This part looks very important:

wget vedder.se/Temp/49-stlinkv2.rules
sudo mv 49-stlinkv2.rules /etc/udev/rules.d/
sudo udevadm trigger

(the trigger is not necessary if you reboot)
If you go to a web browser you can see the content, or you can just run the wget line from that URL to directly download the file:
vedder.se/Temp/49-stlinkv2.rules
this is a udev rule and is universally the same thing on all architectures…this will work directly on a Jetson and will also work on a desktop PC.

For reference, this is what I see, but just use wget if you can:

# stm32 discovery boards, with onboard st/linkv2
# ie, STM32L, STM32F4.
# STM32VL has st/linkv1, which is quite different

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", \
    MODE:="0666", \
    SYMLINK+="stlinkv2_%n"

# If you share your linux system with other users, or just don't like the
# idea of write permission for everybody, you can replace MODE:="0666" with
# OWNER:="yourusername" to create the device owned by you, or with
# GROUP:="somegroupname" and mange access using standard unix groups.

The way udev works is that there are a number of entries which are for default system setup in /lib/udev/rules.d. In cases where custom setup is to be added or existing udev is to be modified, this goes under “/etc/udev/rules.d/” and overrides or appends to the “/lib” content. When a file there is of the same name as one in the system location under “/lib/udev/rules.d/”, then the custom file in “/etc” takes over (which is what the URL instructions do). Once the “/etc” version is deleted the modification goes away and udev goes back to using the original default (or doing nothing at all if the file name did not previously exist).

Creating this file with the content of “vedder.se/Temp/49-stlinkv2.rules”, named 49-stlinkv2.rules", will very likely give you the “/dev” entry upon boot. If not, then you might still need some of the other content from that URL, but the key to continuing is this “49-stlinkv2.rules” entry in “/etc/udev/rules.d/”. Without this rule drivers won’t be found (it won’t do much if the driver isn’t present). Once this is set up, then if the device still does not work, see what the “dmesg --follow” logs show…something will have changed.

Note: That URL shows other steps, e.g., firmware install. Firmware and other steps should work once the udev entry is there.

Thanks again for all the help @linuxdev. I followed that portion of the guide until he connects the stlink programmer and runs make upload. Running it gives this error (but I shouldn’t need the stlink programmer):

openocd -f board/stm32f4discovery.cfg -c "reset_config trst_only combined" -c "program build/BLDC_4_ChibiOS.elf verify reset exit" # For openocd 0.9
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 2000 kHz
adapter_nsrst_delay: 100
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
trst_only combined trst_push_pull
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : clock speed 1800 kHz
Error: open failed
in procedure 'program' 
in procedure 'init' called at file "embedded:startup.tcl", line 506
in procedure 'ocd_bouncer'
** OpenOCD init failed **
shutdown command invoked

Makefile:289: recipe for target 'upload' failed
make: *** [upload] Error 1

I also changed the firmware version for 4.12. Still no success, and “dmesg --follow” looks the same except for some “usb_suspend” logs.

[ 3075.195495] usb 1-2.1.1: new full-speed USB device number 9 using tegra-xusb
[ 3075.216765] usb 1-2.1.1: New USB device found, idVendor=0483, idProduct=5740
[ 3075.216769] usb 1-2.1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3075.216772] usb 1-2.1.1: Product: ChibiOS/RT Virtual COM Port
[ 3075.216774] usb 1-2.1.1: Manufacturer: STMicroelectronics
[ 3075.216776] usb 1-2.1.1: SerialNumber: 301
[ 3448.043674] usb 2-1.1.4: usb_suspend_both: status 0
[ 3448.083657] usb 2-1.1: usb_suspend_both: status 0
[ 3448.143663] usb 2-1: usb_suspend_both: status 0
[ 3448.143835] usb usb2: usb_suspend_both: status 0

It might also be worth mentioning that I’m using this guide from Jetsonhacks to setup the MIT RACECAR software. I’m aware that the guide is meant for l4t 28.1 but it seems to be ok on l4t 32 with some slight changes.

The guide also link to this Github repo which has similar instructions for the VESC to the previous one on vesc-project.com. However it mentions & links building and flashing a bootloader, but provides no instructions on how to do it.

Also in the root directory I noticed there’s 2 vesc firmware directories, “vesc_firmware” & “vesc-firmware”. Vesc_firmware is the new one I’ve been working on with the scripts. Vesc-firmware was probably installed from the racecar guide, but doesn’t have a conf_general.h file. This probably should be causing the problem though.

These issues are just really confusing because the COM port shows up fine on my Ubuntu laptop.

If you are using OpenOCD, then that software is oriented towards JTAG debugging. Any kind of JTAG debugger (or user of OpenOCD) can take a lot of setup, but I see your device listed as basically a motor speed control. Can you tell me more about how or why OpenOCD is involved? If this is only for programming the chip, then I can understand this since it is useful for programming embedded memory, but it wouldn’t be the Jetson which is failing for that if the “/dev” file exists. The only thing the Jetson can do is to create a “/dev” file for the serial UART.

I should mention that there are people here who have set up that JetsonHacks.com project, but I have not. However, I see the instructions are for an R28.x series L4T, not R32.x. As I recall, the ttyACM was missing (as a default configuration, not really missing in any permanent way), and people used to require building the ACM driver for that UART to work.

About that UART: Looking at this line of the udev entry:

SYMLINK+="stlinkv2_%n"

…it appears that somewhere in “/dev/” you would have a file named something like “stlinkv2_#”, where the “#” is a number. Do you see this from the following command?

find /dev -name 'stlinkv2*'

That file in “/dev” should show up after plugin, and should go away after unplug of the device. If that file is present, then everything else which follows is for that project rather than the Jetson side (the part which is dependent upon the Jetson is loading the driver and associating it with the USB device, with the side effect of creating the “/dev” file).

I appreciate the help @linuxdev.

To be honest I’m not really familiar with OpenOCD, and have never had to deal with it when configuring vesc’s before. But I would assume it’s just for programming the chip.

When I run find /dev -name 'stlinkv2*' nothing shows up. However something stlinkv2 related does show up in etc/udev/rules.d. These are the files:

acrt@acrt-racecar:/etc/udev/rules.d$ ls
10-racecar.rules            99-nv-l4t-usb-device-mode.rules
49-stlinkv2.rules           99-nv-wifibt.rules
90-alsa-asound-tegra.rules  99-slabs.rules
91-xorg-conf-tegra.rules    99-tegra-devices.rules
92-hdmi-audio-tegra.rules   99-tegra-mmc-ra.rules

I found this directory in this prior vesc guide which we looked at:

wget vedder.se/Temp/49-stlinkv2.rules
sudo mv 49-stlinkv2.rules /etc/udev/rules.d/
sudo udevadm trigger

Do you think just running a fresh OS reinstall could help at all? Just wondering why this issue is happening on this specific device since many MIT RACECARs with same hardware have been setup, maybe something to do with the OS version and compatibility?

Thanks again.

Looking closer at the udev file, it appears the reason no stlink “/dev” file is created is because it is for a different product from stlink. Note that you have product ID 5740 (from lsusb), but the udev file, although for the same manufacturer, is for a different model: Product ID 3748 (you have a 5740, a serial UART, the udev is for a 3748, the ST-LINK/V2.1).

This is a longshot, but if the UART is an ACM, then you could edit this file. I’d rename it first to: " 49-stlink_ttyacm.rules" for clarity. Then I would edit the file to this, and if the UART is ACM, then it will work upon reboot:

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", \
    MODE:="0666", \
    SYMLINK+="ttyACM%n"

When this is in place, find out if you have anything from “ls /dev/ttyACM*”. If you do, then at least the UART part will probably work. If you see error messages in “dmesg --follow” as you attempt to use this, then it might be that the device isn’t ACM.

Awesome! It shows up now as ACM1 in “ls /dev/ttyACM*”. However, unfortunately it looks like I have another problem. When I launch the BLDC tool to configure the VESC as per this guide “ttyACM1” doesn’t show up as an available serial port which I can connect too.

However I found 2 error messages which may offer a hint:
Makefile:447: recipe for target '.obj/qserialport_unix.o' failedmake[2]: *** [.obj/qserialport_unix.o] Error 1make[2]: Leaving directory '/home/acrt/installBLDCTool/qtserialport/qtserialport-build/src/serialport'Makefile:56: recipe for target 'sub-serialport-install_subtargets' failedmake[1]: *** [sub-serialport-install_subtargets] Error 2make[1]: Leaving directory '/home/acrt/installBLDCTool/qtserialport/qtserialport-build/src'Makefile:58: recipe for target 'sub-src-install_subtargets' failedmake: *** [sub-src-install_subtargets] Error 2

This was in the config.log file in /installBLDCTool/qtserialport/qtserialport-build:

executing config test ntddmodm
cd /home/acrt/installBLDCTool/qtserialport/qtserialport-build/config.tests/ntddm$
cd /home/acrt/installBLDCTool/qtserialport/qtserialport-build/config.tests/ntddm$
g++ -c -g -O2 -fdebug-prefix-map=/build/qtbase-opensource-src-3vxKks/qtbase-open$
/home/acrt/installBLDCTool/qtserialport/config.tests/ntddmodm/main.cpp:34:10: fa$
>  #include <windows.h>
>           ^~~~~~~~~~~
> compilation terminated.
> Makefile:289: recipe for target '.obj/main.o' failed
> make: *** [.obj/main.o] Error 1
test ntddmodm FAILED

Here is the qt serial git hub repo if it helps. Maybe this has something to do with the software meant for L4T 28.1 but I’m not sure specifically how it would affect it.

Thanks again!

Let’s see what is going on with this first since most communications with the device will depend on it:

When you run “ls -l /dev/ttyACM*”, what do you see?

We previously identified this as idVendor 0483, and idProduct 5740. What do you see from the verbose lsusb version of this:

sudo lsusb -d 0483:5740

Just to see if this is responding as a serial UART, what do you see from:

sudo setserial -a /dev/ttyACM1

(if you lack “setserial”, then “sudo apt-get install setserial”)

I am not familiar with the software, but many older serial programs only consider devices named as “/dev/ttyS#” format, which is an unfortunate assumption. As an example of dealing with this, I use gtkterm a lot. When naming devices with other naming conventions I have to either explicitly state the oddball name on command line, or else go into a “defaults” config type file and name this alternate name through editing of the file. I have no idea what command line you are using, and so I have no idea of what possibilities there are for explicitly naming on start-up, or in a config file. Some of the previous questions I’ve just asked will at least narrow down if the device is doing as expected.

I also do not know which software you are compiling, but I see something which I have to wonder about:

There are many non-Windows programs using a file “windows.h”, but there are also many non-Linux programs to build on Windows which do expect “windows.h”. QT is certainly cross platform, and could very well use this file name even for non-Windows builds. Or this could simply be coincidence and this has nothing to do with the failure. Regardless, I think it is necessary to first find out if your ttyACM is valid since this was a hack of a udev file and we do not yet know if that really “solved” the tty problem.

Running ls -l /dev/ttyACM*gives:
lrwxrwxrwx 1 root root 15 Apr 11 23:00 /dev/ttyACM1 -> bus/usb/001/004

sudo lsusb -d 0483:5740 gives:
Bus 001 Device 004: ID 0483:5740 STMicroelectronics STM32F407

sudo setserial -a /dev/ttyACM1 seems to be the issue:

Cannot get serial info: Inappropriate ioctl for device

Thanks.

Order of plugging in devices can change which device the ttyACM1 link points to, but assuming you run “ls -l /dev/ttyACM1” and it points at “bus/usb/001/004”, what do you see from: “ls -l /dev/bus/usb/001/004” (I’m trying to see what the final node “ls -l” shows).

Regarding ioctls, most hardware on the system is accessed as an ordinary file to read from or write to. Non-standard options (options beyond basic file manipulation) use custom ioctl calls (“I/O control”). These files (e.g., “ttyACM1”) are actually the result of a driver and any operation on that file is limited to whatever the driver was programmed to handle. Not all serial devices will have the same set of commands available, and so the ioctl will show as an error if either the driver is not loaded, or if the special ioctl operation was not programmed into the driver. Thus this is not necessarily an error unless your end program depends on that ioctl, or if the driver has not loaded. The ioctl failure could just be because your device (when working normally) does not support that feature.

What can you provide in regards to exact information on this device, its name, and any manufacturer links?

Note that the udev rule is just a symbolic link and naming convention (this is a mapping from IDs to names, and has no influence on function). The udev rule created “/dev/ttyACM1”, and is not created by a driver; this is a pointer to a driver’s resulting file. The actual file “/dev/bus/usb/001/004” is the result of a driver loading (this is not a symbolic link), and this is what we are interested in. If the driver were incorrect for that hardware, then chances are the driver would have never loaded and there would have been a logged error. We used the udev rule to map a label consistent with an ACM serial UART, but if we were wrong, then we’ve just mislabeled another device and incorrect requests for non-existent functions imply the device will fail. I do think this is the right device though. This is where internet research can help…finding clues as to what the hardware is.

So we have to find out two things: First, is the device at “/dev/bus/usb/001/004” really an ACM UART? Second, assuming this is the correct device, is the device prepared to function as expected using the software you are using?

The first question can be answered by looking at the manufacturer and device IDs. These come straight from the device, and not the device driver (USB talks to devices, and USB itself is not a device driver to the end device, and so you are guaranteed a reply of IDs will be valid even if our own idea is not valid). Going here, and looking up manufacturer “0483”, followed by device “5740”, says this is a serial device (a virtual COM port). We have the correct idea of what the device is, although we do not know if it is really correct to use the ACM driver. I suspect (but cannot guarantee) that ACM is correct because otherwise the driver would have probably failed to load. Ignore the ioctl error, this device may just have a subset of ioctls most UARTs have. Now if we were to find a specific ioctl which the device should have and which is an error, then we would have a true error.

Extending the first question, USB says this is a “ChibiOS/RT Virtual COM Port”. Perhaps that is implemented with an ACM serial UART. Having a company program the device name, and yet be a more or less standard and common actual chip (using a generic driver), is common practice. Still, we do not yet have a guarantee, we only know this is likely correct due to the driver loading. What does a verbose lsusb say? Post the output of:

sudo lsusb -d 0483:5740 -vvv

Note that there is no difference between starting numbering at “ttyACM0” versus “ttyACM1”, but since USB is dynamically hot plug, this means numbering simply needs to be unique to any given device. However, this does make me curious about the laptop this works from. What do you see from this on the working laptop?

egrep -R -l 'ttyACM' /lib/udev/rules.d/* /etc/udev/rules.d/*

I am thinking we could refine the ttyACM udev rule, or perhaps find out if there is a comment in the udev file about what the device really is. Since multiple brands might use the same actual UART, then finding other ways the driver is named could help even if the rule is for some other different brand of hardware. For example, we could put a modified “60-serial.rules” into “/etc/udev/rules.d/”.

The second question about whether the device functions as intended might depend on firmware being loaded. Drivers only work if the hardware is what the driver expects, and firmware (for some devices) changes what hardware is present. I do not know what firmware your device needs, if any (I’ve never seen one of these before), but if some sort of user space software is available from STMicroelectronics, then this might include firmware. Should firmware be required, then having drivers present would be necessary, but not sufficient for success. At the very least trying to run this software could produce log info from either the command line or from “dmesg”.

What software do you have to use with this device, and what error or failure do you see from using that software with “ttyACM1”? Monitor “dmesg --follow” while plugging in the device and then while attempting to use the device.

This is what ls -l /dev/bus/usb/001/004 shows:
crw-rw-rw- 1 root root 189, 3 Apr 12 18:06 /dev/bus/usb/001/004

Here is some info on the VESC motor controller (I’m running version 4.12):
Benjamins Robotics - created vesc
Purchase Link

sudo lsusb -d 0483:5740 -vvvgives:
Bus 001 Device 004: ID 0483:5740 STMicroelectronics STM32F407
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0483 STMicroelectronics
idProduct 0x5740 STM32F407
bcdDevice 2.00
iManufacturer 1 STMicroelectronics
iProduct 2 ChibiOS/RT Virtual COM Port
iSerial 3 301
bNumConfigurations 1

On my laptop egrep -R -l 'ttyACM' /lib/udev/rules.d/* /etc/udev/rules.d/* gives:
/lib/udev/rules.d/60-serial.rules
/lib/udev/rules.d/77-mm-fibocom-port-types.rules
/lib/udev/rules.d/77-mm-ublox-port-types.rules

I’m trying to run the Vesc BLDC tool as per this guide and this repo (the link to the specific firmware is at the end of the file). When launching the BLDC tool nothing shows up in “dmesg --follow”
Here is what it looks like on the software next to Serial Connection:
image

Thanks again for all your help.

What we can attempt is to see if we can identify which driver and udev rule is being used on the laptop. The following is from the laptop, not the Jetson.

Can you rename a copy of the three files from the working system’s “/lib/udev/rules.d/” which have “ttyACM” found in them (to a “.txt” file name extension)? Finding something which already works would help.

Monitor “dmesg --follow”. What shows up upon plugging in the USB device? This is from a different UART, so your text will change, but you will see an identifier of the bus/port under sysfs. That line will look something like this:
[ 3393.265336] usb 1-2.3: Product: FT232R USB UART
…the whole line will be important, but the “1-2.3” format number is what you’ll use to find the driver within “/sys”. Write that down, and beware that if you unplug/replug the device, then this number will change.

Use “sudo -s” to enter a root shell since “/sys” will require root. Go here with the device attached, then run “ls”, and post what directory names you see:
/sys/bus/usb/drivers/

Note the “1-2.3” in this example (adjust for your case). Go here with cd:
cd /sys/bus/usb/devices/1-2.3/driver/1-2.3/

Just a warning…"/sys" has a lot of symbolic links. This may test your sanity using “cd” in what follows. Some drivers arrange “/sys” files differently ("/sys" is a result of running drivers and is not a result of anything actually stored on the hard drive), and so what I’m showing you is more a methodology than a guaranteed quickest path to what you want to know…your driver won’t be FTDI like mine is, and so the exact path might or might not follow just like mine does in the following example…

Note that there should be a subdirectory within /sys/bus/usb/devices/1-2.3/driver/1-2.3/ which is not a symbolic link, and that directory will start with the numeric “1-2.3”, but it will append something like “:1.0”, and so it might look something like “1-2.3:1.0”. cd to that subdirectory. Using “ls”, do you see a directory named “ttyACM0/”? If so, then cd into that. Once there you should find another “driver/” subdirectory which is from a symbolic link. cd there. Now you should see a “module” subdirectory which is actually a symbolic link. cd into this, and run “ls”. This big long cd exercise will lead to somewhere similar to this (but I have FTDI):
/sys/bus/usb/devices/1-2.3/driver/1-2.3/1-2.3:1.0/ttyUSB0/driver/module/drivers
…and the “ls” here shows a single symbolic link, and for my case that link shows the driver is “ftdi_sio” via the symbolic link “usb-serial:ftdi_sio”. The “ls” shows this module based driver is “ftdi_sio” talking through “usb-serial”. What driver is your laptop indicating?

This is what I see when plugging the VESC into my laptop:
[ 4693.342365] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 4693.342369] usb 2-3: Product: ChibiOS/RT Virtual COM Port
[ 4693.342372] usb 2-3: Manufacturer: STMicroelectronics
[ 4693.342374] usb 2-3: SerialNumber: 301
[ 4693.360154] cdc_acm 2-3:1.0: ttyACM0: USB ACM device
[ 4693.360670] usbcore: registered new interface driver cdc_acm
[ 4693.360671] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters

Here is what I see in /sys/bus/usb/drivers/:
btusb cdc_acm hub usb usbfs usbhid uvcvideo

My file path was a bit different /sys/bus/usb/devices/2-3:1.0/driver/2-3:1.0/tty/ttyACM0/device/driver/module/drivers# but this is what I got:

usb:cdc_acm

Thanks again.