MicroCLI: Befehlsinterpreter auf einem STM32F0-Discovery + WLAN + Handy-App

MicroCLI Versuchsaufbau auf Steckbrett

MicroCLI Versuchsaufbau auf Steckbrett

Abstract

Ziel ist die Kommunikation zwischen einer Mikrocontroller-Platine und einer Handy-App über WLAN/Bluetooth zum Steuern von Ein- und Ausgängen.

Der Name MicroCLI setzt sich dabei aus Micro für Microcontroller (µC, uC, MCU) und CLI für Command Line Interface (Command Line Interpreter, Befehlsinterpreter) zusammen.

Ein paar Informationen zur WLAN Platine gibt es in diesem Blogpost.

Was macht ein richtiges Kommunikationsprotokoll aus?

A well-designed communications protocol has a number of characteristics.

Everything is sent in well defined packets with a header and an optional body or data payload. In each packet’s header a type and or command specified. Each packet has a definite length.

In addition to these characteristics, protocols have varying degrees of statefulness, inter-packet independence, human readability, and the ability to reestablish a disconnected session.

Paket Format (packet header):

  • Start Markierung mit packet length, Typ z.B. <start:0x00DF:0x01>
  • Endmarkierung <end>

Weiterhin könnte man noch eine Checksumme am Ende hinzufügen um zu erkennen, ob es zu Übertragungsfehlern gekommen ist, einen Zähler der mit jedem Paket nach oben gezählt wird, oder eine Antwort ID, damit der Empfänger eine Antwort genau einer Frage zuordnen kann.

<start:length:type:responseid:counter> packet data <checksum:end>

Die Länge am Anfang ist nützlich falls wir dynamisch Speicher für das Paket anfordern und keinen festen Buffer haben und um fest zu stellen ob Bytes verlorengegangen sind, falls die Endmarkierung nicht dort ist wo sie sein sollte.

Andere Idee: Ein kleiner Befehlsinterpreter

Da die Menge der übermittelten Daten eher gering ist reicht auch eine einfache zeilenbasierte Kommunikation über Befehle aus. Jeder Befehl wird durch ein Newline-Symbol '\n' abgeschlossen und die Daten müssen nicht in Pakete gekapselt werden. Das Handy sendet die Befehle zum Bluetooth-/WLAN-Modul, diese werden an den Serial Port des Mikrocontrollers weitergeleitet, dieser interpretiert dann die Befehle und sendet das Ergebnis zurück. Der Benutzer der Handy App bekommt gar nicht mit, was im Hintergrund ausgeführt wird, man kann sich aber auch ohne Handyapp mit jedem Bluetooth/WLAN fähigen Laptop via Hyperterminal/Telnet verbinden und Daten auslesen oder Parameter setzen.

Der Befehlsinterpreter

Hier sind ein paar interaktive Script Interpreter die klein genug sind um auf Mikrocontrollern zu laufen:

PyMite:

picol:

Weitere:

Ein kleiner Python Interpreter wäre am interessantesten, aber auf dem STM32F0-Mikrocontroller ist einfach nicht genug Platz.

Deshalb habe ich mich dann für die libshell aus dem libemb-Projekt entschieden, mit der sich ein ressourcensparender Interpreter realisieren ließ, bei dem der Quelltext trotzdem leicht verständlich und übersichtlich ist.

Durch den Verzicht auf printf aus der Newlib und stattdessen der Verwendung von libconio konnte ich noch mal 30KB Programmspeicher einsparen.

  • 48,1 KiB mit picol
  • 40 KiB ohne picol
  • 5,6 KiB mit libconio cio_printf
  • 6,3 KiB mit libshell und 2 Befehlen
  • 6,8 KiB Nicht blockierendes Command Prompt mit Zeileneditor (Backspace Taste funktioniert unter anderem in der Eingabezeile microcli>)
  • 8,2 KiB mit WLAN-Initialisierung und Befehlsinterpreter über Telnet
  • 11,6 KiB mit allen momentanen Funktionen, die auf den Screenshots der Handy Apps weiter unten zu sehen sind
MicroCLI über RS232

MicroCLI über RS232

Wenn in der Datei conf.h die Zeile #define WIFI_CONNECTED einkommentiert ist, wird das WLAN Modul automatisch initialisiert und bis zu 16 Personen sollten gleichzeitig per WLAN über Telnetverbindungen auf den Befehlsinterpreter zugreifen können:

MicroCLI über RS232

MicroCLI über Telnet

MicroCLI über RS232

Telnet Verbindung mit PuTTY unter Windows.

Das STM32F0-Discovery Board

Das ganze läuft momentan auf einem STM32F0-Discovery Entwicklungsboard von STM:

STM32F0-Discovery Board

STM32F0-Discovery Board

  • Eingebauter USB-Programmer/Debugger
  • STM32F051R8T6 Cortex-M0 Mikrocontroller
  • 64 KB Flash
  • 8 KB RAM
  • 9,69 € bei Farnell

Die Mikrocontroller Entwicklungsumgebung

Software unter Windows

Software unter Linux

Das Mikrocontroller Programm kann dann mit dem beiliegenden Makefile unter Windows und Linux compiliert werden. Zusätzlich befinden sich im Projektverzeichnis noch 2 Batchdateien, eine zum Compilieren und eine zum Flashen unter Windows.

Das Mikrocontroller Programm

Basiert auf dem Template: https://github.com/szczys/stm32f0-discovery-basic-template

Application Notes, Manuals and Firmware Package:

Die Links zum Download des Source Code von GitHub befinden sich unten.

Compilieren und Flashen unter Windows

Wenn die oben genannten Programme installiert sind kann das Mikrocontroller Programm durch doppeltes klicken auf compile_with_gcc.bat compiliert werden:

Compilieren mit compile_with_gcc.bat

Compilieren mit compile_with_gcc.bat

Zum flashen muss das Discovery Board über USB mit dem PC verbunden werden, dann kann das Programm über die STLINK GUI auf den Mikrocontroller geflashd werden:

Flashen mit der STLINK GUI

Flashen mit der STLINK GUI

Das Flashen ist auch über die Batchdatei flash_with_st-link.bat möglich:

Compilieren mit flash_with_st-link.bat

Flashen mit flash_with_st-link.bat

Compilieren und Flashen unter Linux

Zum Compilieren wird in das Verzeichnis mit dem Source Code gewechselt und make aufrufen:

