serialdbus

Fortschritt: 90% (Funktionsfähig, evt. Erweiterungen)

Das Programm serialdbus dient der Umsetzung der seriellen Schnittstelle zum DBus-Daemon unter Linux.

Mit hilfe dieser Umsetzung kann sehr simpel auf eine oder auch mehrere serielle Schnittstellen zugegriffen werden.

Verwendung

Programm Parameter (-h|--help)

Ausgabe von 'serialdbus –help'

Usage: ./serialdbus device dbus-name [OPTIONS]

  device
                the serial device to use, e.g. /dev/ttyS0, /dev/ttyUSB0 etc.
  dbus-name
                the name under wich this instance will appear in the
                session-dbus domain 'org.schmufu.serialdbus "dbus-name"'.

OPTIONS are:
  -h, --help    shows this help and exits
  -b N, --baud N, --baudrate N
                baudrate to use. Default: 19200
                supported values: 110, 115200, 1200, 19200, 2400, 300, 38400, 4800, 57600, 600, 9600
  -d N, --data N, --databits N
                data bits. Default: 8
                supported values: 5, 6, 7, 8
  -f FLOW, --flow FLOW, --flowcontrol FLOW
                flow control. Default: none
                supported values: hardware, none, off, software, xonxoff
  -s N, --stop N, --stopbits N
                N count stop bits. Default: 1
                supported values: 1, 2
  -p PARITY, --par PARITY, --parity PARITY
                parity to use. Default: none
                supported values: even, mark, none, odd, space

Version: 0.1.0.0 (svn: rev7)
Author:  Patrick Wacker (wacker.p@gmx.de)
License: GNU General Public License version 2, or (at your option) any later version

Start des Programms

serialdbus /dev/ttyUSB0 Ser1

dies stellt ein dbus-Interface „org.schmufu.serialdbus“ mit dem Object „/Ser1“ im DBus zur Verfügung. Der Zugriff hierauf kann dann z.B. über qdbus erfolgen.

Senden von Daten (mit qdbus)

qdbus org.schmufu.serialdbus /Ser1 org.schmufu.serialdbus.apply „send data“

Sendet „send data“ über die serielle Schnittstelle /dev/ttyUSB0

Empfangen von Daten (mit qdbus)

qdbus org.schmufu.serialdbus /Ser1 org.schmufu.serialdbus.receive

Gibt alle, seit dem letzten Aufruf, empfangene Daten zurück und löscht den internen Empfangsbuffer.

Beenden des Programms

serialdbus läuft weiterhin im Vordergrund und kann über STRG+C beendet werden. Es besteht aber auch die Möglichkeit das Programm über den dbus aufruf „qdbus org.schmufu.serialdbus /Ser1 org.schmufu.serialdbus.quit“ zu beenden. (Dies funktioniert auch dann wenn das Programm durch ein nachgestelltes „&“ weiter im Hintergrund ausgeführt wird).

Shell Script Beispiele (bash)

folgendes script kann in ein Script eingebunden werden und dann einfach über die zur Verfügung gestellten funktionen auf die serielle Schnittstelle zugegriffen werden.

dbusserial.sh
#!/bin/bash
#
# bash Script das in andere Scripte eingebunden werden kann um Daten über
# eine serielle Schnittstelle zu senden.
#
export SERIALDBUS="../build/./serialdbus"
 
function serial_init()
{
	local device;
	local baudrate;
	local dbusname;
	local stopbits;
	local databits;
	local flowcontrol;
	local parity;
	local serial_export;
 
	local interface;
	local grepret;
 
	if [[ -z "$1" ]]; then
		device="/dev/ttyS0"
	else
		device="$1"
	fi
 
	if [[ -z "$2" ]]; then
		dbusname="Ser0"
	else
		dbusname="$2"
	fi
 
	if [[ -z "$3" ]]; then
		baudrate=19200
	else
		baudrate="$3"
	fi
 
	if [[ -z "$4" ]]; then
		databits=8
	else
		databits="$4"
	fi
 
	if [[ -z "$5" ]]; then
		flowcontrol="none"
	else
		flowcontrol="$5"
	fi
 
	if [[ -z "$6" ]]; then
		stopbits=1
	else
		stopbits="$6"
	fi
 
	if [[ -z "$7" ]]; then
		parity="none"
	else
		parity="$7"
	fi
 
	# Alle Werte wurden auf Standart oder den übergebenen Wert gesetzt
 
	# Instanz von serialdbus starten und alle Ausgaben des Programs
	# nach /dev/null schicken
	$SERIALDBUS "$device" "$dbusname" -b "$baudrate" -d "$databits" -f "$flowcontrol" -s "$stopbits" -p "$parity" >/dev/null 2>&1 &
 
	sleep 2 #etwas warten damit die schnittstelle initialisert werden kann
 
	# gibt alle funktionen innerhalb von serialdbus wieder
	interface=$(qdbus org.schmufu.serialdbus)
	grepret=$(echo "${interface}" | egrep "${dbusname}")
	# der übergebene dbusname muss als dbus service vorhanden sein
	if [[ -z "${grepret}" ]]; then
		#dbus service konnte nicht erstellt werden
		echo "ERROR at ${FUNCNAME}: cant create the serialdbus service for $dbusname"
		return 1
	fi
 
	return 0;
}
 
# Beendet die genutzte serielle Schnittstelle
function serial_deinit()
{
	if [[ -z "$1" ]]; then
		echo "PROGRAMMING ERROR at ${FUNCNAME}: supply a DBUSNAME at \$1"
		return 1
	fi
 
	qdbus org.schmufu.serialdbus /${1} org.schmufu.serialdbus.quit
 
	return 0
}
 
 
# Sendet über die in $1 definierte Schnittstelle, den in $2 übergebenen String
function serial_send()
{
	local ret;
	local str;
	ret=1;
	if [[ -z "$1" ]]; then
		echo -en "PROGRAMMING ERROR at ${FUNCNAME} - supply a dbusname at \$1!\n"
		return 1
	fi
 
	if [[ -z "$2" ]]; then
		echo -en "PROGRAMMING ERROR at ${FUNCNAME} - supply a text to sent at \$2!\n"
		return 1
	fi
 
 
	str=$(qdbus org.schmufu.serialdbus /${1} org.schmufu.serialdbus.apply "$2")
	if [[ "x${str}" != "xtrue" ]]; then
		ret=1
	else
		ret=0
	fi
 
	return $ret
}
 
# Setzt die globale Variable $SERIALRECV auf den Empfangenen String
function serial_receive()
{
	local str;
 
	if [[ -z "$1" ]]; then
		echo -en "PROGRAMMING ERROR at ${FUNCNAME} - supply a dbusname at \$1!\n"
		return 1;
	fi
 
	str="";
 
	str=$(qdbus org.schmufu.serialdbus /${1} org.schmufu.serialdbus.receive)
	SERIALRECV="${str}";
}

Verwendet werden kann dies dann wie folgt

serial_example.sh
#!/bin/bash
#
# simples Beispiel Script zur Verwendung von serialdbus über die bash
#
#
# Vorrausssetzungen:
#  - es existiert die serielle Schnittstelle /dev/ttyUSB1
#  - TXD ist mit RXD verbunden
#  - das Programm "qdbus" ist installiert
#
#
 
#include the main functions
. dbusserial.sh
 
SER=serial1	# der Name für die serialdbus instanz (frei wählbar!)
		# über diesen Namen wird später auf die Schnittstelle zugeriffen
 
# initialisierung der Schnittstelle
serial_init /dev/ttyUSB1 $SER 19200 8 none 1 none
 
if [[ $? -ne 0 ]]; then
	# Ein Fehler ist bei der Initialisierung aufgetreten
        echo "ERROR: could not open /dev/ttyUSB1 as '$SER' for serial communication"
        exit 1 # Script abbrechen
fi
 
# von jetzt an kann über "serial_send" gelesen und über "serial_receive" geschrieben werden
 
# wenn TxD mit RxD verbunden ist wird das was gesendet wird auch wieder empfangen
serial_send $SER "Diese Daten "
serial_send $SER "werden gesendet"
 
# wir holen die Empfangen Daten ab
serial_receive $SER
# in $SERIALRECV steht jetzt der empfangene String
echo "Empfangen wurde:"
echo -en "$SERIALRECV" # gibt "Diese Daten werden gesendet" aus
echo " "
 
# Die gesendeten Daten enhalten KEINE Steuerzeichen! Und auch ein abschlie0endes
# "\n" wird nicht automatisch an den String angehangen!
# Wenn Steuerzeichen übertragen werden sollen kann dies folgendermaßen
# erreicht werden
 
# String erstellen
SEND_DATA=$(echo -en "Test mit einem\nZeilenumbruch.")
# Daten Senden. $SEND_DATA muss in " ", damit es als ein Argument übergeben wird!
serial_send $SER "$SEND_DATA" 
 
# wir holen die Empfangen Daten ab
serial_receive $SER
# in $SERIALRECV steht jetzt der empfangene String
echo "Empfangen wurde:"
echo -en "$SERIALRECV" # gibt "Test mit einem
echo " "               #      "Zeilenumbruch." aus
 
 
# Auch folgendes ist möglich
serial_send $SER "0x41 (A) in HEX angegeben = \x41\n"
serial_receive $SER
echo "Empfangen wurde:"
echo -en "$SERIALRECV" # gibt "0x41 (A) in HEX angegeben = A" aus
echo " "
 
 
# zum schluss muss die Schnittstelle wieder geschlossen werden
serial_deinit $SER

evt. noch implementieren

  • über dbus die aktuellen Einstellungen auslesen (baudrate, databits, device etc.)
  • über dbus die Einstellungen ändern (baudrate, databits, device etc.)
  • Fehler zurückgeben wenn irgendwas schief ging
  • über dbus die Schnittstelle öffnen und schließen (dabei das Progamm aber nicht beenden)

Weiterführende Links

Projektwerkzeuge