add blocking option to i2c, remove unnecesary GNU_SOURCE and protect pthread_setname from mac (#2260)

* add blocking option to i2c with configurable timeout
* remove unnecesary GNU_SOURCE
* protect pthread_setname from mac
This commit is contained in:
Kirk Scheper
2018-05-09 16:58:06 +02:00
committed by Gautier Hattenberger
parent f03b3876bf
commit 1d66b19adc
20 changed files with 130 additions and 63 deletions

View File

@@ -47,6 +47,7 @@ CFLAGS += -O$(OPT)
CFLAGS += $(DEBUG_FLAGS)
CFLAGS += -std=gnu99
CFLAGS += $(shell pkg-config --cflags-only-I ivy-glib)
CFLAGS += -D_GNU_SOURCE
CXXFLAGS = $(WARN_FLAGS)
CXXFLAGS += $(INCLUDES)
@@ -56,6 +57,7 @@ CXXFLAGS += $(USER_CFLAGS) $(BOARD_CFLAGS)
CXXFLAGS += -O$(OPT)
CXXFLAGS += $(DEBUG_FLAGS)
CXXFLAGS += $(shell pkg-config --cflags-only-I ivy-glib)
CXXFLAGS += -D_GNU_SOURCE
LDFLAGS += $($(TARGET).LDFLAGS)
LDFLAGS += $(BOARD_LDFLAGS)

View File

@@ -56,6 +56,7 @@ CFLAGS += -O$(OPT)
CFLAGS += -g
CFLAGS += -std=gnu99
CFLAGS += $(shell pkg-config --cflags-only-I ivy-glib)
CFLAGS += -D_GNU_SOURCE
LDFLAGS = -lm
LDFLAGS += $(BOARD_LDFLAGS)

View File

@@ -33,8 +33,6 @@
#ifndef I2C_HW_H
#define I2C_HW_H
#include "mcu_periph/i2c.h"
#if USE_I2C1
extern void i2c1_hw_init(void);
#endif /* USE_I2C1 */

View File

@@ -35,10 +35,6 @@
#include <linux/i2c-dev.h>
#include <errno.h>
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include "rt_priority.h"

View File

@@ -28,8 +28,6 @@
#ifndef LINUX_MCU_PERIPH_I2C_ARCH_H
#define LINUX_MCU_PERIPH_I2C_ARCH_H
#include "mcu_periph/i2c.h"
#if USE_I2C0
extern void i2c0_hw_init(void);
#endif /* USE_I2C0 */

View File

@@ -26,10 +26,6 @@
#include "mcu_periph/sys_time.h"
#include <stdio.h>
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include <sys/timerfd.h>
#include <time.h>
@@ -107,7 +103,9 @@ void sys_time_arch_init(void)
perror("Could not setup sys_time_thread");
return;
}
#ifndef MACOSX
pthread_setname_np(tid, "pprz_sys_time_thread");
#endif
}
static void sys_tick_handler(void)

View File

@@ -23,11 +23,6 @@
* linux uart handling
*/
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include BOARD_CONFIG
#include "mcu_periph/uart.h"
@@ -65,7 +60,9 @@ void uart_arch_init(void)
fprintf(stderr, "uart_arch_init: Could not create UART reading thread.\n");
return;
}
#ifndef MACOSX
pthread_setname_np(tid, "pprz_uart_thread");
#endif
}
static void *uart_thread(void *data __attribute__((unused)))

View File

@@ -23,11 +23,6 @@
* linux UDP handling
*/
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include "mcu_periph/udp.h"
#include "udp_socket.h"
#include <stdlib.h>

View File

@@ -28,8 +28,6 @@
#ifndef SIM_MCU_PERIPH_I2C_ARCH_H
#define SIM_MCU_PERIPH_I2C_ARCH_H
#include "mcu_periph/i2c.h"
#define I2cSendStart() {}

View File

@@ -29,7 +29,6 @@
#ifndef I2C_HW_H
#define I2C_HW_H
#include "mcu_periph/i2c.h"
#include <libopencm3/stm32/i2c.h>
#if USE_I2C1

View File

@@ -39,10 +39,6 @@
#include <math.h>
#include <errno.h>
#include <assert.h>
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include "std.h"

View File