[chris@thinkpad microcli-stm32f0-discovery]$ make clean
find . \( -name "*.orig" -or -name "*~" \) -exec rm -v "{}" \;
removed `./README.md~'
rm -f *.o
rm -f main.elf
rm -f main.hex
rm -f main.bin
rm -f main.map
rm -f main.lst
[chris@thinkpad microcli-stm32f0-discovery]$ make
make -C Libraries
make[1]: Entering directory `/mnt/data/Elektrotechnik/ARM/Projekte/MicroCLI/microcli-stm32f0-discovery/Libraries'
arm-none-eabi-ar -r libstm32f0.a stm32f0xx_adc.o stm32f0xx_cec.o stm32f0xx_comp.o stm32f0xx_crc.o stm32f0xx_dac.o stm32f0xx_dbgmcu.o stm32f0xx_dma.o stm32f0xx_exti.o stm32f0xx_flash.o stm32f0xx_gpio.o stm32f0xx_i2c.o stm32f0xx_iwdg.o stm32f0xx_misc.o stm32f0xx_pwr.o stm32f0xx_rcc.o stm32f0xx_rtc.o stm32f0xx_spi.o stm32f0xx_syscfg.o stm32f0xx_tim.o stm32f0xx_usart.o stm32f0xx_wwdg.o
make[1]: Leaving directory `/mnt/data/Elektrotechnik/ARM/Projekte/MicroCLI/microcli-stm32f0-discovery/Libraries'
arm-none-eabi-gcc -Wall -g -std=gnu99 -Os   -mlittle-endian -mcpu=cortex-m0  -march=armv6-m -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-Map=main.map -I inc -I Libraries -I Libraries/CMSIS/Device/ST/STM32F0xx/Include -I Libraries/CMSIS/Include -I Libraries/STM32F0xx_StdPeriph_Driver/inc -include Libraries/stm32f0xx_conf.h -I Libraries/libemb/libserial/src/include -I Libraries/libemb/libconio/src/include -I Libraries/libemb/libshell/src/include src/cli.c src/stm32f0xx_it.c src/main.c src/wifi.c src/system_stm32f0xx.c src/usart.c src/stm32f0_discovery.c Libraries/libemb/libconio/src/conio_serial.c Libraries/libemb/libconio/src/conio.c Libraries/libemb/libserial/src/serial_rb.c Libraries/libemb/libshell/src/shell.c Device/startup_stm32f0xx.s -o main.elf -LLibraries -lstm32f0 -LDevice/ldscripts -Tstm32f0.ld
arm-none-eabi-objcopy -O ihex main.elf main.hex
arm-none-eabi-objcopy -O binary main.elf main.bin
arm-none-eabi-objdump -St main.elf >main.lst
arm-none-eabi-size main.elf
  text    data     bss     dec     hex filename
  11484     364    2920   14768    39b0 main.elf
[chris@thinkpad microcli-stm32f0-discovery]$

Flashen unter Linux funktioniert über den Aufruf von make program:

[chris@thinkpad microcli-stm32f0-discovery]$ make program
openocd -f /usr/share/openocd/scripts/board/stm32f0discovery.cfg -f extra/stm32f0-openocd.cfg -c "stm_flash `pwd`/main.bin" -c shutdown
Open On-Chip Debugger 0.6.0-rc1-dev-00002-g66b9bff (2012-08-13-17:17)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html
1000 kHz
srst_only separate srst_nogate srst_open_drain
Info : clock speed 1000 kHz
Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints
stm_erase
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0xc1000000 pc: 0x08002320 msp: 0x20002000
auto erase enabled
Info : device id = 0x20006440
Info : flash size = 64kbytes
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000003a msp: 0x20002000
wrote 12288 bytes from file /home/chris/data/Elektrotechnik/ARM/Projekte/MicroCLI/microcli-stm32f0-discovery/main.bin in 0.763440s (15.718 KiB/s)
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x2000002e msp: 0x20002000
verified 11848 bytes in 0.159326s (72.620 KiB/s)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0xc1000000 pc: 0x08002320 msp: 0x20002000
shutdown command invoked
[chris@thinkpad microcli-stm32f0-discovery]$

Debuggen unter Linux

Wenn Nemiver und xterm installiert sind geht das über den Aufruf von make debug, siehe hier.

Die Handy Apps

Bei den Apps gibt es sicher noch Verbesserungspotential, sie sollten als eher Proof of Concept verstanden werden.

Die Apps wurden unter Android 1.6, im Emulator unter Android 2.2 und unter Android 4.1 getestet.

Auf GitHub gibt einen extra Branch der eine angepasste Version für Android 1.6 enthält, da bei der API unter Android 1.6 noch ein paar Funktionen fehlen und einen extra Branch für Android 4.1 da inzwischen einige ältere Funktionen aus der Android API entfernt wurden.

Entwicklungsumgebung:

MicroCLI Android Console

  • Minimal Programm zu Testzwecken
  • Bei drücken der Menü-Taste öffnet sich kleines Menü mit 3 Funktionen: toggle LED3, disable TOGGLE_LEDS, enable TOGGLE_LEDS. Damit kann man das Blinken der LEDs aus-/einschalten oder LED3 umschalten.
  • Eingabefeld um einzelne Befehle an das Mikrocontroller Board zu senden.
  • Vor dem Starten der App sollte man sich über die WLAN Einstellungen des Handys mit dem MicroCLI_WiFi-Netzwerk verbinden.
MicroCLI Console im Android Emulator

Die MicroCLI Console im Android Emulator, wenn der PC per WLAN mit dem Discovery Board verbunden ist kann man auch vom Emulator mit der Hardware kommunizieren.

MicroCLI Android Control

  • Viele Funktionen haben extra Menüs und Buttons.

  • Um die App im Emulator zu testen müssen die Variablen USE_BLUETOOTH und RUN_IN_EMULATOR in MicrodroidActivity.java folgende Werte haben:

    private static final boolean USE_BLUETOOTH = false;
    private static final boolean RUN_IN_EMULATOR = true;
    

Hier ein paar Screenshots von der App, die Outputs und Optionen kann man durch antippen mit dem Finger umschalten:

../../../_images/microcli_app_1.png ../../../_images/microcli_app_2.png ../../../_images/microcli_app_3.png ../../../_images/microcli_app_4.png ../../../_images/microcli_app_5.png ../../../_images/microcli_app_6.png ../../../_images/microcli_app_7.png ../../../_images/microcli_app_8.png ../../../_images/microcli_app_9.png