Skip to content
Snippets Groups Projects
Commit efad6f91 authored by bbartels's avatar bbartels
Browse files

quad: update fifos to use blocking I/O for inputs and outputs

parent 0e2557d5
No related branches found
No related tags found
No related merge requests found
...@@ -16,25 +16,39 @@ MOTOR_MAX = 200000 ...@@ -16,25 +16,39 @@ MOTOR_MAX = 200000
GEAR_ON = 170800 GEAR_ON = 170800
GEAR_OFF = 118300 GEAR_OFF = 118300
MOTOR1 = "virt-quad-fifos/pwm-output-motor1"
MOTOR2 = "virt-quad-fifos/pwm-output-motor2"
MOTOR3 = "virt-quad-fifos/pwm-output-motor3"
MOTOR4 = "virt-quad-fifos/pwm-output-motor4"
GEAR = "virt-quad-fifos/pwm-input-gear"
THROTTLE = "virt-quad-fifos/pwm-input-throttle"
LED = "virt-quad-fifos/mio7-led"
require 'test/unit/assertions' require 'test/unit/assertions'
require 'thread' require 'thread'
include Test::Unit::Assertions include Test::Unit::Assertions
def read_fifo_num(fifo)
File.read(fifo).chomp.split("\n").last.to_i
end
# Utility functions # Utility functions
def check_motors_are_off def check_motors_are_off
motor1 = File.read("virt-quad-fifos/pwm-output-motor1") motor1 = read_fifo_num(MOTOR1)
motor2 = File.read("virt-quad-fifos/pwm-output-motor2") motor2 = read_fifo_num(MOTOR2)
motor3 = File.read("virt-quad-fifos/pwm-output-motor3") motor3 = read_fifo_num(MOTOR3)
motor4 = File.read("virt-quad-fifos/pwm-output-motor4") motor4 = read_fifo_num(MOTOR4)
assert_operator motor1.to_i, :<=, THROTTLE_MIN assert_operator motor1, :<=, THROTTLE_MIN
assert_operator motor2.to_i, :<=, THROTTLE_MIN assert_operator motor2, :<=, THROTTLE_MIN
assert_operator motor3.to_i, :<=, THROTTLE_MIN assert_operator motor3, :<=, THROTTLE_MIN
assert_operator motor4.to_i, :<=, THROTTLE_MIN assert_operator motor4, :<=, THROTTLE_MIN
end end
def check_led(on) def check_led(on)
led = File.read("virt-quad-fifos/mio7-led") led = read_fifo_num(LED)
assert_equal(led.to_i, on) assert_equal(led, on)
end end
script_dir = File.expand_path(File.dirname(__FILE__)) script_dir = File.expand_path(File.dirname(__FILE__))
...@@ -61,47 +75,47 @@ begin ...@@ -61,47 +75,47 @@ begin
# Check that increasing the throttle does nothing to motors # Check that increasing the throttle does nothing to motors
# (because gear is still off) # (because gear is still off)
for i in (THROTTLE_MIN..THROTTLE_MAX).step(1000) for i in (THROTTLE_MIN..THROTTLE_MAX).step(1000)
File.write("virt-quad-fifos/pwm-input-throttle", i) File.write(THROTTLE, i)
check_motors_are_off check_motors_are_off
sleep 0.005 sleep 0.005
end end
# Check that flipping gear to 1 while throttle is high does nothing # Check that flipping gear to 1 while throttle is high does nothing
# (motors should still be off, LED should still be off) # (motors should still be off, LED should still be off)
File.write("virt-quad-fifos/pwm-input-gear", GEAR_ON) File.write(GEAR, GEAR_ON)
sleep 0.015 sleep 0.015
check_motors_are_off check_motors_are_off
i = THROTTLE_MAX i = THROTTLE_MAX
while i > THROTTLE_MID while i > THROTTLE_MID
i -= 1000 i -= 1000
File.write("virt-quad-fifos/pwm-input-throttle", i) File.write(THROTTLE, i)
check_motors_are_off check_motors_are_off
check_led 0 check_led 0
sleep 0.005 sleep 0.005
end end
# (swtich GEAR back to off and bring throttle off) # (swtich GEAR back to off and bring throttle off)
File.write("virt-quad-fifos/pwm-input-gear", GEAR_OFF) File.write(GEAR, GEAR_OFF)
File.write("virt-quad-fifos/pwm-input-throttle", THROTTLE_MIN) File.write(THROTTLE, THROTTLE_MIN)
# Check that the LED turns on when gear is flipped on # Check that the LED turns on when gear is flipped on
# (motors should still be off because our throttle is low) # (motors should still be off because our throttle is low)
File.write("virt-quad-fifos/pwm-input-gear", GEAR_ON) File.write(GEAR, GEAR_ON)
sleep 0.010 sleep 0.010
check_led 1 check_led 1
check_motors_are_off check_motors_are_off
# Check that motors turn on # Check that motors turn on
File.write("virt-quad-fifos/pwm-input-throttle", THROTTLE_MID) File.write(THROTTLE, THROTTLE_MID)
motor1 = [] motor1 = []
motor2 = [] motor2 = []
motor3 = [] motor3 = []
motor4 = [] motor4 = []
for i in 0..100 for i in 0..100
motor1.push(File.read("virt-quad-fifos/pwm-output-motor1").to_i) motor1.push(read_fifo_num(MOTOR1))
motor2.push(File.read("virt-quad-fifos/pwm-output-motor2").to_i) motor2.push(read_fifo_num(MOTOR2))
motor3.push(File.read("virt-quad-fifos/pwm-output-motor3").to_i) motor3.push(read_fifo_num(MOTOR3))
motor4.push(File.read("virt-quad-fifos/pwm-output-motor4").to_i) motor4.push(read_fifo_num(MOTOR4))
sleep 0.005 sleep 0.005
end end
average1 = motor1.inject(:+).to_f / motor1.size average1 = motor1.inject(:+).to_f / motor1.size
...@@ -114,16 +128,16 @@ begin ...@@ -114,16 +128,16 @@ begin
# Check that gear switch kills the motors # Check that gear switch kills the motors
# (and that light goes off) # (and that light goes off)
File.write("virt-quad-fifos/pwm-input-gear", GEAR_OFF) File.write(GEAR, GEAR_OFF)
sleep 0.015 sleep 0.015
check_motors_are_off check_motors_are_off
check_led 0 check_led 0
# (Bring the RC throttle back down) # (Bring the RC throttle back down)
File.write("virt-quad-fifos/pwm-input-throttle", THROTTLE_MIN) File.write(THROTTLE, THROTTLE_MIN)
# Check that we can resume flight # Check that we can resume flight
File.write("virt-quad-fifos/pwm-input-gear", GEAR_ON) File.write(GEAR, GEAR_ON)
sleep 0.015 sleep 0.015
check_led 1 check_led 1
......
...@@ -25,6 +25,7 @@ int unix_mio7_led_reset(struct LEDDriver *self) { ...@@ -25,6 +25,7 @@ int unix_mio7_led_reset(struct LEDDriver *self) {
// Start up worker thread whose job is to update the caches // Start up worker thread whose job is to update the caches
pthread_create(&worker, 0, output_cached_led, NULL); pthread_create(&worker, 0, output_cached_led, NULL);
return 0; return 0;
} }
...@@ -47,12 +48,10 @@ int unix_mio7_led_turn_off(struct LEDDriver *self) { ...@@ -47,12 +48,10 @@ int unix_mio7_led_turn_off(struct LEDDriver *self) {
void * output_cached_led() { void * output_cached_led() {
char buff[16]; char buff[16];
while (1) { while (1) {
usleep(500); // don't spam the reader int fifo = open(led_fifo_name, O_WRONLY);
int fifo = open(led_fifo_name, O_WRONLY | O_NONBLOCK); sprintf(buff, "%d\n", on);
if (fifo >= 0) { write(fifo, buff, strlen(buff));
sprintf(buff, "%d ", on);
write(fifo, buff, strlen(buff));
}
close(fifo); close(fifo);
usleep(500); // don't spam the reader
} }
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <pthread.h> #include <pthread.h>
void * update_input_caches(); void * update_input_cache();
static char *input_names[6]; static char *input_names[6];
static int fifos[6]; static int fifos[6];
...@@ -21,18 +21,13 @@ int unix_pwm_input_reset(struct PWMInputDriver *self) { ...@@ -21,18 +21,13 @@ int unix_pwm_input_reset(struct PWMInputDriver *self) {
input_names[5] = "pwm-input-flap"; input_names[5] = "pwm-input-flap";
mkdir(VIRT_QUAD_FIFOS_DIR, 0777); mkdir(VIRT_QUAD_FIFOS_DIR, 0777);
// Start up worker thread whose job is to update the caches
int i; int i;
for (i = 0; i < 6; i += 1) { for (i = 0; i < 6; i += 1) {
unlink(input_names[i]); pthread_create(&worker, 0, update_input_cache, &i);
char fifoname[64];
sprintf(fifoname, "%s/%s", VIRT_QUAD_FIFOS_DIR, input_names[i]);
mkfifo(fifoname, 0666);
fifos[i] = open(fifoname, O_RDONLY | O_NONBLOCK);
} }
// Start up worker thread whose job is to update the caches
pthread_create(&worker, 0, update_input_caches, NULL);
cache[0] = THROTTLE_MIN; cache[0] = THROTTLE_MIN;
cache[1] = ROLL_CENTER; cache[1] = ROLL_CENTER;
cache[2] = PITCH_CENTER; cache[2] = PITCH_CENTER;
...@@ -55,19 +50,30 @@ int unix_pwm_input_read(struct PWMInputDriver *self, ...@@ -55,19 +50,30 @@ int unix_pwm_input_read(struct PWMInputDriver *self,
return 0; return 0;
} }
void * update_input_caches() { void * update_input_cache(void *arg) {
int *cache_index = arg;
int i = *cache_index;
char buff[16]; char buff[16];
int i;
// Setup FIFO
unlink(input_names[i]);
char fifoname[64];
sprintf(fifoname, "%s/%s", VIRT_QUAD_FIFOS_DIR, input_names[i]);
mkfifo(fifoname, 0666);
fifos[i] = open(fifoname, O_RDONLY);
// Block while waiting for reads
while (1) { while (1) {
for (i = 0; i < 6; i += 1) { int bytes_read = read(fifos[i], buff, 15);
int bytes_read = read(fifos[i], buff, 15); if (bytes_read > 0) {
if (bytes_read >= 6) { buff[bytes_read] = '\0';
buff[bytes_read] = '\0'; unsigned long val = strtoll(buff, NULL, 10);
unsigned long val = strtoll(buff, NULL, 10); if (val < max && val > min) {
if (val < max && val > min) { cache[i] = val;
cache[i] = val; printf("%s: %d\n", input_names[i], val);
printf("%s: %d\n", input_names[i], val); }
} else {
printf("%s: Bad value - input not received\n", input_names[i]);
} }
} }
} }
......
...@@ -6,12 +6,17 @@ ...@@ -6,12 +6,17 @@
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
void * output_caches(); void * output_cache();
static char *output_pwms[4]; static char *output_pwms[4];
static unsigned long cache[4]; static unsigned long cache[4];
pthread_t worker; pthread_t worker;
static int zero = 0;
static int one = 1;
static int two = 2;
static int three = 3;
int unix_pwm_output_reset(struct PWMOutputDriver *self) { int unix_pwm_output_reset(struct PWMOutputDriver *self) {
output_pwms[0] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor1"; output_pwms[0] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor1";
output_pwms[1] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor2"; output_pwms[1] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor2";
...@@ -19,14 +24,12 @@ int unix_pwm_output_reset(struct PWMOutputDriver *self) { ...@@ -19,14 +24,12 @@ int unix_pwm_output_reset(struct PWMOutputDriver *self) {
output_pwms[3] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor4"; output_pwms[3] = VIRT_QUAD_FIFOS_DIR "/pwm-output-motor4";
mkdir(VIRT_QUAD_FIFOS_DIR, 0777); mkdir(VIRT_QUAD_FIFOS_DIR, 0777);
int i;
for (i = 0; i < 4; i += 1) {
unlink(output_pwms[i]);
mkfifo(output_pwms[i], 0666);
}
// Start up worker thread whose job is to update the caches // Start up worker thread whose job is to update the caches
pthread_create(&worker, 0, output_caches, NULL); pthread_create(&worker, 0, output_cache, &zero);
pthread_create(&worker, 0, output_cache, &one);
pthread_create(&worker, 0, output_cache, &two);
pthread_create(&worker, 0, output_cache, &three);
return 0; return 0;
} }
...@@ -41,19 +44,22 @@ int unix_pwm_output_write(struct PWMOutputDriver *self, ...@@ -41,19 +44,22 @@ int unix_pwm_output_write(struct PWMOutputDriver *self,
return 0; return 0;
} }
void * output_caches() { void * output_cache(void *arg) {
int *output_index = arg;
char buff[16]; char buff[16];
int i; int i = *output_index;
// Setup FIFO
unlink(output_pwms[i]);
mkfifo(output_pwms[i], 0666);
// Block while waiting for someone to listen
while (1) { while (1) {
int fifo = open(output_pwms[i], O_WRONLY);
sprintf(buff, "%ld\n", cache[i]);
write(fifo, buff, strlen(buff));
close(fifo);
usleep(500); // don't spam the reader usleep(500); // don't spam the reader
for (i = 0; i < 4; i += 1) {
int fifo = open(output_pwms[i], O_WRONLY | O_NONBLOCK);
if (fifo >= 0) {
sprintf(buff, " %ld ", cache[i]);
write(fifo, buff, strlen(buff));
}
close(fifo);
}
} }
return NULL; return NULL;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment