Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
pipe_arch.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018 Kirk Scheper <kirkscheper@gmail.com>
3 *
4 * This file is part of Paparazzi.
5 *
6 * Paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * Paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
26#include "mcu_periph/pipe.h"
27#include <stdlib.h>
28#include <stdio.h>
29#include <errno.h>
30#include <pthread.h>
31#include <sys/select.h>
32
33// FIFO
34#include <fcntl.h>
35#include <sys/stat.h>
36#include <sys/types.h>
37#include <unistd.h>
38
39#include "rt_priority.h"
40
41#ifndef PIPE_THREAD_PRIO
42#define PIPE_THREAD_PRIO 10
43#endif
44
45static void *pipe_thread(void *data __attribute__((unused)));
47
49{
51
52#if defined(USE_PIPE0_WRITER) || defined(USE_PIPE0_READER)
53 PIPE0Init();
54#endif
55#if defined(USE_PIPE1_WRITER) || defined(USE_PIPE1_READER)
56 PIPE1Init();
57#endif
58#if defined(USE_PIPE2_WRITER) || defined(USE_PIPE2_READER)
59 PIPE2Init();
60#endif
61
63 if (pthread_create(&tid, NULL, pipe_thread, NULL) != 0) {
64 fprintf(stderr, "pipe_arch_init: Could not create PIPE reading thread.\n");
65 return;
66 }
67#ifndef __APPLE__
68 pthread_setname_np(tid, "pipe");
69#endif
70}
71
77{
78 if(read_name != NULL)
79 {
80 if( access( read_name, F_OK ) == -1 ) {
81 mkfifo(read_name, 0666);
82 }
83 p->fd_read = open(read_name, O_RDWR | O_NONBLOCK);
84 } else {
85 p->fd_read = -1;
86 }
87
88 if(write_name != NULL)
89 {
90 if( access( write_name, F_OK ) == -1 ) {
91 mkfifo(write_name, 0666);
92 }
93 p->fd_write = open(write_name, O_RDWR | O_NONBLOCK);
94 } else {
95 p->fd_write = -1;
96 }
97}
98
105{
107 int available = p->rx_insert_idx - p->rx_extract_idx;
108 if (available < 0) {
109 available += PIPE_RX_BUFFER_SIZE;
110 }
112 return available;
113}
114
121{
123 uint8_t ret = p->rx_buf[p->rx_extract_idx];
124 p->rx_extract_idx = (p->rx_extract_idx + 1) % PIPE_RX_BUFFER_SIZE;
126 return ret;
127}
128
133{
134 if (p == NULL) { return; }
135 if (p->fd_read < 0) { return; }
136
137 int16_t i;
140
141 if (available <= 0) {
142 return; // No space
143 }
144
145 ssize_t bytes_read = read(p->fd_read, buf, available);
146
148 if (bytes_read > 0) {
149 for (i = 0; i < bytes_read; i++) {
150 p->rx_buf[p->rx_insert_idx] = buf[i];
151 p->rx_insert_idx = (p->rx_insert_idx + 1) % PIPE_RX_BUFFER_SIZE;
152 }
153 }
155}
156
160void pipe_send_message(struct pipe_periph *p, long fd __attribute__((unused)))
161{
162 if (p == NULL) { return; }
163 if (p->fd_write < 0) { return; }
164
165 if (p->tx_insert_idx > 0) {
166 ssize_t bytes_sent = write(p->fd_write, p->tx_buf, p->tx_insert_idx);
167 if (bytes_sent != p->tx_insert_idx) {
168 if (bytes_sent < 0) {
169 fprintf(stderr, "pipe_send_message failed\n");
170 } else {
171 fprintf(stderr, "pipe_send_message: only sent %d bytes instead of %d\n",
172 (int)bytes_sent, p->tx_insert_idx);
173 }
174 }
175 p->tx_insert_idx = 0;
176 }
177}
178
182void pipe_send_raw(struct pipe_periph *p, long fd __attribute__((unused)), uint8_t *buffer, uint16_t size)
183{
184 if (p == NULL) { return; }
185 if (p->fd_write < 0) { return; }
186
187 ssize_t test __attribute__((unused)) = write(p->fd_write, buffer, size);
188}
189
193static void *pipe_thread(void *data __attribute__((unused)))
194{
196
197 /* file descriptor list */
199 /* maximum file descriptor number */
200 int fdmax = 0;
201
202 /* clear the fd list */
204 /* add used file descriptors */
205 int fd __attribute__((unused));
206#ifdef USE_PIPE0_READER
207 if (pipe0.fd_read >= 0){
208 FD_SET(pipe0.fd_read, &fds_master);
209 if (pipe0.fd_read > fdmax) {
210 fdmax = pipe0.fd_read;
211 }
212 }
213#endif
214#ifdef USE_PIPE1_READER
215 if(pipe1.fd_read >= 0){
216 FD_SET(pipe1.fd_read, &socks_master);
217 if (pipe1.fd_read > fdmax) {
218 fdmax = pipe1.fd_read;
219 }
220 }
221#endif
222#ifdef USE_PIPE2_READER
223 if(pipe2.fd_read >= 0){
224 FD_SET(pipe2.fd_read, &socks_master);
225 if (pipe2.fd_read > fdmax) {
226 fdmax = pipe2.fd_read;
227 }
228 }
229#endif
230
231 /* files to be read, modified after each select */
232 fd_set fds;
233
234 while (1) {
235 /* reset list of socks to check */
236 fds = fds_master;
237
238 if (select(fdmax + 1, &fds, NULL, NULL, NULL) < 0) {
239 fprintf(stderr, "pipe_thread: select failed!");
240 } else {
241#ifdef USE_PIPE0_READER
242 if (FD_ISSET(pipe0.fd_read, &fds)) {
244 }
245#endif
246#ifdef USE_PIPE1_READER
247 if (FD_ISSET(pipe1.fd_read, &fds)) {
249 }
250#endif
251#ifdef USE_PIPE2_READER
252 if (FD_ISSET(pipe2.fd_read, &fds)) {
254 }
255#endif
256 }
257 }
258 return 0;
259}
static float p[2][2]
void pipe_receive(struct pipe_periph *p)
Read bytes from PIPE.
Definition pipe_arch.c:132
static void * pipe_thread(void *data)
check for new pipe packets to receive.
Definition pipe_arch.c:193
void pipe_arch_init(void)
Definition pipe_arch.c:48
int pipe_char_available(struct pipe_periph *p)
Get number of bytes available in receive buffer.
Definition pipe_arch.c:104
uint8_t pipe_getch(struct pipe_periph *p)
Get the last character from the receive buffer.
Definition pipe_arch.c:120
#define PIPE_THREAD_PRIO
Definition pipe_arch.c:42
void pipe_arch_periph_init(struct pipe_periph *p, char *read_name, char *write_name)
Initialize the PIPE peripheral.
Definition pipe_arch.c:76
static pthread_mutex_t pipe_mutex
Definition pipe_arch.c:46
void pipe_send_message(struct pipe_periph *p, long fd)
Send a message.
Definition pipe_arch.c:160
void pipe_send_raw(struct pipe_periph *p, long fd, uint8_t *buffer, uint16_t size)
Send a packet from another buffer.
Definition pipe_arch.c:182
#define PIPE_RX_BUFFER_SIZE
Definition pipe_arch.h:31
uint16_t foo
Definition main_demo5.c:58
arch independent PIPE API
Functions to obtain rt priority or set the nice level.
static int get_rt_prio(int prio)
Definition rt_priority.h:32
int fd
Definition serial.c:26
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.