Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lab 1 extension: a Linux app that talks to the Blue Pill

Until now you typed 1 or 2 in the CLion serial terminal and read the board's reply there. In this extension a C program running in Linux (WSL) does the same job: it sends 1 or 2 to the board over the UART and prints what the board answers (Hello or Welcome).

 WSL (Linux)                      Windows                         Board
 ┌──────────────┐  usbipd-win  ┌──────────────┐  USB cable  ┌──────────────────────────┐
 │  uart_app    │◄────────────►│ CH340 USB    │◄───────────►│ CH340 ──► PA9/PA10       │
 │ /dev/ttyUSB0 │  (USB/IP)    │ device       │             │ USART1 of the STM32F103  │
 └──────────────┘              └──────────────┘             └──────────────────────────┘

The firmware does not change. Keep flashing it from CLion with Panda Run (HEX) as before.


Part 0: what you need first

  • The Lab 1 firmware flashed and working (it answers 1 → Hello, 2 → Welcome in the CLion terminal).
  • The baud rate set in Usart1_Init() in your firmware. This guide assumes 115200. If yours is different, pass it on the command line in Part 5.
  • The board's Serial UART DIP switch ON (both ways), and the CH340 USB cable plugged in.
  • WSL installed (Ubuntu).

Part 1: why WSL can't see the board yet

WSL2 is a small virtual machine. Windows owns every USB device and does not hand them to the Linux VM automatically, so inside WSL there is no /dev/ttyUSB0 yet. The tool usbipd-win fixes this: it takes the CH340 away from Windows and lends it to WSL over a virtual network link (the USB/IP protocol). While the CH340 is lent to WSL, Windows (and CLion's serial monitor, PuTTY, etc.) can't use it, and vice versa.


Part 2: install usbipd-win (Windows, one time)

  1. Open PowerShell as Administrator (Start → type PowerShell → right-click → Run as administrator).
  2. Run:
    winget install --interactive --exact dorssel.usbipd-win
    Click through the installer, then close and reopen the admin PowerShell.
  3. Make sure WSL itself is up to date (newer WSL kernels already include the CH340 driver):
    wsl --update

Part 3: lend the CH340 to WSL (every time you plug the board in)

  1. Close anything on Windows that has the COM port open (CLion Serial Port Monitor, PuTTY).
  2. Open a WSL terminal and leave it open (usbipd needs WSL to be running).
  3. In the admin PowerShell, list the USB devices:
    usbipd list
    Find the line that says USB-SERIAL CH340 and note its BUSID, e.g. 2-3:
    BUSID  VID:PID    DEVICE                       STATE
    2-3    1a86:7523  USB-SERIAL CH340 (COM5)      Not shared
    
    The ST-Link (0483:3748) is a different device: leave it alone so CLion can still flash.
  4. Share the device (only needed the first time for this USB port):
    usbipd bind --busid 2-3
  5. Attach it to WSL:
    usbipd attach --wsl --busid 2-3
    usbipd list now shows the state Attached.

Unplugging the cable or restarting the PC detaches it. Repeat step 5 after that (step 4 is remembered).


Part 4: set up Linux (WSL, one time)

In the WSL terminal:

  1. Install the compiler and CMake:
    sudo apt update
    sudo apt install -y build-essential cmake usbutils
  2. Check that Linux sees the board:
    lsusb                 # should list: 1a86:7523 QinHeng Electronics CH340 serial converter
    ls /dev/ttyUSB*       # should print: /dev/ttyUSB0
    If lsusb shows the CH340 but there is no /dev/ttyUSB0, run wsl --update in PowerShell, then wsl --shutdown, and attach again (Part 3, step 5).
  3. Give your user permission to use serial ports. Linux only lets members of the dialout group open /dev/ttyUSB0:
    sudo usermod -aG dialout $USER
    Then in PowerShell run wsl --shutdown, reopen WSL, and attach the board again. Check with groups: the list should contain dialout.

Part 5: build and run the app

  1. Copy the project into your Linux home folder. Windows drives appear in WSL under /mnt/, so D:\... is /mnt/d/.... For example, if you unzipped it to D:\nouran\linux-uart-app:
    cp -r /mnt/d/nouran/linux-uart-app ~/
    cd ~/linux-uart-app
    (Building inside /mnt/d also works, just more slowly.)
  2. Build with CMake:
    cmake -S . -B build
    cmake --build build
    This produces the program build/uart_app.
  3. Run it (device and baud are optional; these are the defaults):
    ./build/uart_app /dev/ttyUSB0 115200
  4. Expected session:
    Opened /dev/ttyUSB0 at 115200 baud (8N1)
    
    Enter 1 or 2 (q to quit): 1
    Sent    : 1
    Received: Hello
    
    Enter 1 or 2 (q to quit): 2
    Sent    : 2
    Received: Welcome
    
    Enter 1 or 2 (q to quit): q
    Bye
    
    Watch the board's RX/TX LEDs blink on every exchange.

Part 6: give the board back to Windows

When you want to use CLion's serial monitor again, in admin PowerShell:

usbipd detach --busid 2-3

Flashing with the ST-Link is not affected either way: it is a separate USB device.


How the code works

File What it does
src/serial_port.c Opens /dev/ttyUSB0 and configures it with termios (the Linux serial-port API). Reads one reply line with a timeout.
src/main.c The user loop: read 1/2 from the keyboard, send it, print the reply.
include/serial_port.h Declarations of the two serial functions.
CMakeLists.txt Builds uart_app with the normal Linux gcc (not the ARM compiler).

Key ideas:

  1. In Linux a serial port is a file. open("/dev/ttyUSB0") gives a file descriptor; write() sends bytes to the board, read() receives bytes from it.
  2. termios settings must match the MCU. serial_open() sets the same frame as Usart1_Init(): baud rate (cfsetispeed/cfsetospeed), 8 data bits (CS8), no parity (~PARENB), 1 stop bit (~CSTOPB), no hardware flow control (~CRTSCTS). A different baud on either side gives garbage or nothing.
  3. Raw mode. cfmakeraw() turns off the terminal "helpers" (echo, line editing, turning \n into \r\n), so the program sees exactly the bytes the board sent.
  4. One byte per command. The firmware reacts to a single character, so the app sends only '1' or '2', without the Enter key (\n).
  5. Waiting with a timeout. serial_read_line() uses poll() to wait up to 1 s for each byte and stops at \n (the firmware ends replies with \r\n). If the board is off or the baud is wrong, you get a clear "No reply" message instead of a frozen program.

Troubleshooting

Symptom Cause and fix
/dev/ttyUSB0: No such file or directory Not attached to WSL. Do Part 3 step 5; check ls /dev/ttyUSB*.
/dev/ttyUSB0: Permission denied Not in dialout (Part 4 step 3), or run once with sudo to confirm.
usbipd: error: ... WSL ... not running Open a WSL terminal first, then attach.
usbipd attach fails, device busy Close CLion's serial monitor / PuTTY on Windows first.
No reply within 1000 ms Baud mismatch with Usart1_Init(), Serial UART DIP switch OFF, or firmware not running (press reset).
Received text is garbage Baud mismatch, or the MCU clock is not what the firmware assumes.
COM port vanished from Windows It is attached to WSL. usbipd detach --busid 2-3.

Ideas for students

  • Add a command-line mode: ./build/uart_app /dev/ttyUSB0 115200 1 sends one command and exits.
  • Add a third command in the firmware (e.g. 3 toggles the LED) and handle it in the app.
  • Log every exchange with a timestamp to a file.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages