Paparazzi UAS  v5.10_stable-5-g83a0da5-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Datalink library

Datalink (uplink and downlink) lib using PPRZ protocol

HOWTO export

  • Export library: in this folder (sw/airborne/subsystems/datalink), type
    1 make export_lib
    be sure that you have correctly build the paparazzi project (make in the main directory)
  • The default export directory is ${PAPARAZZI_HOME}/var/export, to change it:
    1 EXPORT_ROOT=<your_export_root_dir> make export_lib
  • make clean will only remove the export directory

HOWTO use the datalink library

  1. Copy the folder datalink in the export directory to your project directory (or untar the file pprz_datalink.tar)
  2. In your project makefile:
    • define the variable PPRZ_DATALINK_PORT to your device (ex: PPRZ_DATALINK_PORT=XXX)
    • define the variable PPRZ_DATALINK_DIR to your extract folder
    • include the library makefile include ${PPRZ_DATALINK_DIR}/datalink/pprz_datalink.mk
    • add PPRZ_DATALINK_CFLAGS to your cflags
    • add PPRZ_DATALINK_SRCS to your sources (if your project requires a list of object files, you can use PPRZ_DATALINK_OBJS instead)
  3. Device interface You need to provide an interface to send the data. If your device is named XXX, you need to provide the following functions or macros

    • XXXCheckFreeSpace(len) that return true if your device has enough space for len bytes
    • XXXTransmit(c) that send a single byte c using the device XXX (or store them in a buffer)
    • XXXSendMessage() that flushs the bytes to send (if needed)
    • XXXChAvailable() that returns true new characters are available for reading
    • XXXGetch() taht returns the next character to parse

    Usually, an UART interface is used for datalink.

  4. Message parsing and includes: in a C file of you project (for example a file named datalink.c), add the following lines:
    #define DATALINK_C 1 // this should be placed before the includes
    #inlcude "uart.h" // or change this include to the header of your actual device interface
    #include "downlink.h"
    void dl_parse_msg(void) {
    <add your code to parse messages here>
    }
    You also need to poll for new characters, which means that you have to call the DatalinkEvent() function in your main loop. This function is non-blocking and calls the decoder on each received byte. Finally the dl_parse_msg function is called when a complete message is received (checksum is valid).

Example project for Mbeb dev board

Test file test_dl.cpp (assuming you already have the Mbed library)

#include "mbed.h"
Ticker daq;
Serial uart1(p9, p10);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
/**** PPRZ interface ****/
#define DATALINK_C 1
#define UartCheckFreeSpace(_len) uart1.writeable()
#define UartTransmit(_c) uart1.putc(_c)
#define UartSendMessage() {}
#define UartChAvailable() uart1.readable()
#define UartGetch() uart1.getc()
#include "downlink.h"
void dl_parse_msg(void) {
int msg_id = dl_buffer[1];
switch (msg_id) {
case DL_PONG:
led2 =! led2; // toggle led on new PONG message
break;
default:
break;
}
}
/************************/
void cb()
{
// Toggle led 1 when sending PING
led1 =! led1;
// Send PPRZ message
DOWNLINK_SEND_PING(DefaultChannel, DefaultDevice);
}
int main()
{
uart1.baud(57600); // set serial baud rate for PPRZ
led1 = led2 = 0; // turn off all LEDs
daq.attach(&cb, 1); // callback
while(1) {
// Your (non-blocking) code
// Poll new bytes on uart
} // ~while
} // ~main

With the makefile:

1 # This file was automagically generated by mbed.org with PPRZ datalink library addition
2 
3 GCC_BIN = /usr/bin/
4 PROJECT = Test_PPRZ_Datalink
5 OBJECTS = ./test_dl.o
6 SYS_OBJECTS = ./mbed/LPC1768/GCC_CS/sys.o ./mbed/LPC1768/GCC_CS/cmsis_nvic.o ./mbed/LPC1768/GCC_CS/system_LPC17xx.o ./mbed/LPC1768/GCC_CS/core_cm3.o ./mbed/LPC1768/GCC_CS/startup_LPC17xx.o
7 INCLUDE_PATHS = -I. -I./mbed -I./mbed/LPC1768 -I./mbed/LPC1768/GCC_CS
8 LIBRARY_PATHS = -L./mbed/LPC1768/GCC_CS
9 LIBRARIES = -lmbed -lcapi
10 LINKER_SCRIPT = ./mbed/LPC1768/GCC_CS/LPC1768.ld
11 
12 CC = $(GCC_BIN)arm-none-eabi-gcc
13 CPP = $(GCC_BIN)arm-none-eabi-g++
14 CC_FLAGS = -c -Os -fno-common -fmessage-length=0 -Wall -fno-exceptions -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections
15 ONLY_C_FLAGS = -std=gnu99
16 ONLY_CPP_FLAGS = -std=gnu++98
17 CC_SYMBOLS = -DTARGET_LPC1768 -DTOOLCHAIN_GCC_CS -DNDEBUG
18 
19 
20 ### PPRZ Datalink ###
21 
22 PPRZ_DATALINK_PORT = Uart
23 PPRZ_DATALINK_DIR = .
24 include $(PPRZ_DATALINK_DIR)/datalink/pprz_datalink.mk
25 OBJECTS += $(PPRZ_DATALINK_OBJS)
26 CC_SYMBOLS += $(PPRZ_DATALINK_CFLAGS)
27 
28 #####################
29 
30 
31 AS = $(GCC_BIN)arm-none-eabi-as
32 
33 LD = $(GCC_BIN)arm-none-eabi-gcc
34 LD_FLAGS = -mcpu=cortex-m3 -mthumb -Wl,--gc-sections
35 LD_SYS_LIBS = -lstdc++ -lsupc++ -lm -lc -lgcc
36 
37 OBJCOPY = $(GCC_BIN)arm-none-eabi-objcopy
38 
39 all: $(PROJECT).bin
40 
41 clean:
42  rm -f $(PROJECT).bin $(PROJECT).elf $(OBJECTS)
43 
44 .s.o:
45  $(AS) $(CC_FLAGS) $(CC_SYMBOLS) -o $@ $<
46 
47 .c.o:
48  $(CC) $(CC_FLAGS) $(CC_SYMBOLS) $(ONLY_C_FLAGS) $(INCLUDE_PATHS) -o $@ $<
49 
50 .cpp.o:
51  $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) $(ONLY_CPP_FLAGS) $(INCLUDE_PATHS) -o $@ $<
52 
53 
54 $(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS)
55  $(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $@ $^ $(LIBRARIES) $(LD_SYS_LIBS) $(LIBRARIES) $(LD_SYS_LIBS)
56 
57 $(PROJECT).bin: $(PROJECT).elf
58  $(OBJCOPY) -O binary $< $@