@@ -74,7 +74,7 @@ void actuators_bebop_commit(void)
{
// Receive the status
actuators_bebop.i2c_trans.buf[0] = ACTUATORS_BEBOP_GET_OBS_DATA;
i2c_transceive(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 1, 13);
i2c_blocking_transceive(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 1, 13);
// Update status
electrical.vsupply = (actuators_bebop.i2c_trans.buf[9] + (actuators_bebop.i2c_trans.buf[8] << 8)) / 100;
@@ -94,7 +94,7 @@ void actuators_bebop_commit(void)
if (actuators_bebop.i2c_trans.buf[10] != 4 && actuators_bebop.i2c_trans.buf[10] != 2 && autopilot_get_motors_on()) {
// Reset the error
actuators_bebop.i2c_trans.buf[0] = ACTUATORS_BEBOP_CLEAR_ERROR;
i2c_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 1);
i2c_blocking_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 1);
// Start the motors
actuators_bebop.i2c_trans.buf[0] = ACTUATORS_BEBOP_START_PROP;
@@ -104,12 +104,12 @@ void actuators_bebop_commit(void)
#else
actuators_bebop.i2c_trans.buf[1] = 0b00000101;
#endif
i2c_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 2);
i2c_blocking_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 2);
}
// Stop the motors
else if (actuators_bebop.i2c_trans.buf[10] == 4 && !autopilot_get_motors_on()) {
actuators_bebop.i2c_trans.buf[0] = ACTUATORS_BEBOP_STOP_PROP;
i2c_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 1);
i2c_blocking_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 1);
} else if (actuators_bebop.i2c_trans.buf[10] == 4 && autopilot_get_motors_on()) {
// Send the commands
actuators_bebop.i2c_trans.buf[0] = ACTUATORS_BEBOP_SET_REF_SPEED;
@@ -126,14 +126,14 @@ void actuators_bebop_commit(void)
#pragma GCC diagnostic ignored "-Wcast-qual"
actuators_bebop.i2c_trans.buf[10] = actuators_bebop_checksum((uint8_t *)actuators_bebop.i2c_trans.buf, 9);
#pragma GCC diagnostic pop
i2c_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 11);
i2c_blocking_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 11);
}
// Update the LEDs
if (actuators_bebop.led != (led_hw_values & 0x3)) {
actuators_bebop.i2c_trans.buf[0] = ACTUATORS_BEBOP_TOGGLE_GPIO;
actuators_bebop.i2c_trans.buf[1] = (led_hw_values & 0x3);
i2c_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 2);
i2c_blocking_transmit(&i2c1, &actuators_bebop.i2c_trans, actuators_bebop.i2c_trans.slave_addr, 2);
actuators_bebop.led = led_hw_values & 0x3;
}

View File

@@ -92,7 +92,7 @@ static void write_reg(struct mt9f002_t *mt, uint16_t addr, uint32_t val, uint8_t
}
// Transmit the buffer
i2c_transmit(mt->i2c_periph, &mt->i2c_trans, MT9F002_ADDRESS, len + 2);
i2c_blocking_transmit(mt->i2c_periph, &mt->i2c_trans, MT9F002_ADDRESS, len + 2);
}
/**
@@ -105,7 +105,7 @@ static uint32_t read_reg(struct mt9f002_t *mt, uint16_t addr, uint8_t len)
mt->i2c_trans.buf[1] = addr & 0xFF;
// Transmit the buffer and receive back
i2c_transceive(mt->i2c_periph, &mt->i2c_trans, MT9F002_ADDRESS, 2, len);
i2c_blocking_transceive(mt->i2c_periph, &mt->i2c_trans, MT9F002_ADDRESS, 2, len);
/* Fix sigdness */
for (uint8_t i = 0; i < len; i++) {

View File

@@ -214,7 +214,7 @@ static void write_reg(struct mt9v117_t *mt, uint16_t addr, uint32_t val, uint16_
}
// Transmit the buffer
i2c_transmit(mt->i2c_periph, &mt->i2c_trans, MT9V117_ADDRESS, len + 2);
i2c_blocking_transmit(mt->i2c_periph, &mt->i2c_trans, MT9V117_ADDRESS, len + 2);
}
/**
@@ -227,7 +227,7 @@ static uint32_t read_reg(struct mt9v117_t *mt, uint16_t addr, uint16_t len)
mt->i2c_trans.buf[1] = addr & 0xFF;
// Transmit the buffer and receive back
i2c_transceive(mt->i2c_periph, &mt->i2c_trans, MT9V117_ADDRESS, 2, len);
i2c_blocking_transceive(mt->i2c_periph, &mt->i2c_trans, MT9V117_ADDRESS, 2, len);
/* Fix sigdness */
for (uint8_t i = 0; i < len; i++) {
@@ -285,7 +285,7 @@ static inline void mt9v117_write_patch(struct mt9v117_t *mt)
}
// Transmit the buffer
i2c_transmit(mt->i2c_periph, &mt->i2c_trans, mt->i2c_trans.slave_addr, mt9v117_patch_lines[i].len);
i2c_blocking_transmit(mt->i2c_periph, &mt->i2c_trans, mt->i2c_trans.slave_addr, mt9v117_patch_lines[i].len);
}
write_reg(mt, MT9V117_LOGICAL_ADDRESS_ACCESS, 0x0000, 2);

View File

@@ -32,10 +32,6 @@
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include <linux/input.h>

View File

@@ -32,10 +32,6 @@
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include <linux/input.h>
#include "subsystems/electrical.h"

View File

