src/libtrivdl.c the library for both MCU and PC
src/libtrivdl.h API header
examples/ examples, see below
You would want to make yourself familiar with shortcuts
and other definitions in libtrivdl.h,
because they are used extensively throughout the code.
The 'line' (struct t_line) represents a single peer-to-peer connection.
It contains two 'frames', one is RX buffer, another is TX buffer.
Along with frames, line has a file descriptor associated with serial port in POSIX code,
flags for signalling asynchronous machine (lflags) and void pointer to
arbitrary user data associated with the connection.
Each frame (struct t_frame) represents a single
datalink frame (see protocol), also serving
as RX or TX buffer.
It has the data (all bytes from 0xBA to the end),
index of next RX/TX byte
and transmission synchronization flags resembling modem's RTS/CTS.
In the core sits 'asynchronous machine', which transmits and receives
next byte of frame buffer when physical layer becomes ready.
In between these events, when both TX and RX are busy, it calls cb_idle().
Each character is handled by incoming_char() or outgoing_char().
When they finish receiving/transmitting the entire frame, they call
cb_frame_tx_done() or cb_frame_rx_done().
The main synchronization mean for all these functions is READY flag
in struct t_frame, see libtrivdl.h for its description.
library code | user code (callbacks)
|
|
| cb_frame_tx_done()
/
/
incoming_char() |
/ |
async_machine() ------------------ cb_idle()
or MCU ISRs |
user code \ |
outgoing_char() |
\
|\
| cb_frame_rx_done()
Users must define three callback functions in their code: cb_frame_tx_done,
cb_frame_rx_done and cb_idle. See libtrivdl.h for
their prototypes.
Also, asyncronous machine itself is fully implemented for POSIX side
but expected to be implemented by user as interrupt service routines (ISR)
for their MCU, see stream example
for MSP430 implementation.
Along with core procedures, the following helper functions are provided:
init_frameinit_linecompute_checksumadd_hdr_and_checksumbuild_framestrfr(return frame as a string; only in POSIX version)strfrret(return callbacks'statusargument as a string; only in POSIX version)
See libtrivdl.h for details.
libtrivdl provides code for both MCU and PC (aka 'POSIX' aka 'libc').
Moreover, core functions for both versions share the same C code.
Source for MCU must be compiled with MCU defined:
mspgcc -DMCU ...
or:
#define MCU
while POSIX version must be built without MCU defined.
Provided makefiles build the library and examples for both Linux PC and TI MSP-EXP430G2 Launchpad with MSP430G2553 MCU on board, hopefully as simple as:
apt-get install gcc-msp430 binutils-msp430 msp430-libc
cd libtrivdl
make
# upload 'echo' example to MCU
cd examples/echo/msp430 && make upload
# initiate example transmission
../posix/echo
For debug, enable -DDEBUG in makefiles
and additional callback functions in MCU code: mcudebug1 and mcudebug2
(prototypes, example).
POSIX version will output debug information to stderr,
while 430 Launchpad will blink green (RX) and red (TX) LED.
The single synchronous ping-pong. See how compact the code using libtrivdl can be.
PC (master) commands the MCU to start flooding with programmable-size frames, and starts its own flood in the opposite direction, fully two-way synchronous.
After transferring or receiving the given amount of data, master commands MCU to stop and stops itself. MCU sends statistics (rx/tx/errors) to master.
The state machine is described is stream.h.
This procedure runs multiple times using different frame sizes. At the end statistics table is printed.
You can also try to run echo master vs stream slave and vice versa.