STM CDC and Linux ACM driver....  - Page 1
Forum section: electronics / general

author: paulca
author_rank: Super Contributor
timestamp: May 31, 2025, 05:16:07 pm
content: So you never can do an STM32 project without every god damn dragon and gremlin it can produce being thrown at you. It never goes smoothly.Now I when I try and use the CDC USB serial setup, Linux for whatever bloody reason unbeknown to us, decides to default to REMOTE echo ON.This means as soon as you Send:"Welcome to my crappy project V1.0"Most of that ends up back in your input buffer, as soon as you even look at the serial port in linux.Worse... when you figure out that "echo" is on and use "stty" to turn it off.... it's already too late as stty opens the damn connection and then changes settings, so you still end up with"Welcome to m"In your input buffer.Before I go and setup a systemd hook or udev rule to bring sanity back to my life... can anyone suggest an easier way?

author: __george__
author_rank: Contributor
timestamp: May 31, 2025, 05:42:01 pm
content: Are you using the Arduino framework or the ST SDK?The issue that you are describing I heard before with the Arduino framework:https://github.com/rogerclarkmelbourne/Arduino_STM32/issues/910

author: paulca
author_rank: Super Contributor
timestamp: May 31, 2025, 06:03:48 pm
content: It's vanila CubeIDE. MX Generated, just add a CDC_Transmit_FS() and put a break point in CDC_Receive_FS() and sure enough, anything you send comes back one character at a time with the new line swapped from \n to \r and all.Running this fixes it:Code:stty -F /dev/ttyACM0 -echoHowever in the process a bunch of characters get echoed back.At the moment I am working around it, I trigger on "\n" or "\r" as a "command" and if it doesn't match an actual command it's ignored. So the first load of garbage should just be ignored.

author: __george__
author_rank: Contributor
timestamp: May 31, 2025, 06:46:42 pm
content: Don't have many ideas here but maybe it is worth to try the raw mode of stty to check if it does any differenceCode:stty raw -F /dev/ttyACM0 -echo

author: Nominal Animal
author_rank: Super Contributor
timestamp: May 31, 2025, 09:18:31 pm
content: Quote from: paulca on May 31, 2025, 06:03:48 pmWhy not stuff it in an udev rule?Create file/etc/udev/rules.d/99-ttyacm-defaults.rulescontaining say# Make USB serial devices default to sane terminal settingsACTION=="add", SUBSYSTEMS=="usb-serial", RUN+="/usr/bin/stty -F /dev/%k raw -echo"where the "raw" bit disables all termios processing and "-echo" disables echo; seeman 1 sttyfor other possibilities. You can also limit to specific vendor and device ID patterns if you like; seeman udev.Then, runudevadm control --reload-rulesso that the new rule is loaded. (Run this whenever you add or modify your udev rules.)Next time you plug in any USB serial device, it will have echo disabled.

author: paulca
author_rank: Super Contributor
timestamp: May 31, 2025, 11:26:16 pm
content: udev or systemd was the next port of call. However the protocol doesn't really care, it ignores garbage anyway.Been a long, long day at it, but progress:Anyone seeing those addresses (and I only have 4 bits of the databus) will probably recognise this as a flash programmer.All lovely bit-banged with LL code.Tomorrow I'll do some more fine tuning (like not using a 1ms sleep when a 40ns one was needed!) and then turn it loose on the actual IC.

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 01, 2025, 12:12:30 am
content: I do recommend creating udev rules for development boards; especially something likeACTION=="add", SUBSYSTEMS=="usb-serial", ATTRS{idVendor}=="VVVV", ATTRS{idProduct}=="PPPP", SYMLINK+="name"that creates a symlink/dev/namewhenever an USB serial device with that specific USB vendor:product ID is inserted. The symlink is autodeleted when the device is unplugged.If you have more than one of the same type, useSYMLINK+="name-$attr{serial}"which creates symlink/dev/name-serialnumberstring.You can add more than one such rule in a single file. Just be careful with the operators:==is equality comparison that filters, whereas=and+=are assignments.If you assignOWNER(user owning the device, default isroot),GROUP(set usually todialoutfor serial-like devices), orMODE(octal access mode: 0ugo, where u is for user, g is for group, and o is for others, 0 = no access, 1 = execute permission, 2 = write permission, 4 = read permission; recommend 0660), it sets those for the actual device, affecting all symlinks also.The USB subsystem triggers for the raw USB device node,/dev/bus/usb/BBB/DDD, which are character devices providing the Linux usbfs interface. If you do direct bulk transfers or async I/O, it can be useful to change the owner of that to a specific user or group, so that extra privileges are not needed.