@@ -26,6 +26,7 @@
*/
#include "mcu_periph/i2c.h"
#include "mcu_periph/sys_time.h"
#if PERIODIC_TELEMETRY
#include "subsystems/datalink/telemetry.h"
@@ -285,3 +286,71 @@ bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t,
t->len_r = len_r;
return i2c_submit(p, t);
}
/** Default timeout for blocking I2C transactions */
#ifndef I2C_BLOCKING_TIMEOUT
#define I2C_BLOCKING_TIMEOUT 1.f
#endif
bool i2c_blocking_transmit(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint8_t len)
{
t->type = I2CTransTx;
t->slave_addr = s_addr;
t->len_w = len;
t->len_r = 0;
if (!i2c_submit(p, t)) {
return false;
}
// Wait for transaction to complete
float start_t = get_sys_time_float();
while (t->status == I2CTransPending || t->status == I2CTransRunning) {
if (get_sys_time_float() - start_t > I2C_BLOCKING_TIMEOUT) {
break; // timeout after 1 second
}
}
return true;
}
bool i2c_blocking_receive(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint16_t len)
{
t->type = I2CTransRx;
t->slave_addr = s_addr;
t->len_w = 0;
t->len_r = len;
if (!i2c_submit(p, t)) {
return false;
}
// Wait for transaction to complete
float start_t = get_sys_time_float();
while (t->status == I2CTransPending || t->status == I2CTransRunning) {
if (get_sys_time_float() - start_t > I2C_BLOCKING_TIMEOUT) {
break; // timeout after 1 second
}
}
return true;
}
bool i2c_blocking_transceive(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint8_t len_w, uint16_t len_r)
{
t->type = I2CTransTxRx;
t->slave_addr = s_addr;
t->len_w = len_w;
t->len_r = len_r;
if (!i2c_submit(p, t)) {
return false;
}
// Wait for transaction to complete
float start_t = get_sys_time_float();
while (t->status == I2CTransPending || t->status == I2CTransRunning) {
if (get_sys_time_float() - start_t > I2C_BLOCKING_TIMEOUT) {
break; // timeout after 1 second
}
}
return true;
}

View File

@@ -228,7 +228,7 @@ extern bool i2c_idle(struct i2c_periph *p);
* Must be implemented by the underlying architecture
* @param p i2c peripheral to be used
* @param t i2c transaction
* @return TRUE if insertion to the transaction queue succeded
* @return TRUE if insertion to the transaction queue succeeded
*/
extern bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t);
@@ -253,10 +253,10 @@ extern void i2c_event(void);
* @param t i2c transaction
* @param s_addr slave address
* @param len number of bytes to transmit
* @return TRUE if insertion to the transaction queue succeded
* @return TRUE if insertion to the transaction queue succeeded
*/
extern bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint8_t len);
uint8_t s_addr, uint8_t len);
/** Submit a read only transaction.
* Convenience function which is usually preferred over i2c_submit,
@@ -265,10 +265,10 @@ extern bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t,
* @param t i2c transaction
* @param s_addr slave address
* @param len number of bytes to receive
* @return TRUE if insertion to the transaction queue succeded
* @return TRUE if insertion to the transaction queue succeeded
*/
extern bool i2c_receive(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint16_t len);
uint8_t s_addr, uint16_t len);
/** Submit a write/read transaction.
* Convenience function which is usually preferred over i2c_submit,
@@ -278,11 +278,47 @@ extern bool i2c_receive(struct i2c_periph *p, struct i2c_transaction *t,
* @param s_addr slave address
* @param len_w number of bytes to transmit
* @param len_r number of bytes to receive
* @return TRUE if insertion to the transaction queue succeded
* @return TRUE if insertion to the transaction queue succeeded
*/
extern bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint8_t len_w, uint16_t len_r);
uint8_t s_addr, uint8_t len_w, uint16_t len_r);
/** Submit a write only transaction and wait for it to complete.
* Convenience function which is usually preferred over i2c_submit,
* as it explicitly sets the transaction type again.
* @param p i2c peripheral to be used
* @param t i2c transaction
* @param s_addr slave address
* @param len number of bytes to transmit
* @return TRUE if insertion to the transaction queue succeeded
*/
bool i2c_blocking_transmit(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint8_t len);
/** Submit a read only transaction and wait for it to complete.
* Convenience function which is usually preferred over i2c_submit,
* as it explicitly sets the transaction type again.
* @param p i2c peripheral to be used
* @param t i2c transaction
* @param s_addr slave address
* @param len number of bytes to receive
* @return TRUE if insertion to the transaction queue succeeded
*/
bool i2c_blocking_receive(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint16_t len);
/** Submit a write/read transaction and wait for it to complete.
* Convenience function which is usually preferred over i2c_submit,
* as it explicitly sets the transaction type again.
* @param p i2c peripheral to be used
* @param t i2c transaction
* @param s_addr slave address
* @param len_w number of bytes to transmit
* @param len_r number of bytes to receive
* @return TRUE if insertion to the transaction queue succeeded
*/
bool i2c_blocking_transceive(struct i2c_periph *p, struct i2c_transaction *t,
uint8_t s_addr, uint8_t len_w, uint16_t len_r);
/** @}*/
/** @}*/

View File

@@ -50,10 +50,6 @@
#endif
// Threaded computer vision
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include "rt_priority.h"

View File

@@ -37,10 +37,6 @@
#include "mcu_periph/adc.h"
#include "mcu_periph/spi.h"
#include "subsystems/abi.h"
#ifndef _GNU_SOURCE
// for pthread_setname_np
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include "subsystems/datalink/downlink.h"