Permalink
Browse files

Migrated documentation from MD to ReST. Added libcsp.rst and structur…

…e.rst
  • Loading branch information...
kristianbay committed Nov 12, 2015
1 parent 31e7d4c commit a7f5dd253997cfbf3c05b8fa802f19f792a55bac
@@ -9,7 +9,9 @@ certain optional features.
To configure CSP to build with the AVR32 toolchain for FreeRTOS and output
the compiled libcsp.a and header files to the install directory, issue:
./waf configure --toolchain=avr32- --with-os=freertos --prefix=install
.. code-block:: bash
./waf configure --toolchain=avr32- --with-os=freertos --prefix=install
When compiling for FreeRTOS, the path to the FreeRTOS header files must be
specified with `--with-freertos=PATH.`
@@ -23,4 +25,6 @@ where CHIP is one of 'socketcan', 'at91sam7a1', 'at91sam7a3' or 'at90can128'.
To build and copy the library to the location specified with --prefix, use:
./waf build install
.. code-block:: bash
./waf build install
View
File renamed without changes.
View

This file was deleted.

Oops, something went wrong.
View
@@ -0,0 +1,123 @@
Client and server example
=========================
The following examples show the initialization of the protocol stack and examples of client/server code.
Initialization Sequence
-----------------------
This code initializes the CSP buffer system, device drivers and router core. The example uses the CAN interface function csp_can_tx but the initialization is similar for other interfaces. The loopback interface does not require any explicit initialization.
.. code-block:: c
#include <csp/csp.h>
#include <csp/interfaces/csp_if_can.h>
/* CAN configuration struct for SocketCAN interface "can0" */
struct csp_can_config can_conf = {.ifc = "can0"};
/* Init buffer system with 10 packets of maximum 320 bytes each */
csp_buffer_init(10, 320);
/* Init CSP with address 1 */
csp_init(1);
/* Init the CAN interface with hardware filtering */
csp_can_init(CSP_CAN_MASKED, &can_conf)
/* Setup default route to CAN interface */
csp_route_set(CSP_DEFAULT_ROUTE, &csp_can_tx, CSP_HOST_MAC);
/* Start router task with 500 word stack, OS task priority 1 */
csp_route_start_task(500, 1);
Server
------
This example shows how to create a server task that listens for incoming connections. CSP should be initialized before starting this task. Note the use of `csp_service_handler()` as the default branch in the port switch case. The service handler will automatically reply to ICMP-like requests, such as pings and buffer status requests.
.. code-block:: c
void csp_task(void *parameters) {
/* Create socket without any socket options */
csp_socket_t *sock = csp_socket(CSP_SO_NONE);
/* Bind all ports to socket */
csp_bind(sock, CSP_ANY);
/* Create 10 connections backlog queue */
csp_listen(sock, 10);
/* Pointer to current connection and packet */
csp_conn_t *conn;
csp_packet_t *packet;
/* Process incoming connections */
while (1) {
/* Wait for connection, 10000 ms timeout */
if ((conn = csp_accept(sock, 10000)) == NULL)
continue;
/* Read packets. Timout is 1000 ms */
while ((packet = csp_read(conn, 1000)) != NULL) {
switch (csp_conn_dport(conn)) {
case MY_PORT:
/* Process packet here */
default:
/* Let the service handler reply pings, buffer use, etc. */
csp_service_handler(conn, packet);
break;
}
}
/* Close current connection, and handle next */
csp_close(conn);
}
}
Client
------
This example shows how to allocate a packet buffer, connect to another host and send the packet. CSP should be initialized before calling this function. RDP, XTEA, HMAC and CRC checksums can be enabled per connection, by setting the connection option to a bitwise OR of any combination of `CSP_O_RDP`, `CSP_O_XTEA`, `CSP_O_HMAC` and `CSP_O_CRC`.
.. code-block:: c
int send_packet(void) {
/* Get packet buffer for data */
csp_packet_t *packet = csp_buffer_get(data_size);
if (packet == NULL) {
/* Could not get buffer element */
printf("Failed to get buffer element\\n");
return -1;
}
/* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */
csp_conn_t *conn = csp_connect(CSP_PRIO_NORM, HOST, PORT, 1000, CSP_O_NONE);
if (conn == NULL) {
/* Connect failed */
printf("Connection failed\\n");
/* Remember to free packet buffer */
csp_buffer_free(packet);
return -1;
}
/* Copy message to packet */
char *msg = "HELLO";
strcpy(packet->data, msg);
/* Set packet length */
packet->length = strlen(msg);
/* Send packet */
if (!csp_send(conn, packet, 1000)) {
/* Send failed */
printf("Send failed\\n");
csp_buffer_free(packet);
}
/* Close connection */
csp_close(conn);
return 0
}
@@ -14,4 +14,4 @@ This is the known list of satellites or organisations that uses CSP.
* EuroLuna
* NUTS
* Hawaiian Space Flight Laboratory
* GomSpace GOMX-3
@@ -5,29 +5,29 @@ This is an example of how to implement a new layer-2 interface in CSP. The examp
CSP interfaces are declared in a `csp_iface_t` structure, which sets the interface nexthop function and name. A maximum transmission unit can also be set, which forces CSP to drop outgoing packets above a certain size. The fifo interface is defined as:
``` c
#include <csp/csp.h>
#include <csp/csp_interface.h>
.. code-block:: c
csp_iface_t csp_if_fifo = {
.name = "fifo",
.nexthop = csp_fifo_tx,
.mtu = BUF_SIZE,
};
```
#include <csp/csp.h>
#include <csp/csp_interface.h>
csp_iface_t csp_if_fifo = {
.name = "fifo",
.nexthop = csp_fifo_tx,
.mtu = BUF_SIZE,
};
Outgoing traffic
----------------
The nexthop function takes a pointer to a CSP packet and a timeout as parameters. All outgoing packets that are routed to the interface are passed to this function:
``` c
int csp_fifo_tx(csp_packet_t *packet, uint32_t timeout) {
write(tx_channel, &packet->length, packet->length + sizeof(uint32_t) + sizeof(uint16_t));
csp_buffer_free(packet);
return 1;
}
```
.. code-block:: c
int csp_fifo_tx(csp_packet_t *packet, uint32_t timeout) {
write(tx_channel, &packet->length, packet->length + sizeof(uint32_t) + sizeof(uint16_t));
csp_buffer_free(packet);
return 1;
}
In the fifo interface, we simply transmit the header, length field and data using a write to the fifo. CSP does not dictate the wire format, so other interfaces may decide to e.g. ignore the length field if the physical layer provides start/stop flags.
@@ -38,22 +38,22 @@ Incoming traffic
The interface also needs to receive incoming packets and pass it to the CSP protocol stack. In the fifo interface, this is handled by a thread that blocks on the incoming fifo and waits for packets:
``` c
void * fifo_rx(void * parameters) {
csp_packet_t *buf = csp_buffer_get(BUF_SIZE);
/* Wait for packet on fifo */
while (read(rx_channel, &buf->length, BUF_SIZE) > 0) {
csp_new_packet(buf, &csp_if_fifo, NULL);
buf = csp_buffer_get(BUF_SIZE);
}
}
```
.. code-block:: c
void * fifo_rx(void * parameters) {
csp_packet_t *buf = csp_buffer_get(BUF_SIZE);
/* Wait for packet on fifo */
while (read(rx_channel, &buf->length, BUF_SIZE) > 0) {
csp_new_packet(buf, &csp_if_fifo, NULL);
buf = csp_buffer_get(BUF_SIZE);
}
}
A new CSP buffer is preallocated with csp_buffer_get(). When data is received, the packet is passed to CSP using `csp_new_packet()` and a new buffer is allocated for the next packet. In addition to the received packet, `csp_new_packet()` takes two additional arguments:
``` c
void csp_new_packet(csp_packet_t *packet, csp_iface_t *interface, CSP_BASE_TYPE *pxTaskWoken);
```
.. code-block:: c
void csp_new_packet(csp_packet_t *packet, csp_iface_t *interface, CSP_BASE_TYPE *pxTaskWoken);
The calling interface must be passed in `interface` to avoid routing loops. Furthermore, `pxTaskWoken` must be set to a non-NULL value if the packet is received in an interrupt service routine. If the packet is received in task context, NULL must be passed. 'pxTaskWoken' only applies to FreeRTOS systems, and POSIX system should always set the value to NULL.
@@ -64,17 +64,17 @@ Initialization
In order to initialize the interface, and make it available to the router, use the following function found in `csp/csp_interface.h`:
``` c
csp_route_add_if(&csp_if_fifo);
```
.. code-block:: c
csp_route_add_if(&csp_if_fifo);
This actually happens automatically if you try to call `csp_route_add()` with an interface that is inknown to the router. This may however be removed in the future, in order to ensure that all interfaces are initialised before configuring the routing table. The reason is, that some products released in the future may ship with an empty routing table, which is then configured by a routing protocol rather than a static configuration.
In order to setup a manual static route, use the follwing example where the default route is set to the fifo interface:
``` c
csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_fifo, CSP_NODE_MAC);
```
.. code-block:: c
csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_fifo, CSP_NODE_MAC);
All outgoing traffic except loopback, is now passed to the fifo interface's nexthop function.
@@ -83,13 +83,13 @@ Building the example
The fifo examples can be compiled with:
``` bash
% gcc csp_if_fifo.c -o csp_if_fifo -I<CSP PATH>/include -L<CSP PATH>/build -lcsp -lpthread -lrt
```
.. code-block:: bash
% gcc csp_if_fifo.c -o csp_if_fifo -I<CSP PATH>/include -L<CSP PATH>/build -lcsp -lpthread -lrt
The two named pipes are created with:
``` bash
% mkfifo server_to_client client_to_server
```
.. code-block:: bash
% mkfifo server_to_client client_to_server
Oops, something went wrong.

0 comments on commit a7f5dd2

Please sign in to comment.