Make NuttX drivers cross platform (VDev -> CDev)

This commit is contained in:
Daniel Agar
2017-08-31 09:27:36 +02:00
committed by Lorenz Meier
parent 6562dd496b
commit 07619cf723
29 changed files with 216 additions and 306 deletions
+9
View File
@@ -35,7 +35,16 @@
#ifdef __PX4_NUTTX
#include "device_nuttx.h"
#include <nuttx/arch.h>
#define ATOMIC_ENTER irqstate_t flags = px4_enter_critical_section()
#define ATOMIC_LEAVE px4_leave_critical_section(flags)
#elif defined (__PX4_POSIX)
#include "vdev.h"
#define ATOMIC_ENTER lock()
#define ATOMIC_LEAVE unlock()
#endif
+21 -17
View File
@@ -64,9 +64,10 @@ namespace device
I2C::I2C(const char *name,
const char *devname,
int bus,
uint16_t address) :
uint16_t address,
uint32_t frequency) :
// base class
VDev(name, devname),
CDev(name, devname),
// public
// protected
_retries(0),
@@ -75,7 +76,7 @@ I2C::I2C(const char *name,
_address(address),
_fd(-1)
{
//warnx("I2C::I2C name = %s devname = %s", name, devname);
DEVICE_DEBUG("I2C::I2C name = %s devname = %s", name, devname);
// fill in _device_id fields for a I2C device
_device_id.devid_s.bus_type = DeviceBusType_I2C;
_device_id.devid_s.bus = bus;
@@ -103,10 +104,10 @@ I2C::init()
// way to set it from user space.
// do base class init, which will create device node, etc
ret = VDev::init();
ret = CDev::init();
if (ret != PX4_OK) {
DEVICE_DEBUG("VDev::init failed");
DEVICE_DEBUG("CDev::init failed");
return ret;
}
@@ -146,12 +147,12 @@ I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned re
unsigned retry_count = 0;
if (_fd < 0) {
warnx("I2C device not opened");
PX4_ERR("I2C device not opened");
return 1;
}
do {
// DEVICE_DEBUG("transfer out %p/%u in %p/%u", send, send_len, recv, recv_len);
DEVICE_DEBUG("transfer out %p/%u in %p/%u", send, send_len, recv, recv_len);
msgs = 0;
if (send_len > 0) {
@@ -178,15 +179,18 @@ I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned re
packets.nmsgs = msgs;
if (simulate) {
//warnx("I2C SIM: transfer_4 on %s", get_devname());
DEVICE_DEBUG("I2C SIM: transfer_4 on %s", get_devname());
ret = PX4_OK;
} else {
ret = ::ioctl(_fd, I2C_RDWR, (unsigned long)&packets);
if (ret < 0) {
warnx("I2C transfer failed");
return 1;
if (ret == -1) {
DEVICE_DEBUG("I2C transfer failed");
ret = PX4_ERROR;
} else {
ret = PX4_OK;
}
}
@@ -221,7 +225,7 @@ I2C::transfer(struct i2c_msg *msgv, unsigned msgs)
packets.nmsgs = msgs;
if (simulate) {
warnx("I2C SIM: transfer_2 on %s", get_devname());
DEVICE_DEBUG("I2C SIM: transfer_2 on %s", get_devname());
ret = PX4_OK;
} else {
@@ -229,7 +233,7 @@ I2C::transfer(struct i2c_msg *msgv, unsigned msgs)
}
if (ret < 0) {
warnx("I2C transfer failed");
DEVICE_DEBUG("I2C transfer failed");
return 1;
}
@@ -251,13 +255,13 @@ int I2C::ioctl(device::file_t *filp, int cmd, unsigned long arg)
#ifdef __PX4_LINUX
case I2C_RDWR:
warnx("Use I2C::transfer, not ioctl");
DEVICE_DEBUG("Use I2C::transfer, not ioctl");
return 0;
#endif
default:
/* give it to the superclass */
return VDev::ioctl(filp, cmd, arg);
return CDev::ioctl(filp, cmd, arg);
}
}
@@ -265,7 +269,7 @@ ssize_t I2C::read(file_t *filp, char *buffer, size_t buflen)
{
if (simulate) {
// FIXME no idea what this should be
warnx("2C SIM I2C::read");
DEVICE_DEBUG("2C SIM I2C::read");
return 0;
}
@@ -279,7 +283,7 @@ ssize_t I2C::read(file_t *filp, char *buffer, size_t buflen)
ssize_t I2C::write(file_t *filp, const char *buffer, size_t buflen)
{
if (simulate) {
warnx("2C SIM I2C::write");
DEVICE_DEBUG("2C SIM I2C::write");
return buflen;
}
+17 -2
View File
@@ -55,7 +55,7 @@ namespace device __EXPORT
/**
* Abstract class for character device on I2C
*/
class __EXPORT I2C : public VDev
class __EXPORT I2C : public CDev
{
public:
@@ -88,7 +88,8 @@ protected:
I2C(const char *name,
const char *devname,
int bus,
uint16_t address);
uint16_t address,
uint32_t frequency = 0);
virtual ~I2C();
virtual int init();
@@ -122,6 +123,20 @@ protected:
*/
int transfer(struct i2c_msg *msgv, unsigned msgs);
/**
* Change the bus address.
*
* Most often useful during probe() when the driver is testing
* several possible bus addresses.
*
* @param address The new bus address to set.
*/
void set_address(uint16_t address)
{
_address = address;
_device_id.devid_s.address = _address;
}
private:
uint16_t _address;
int _fd;
+1 -1
View File
@@ -88,7 +88,7 @@ SIM::init()
ret = Device::init();
if (ret != PX4_OK) {
PX4_ERR("VDev::init failed");
PX4_ERR("CDev::init failed");
return ret;
}
-4
View File
@@ -50,11 +50,7 @@ namespace device __EXPORT
/**
* Abstract class for character device on SPI
*/
#ifdef __PX4_NUTTX
class __EXPORT SPI : public CDev
#else
class __EXPORT SPI : public VDev
#endif
{
protected:
/**
+53 -53
View File
@@ -61,7 +61,7 @@ static map<string, void *> devmap;
pthread_mutex_t devmutex = PTHREAD_MUTEX_INITIALIZER;
VDev::VDev(const char *name,
CDev::CDev(const char *name,
const char *devname) :
// base class
Device(name),
@@ -75,12 +75,12 @@ VDev::VDev(const char *name,
_open_count(0),
_pollset(nullptr)
{
PX4_DEBUG("VDev::VDev");
DEVICE_DEBUG("CDev::CDev");
}
VDev::~VDev()
CDev::~CDev()
{
PX4_DEBUG("VDev::~VDev");
DEVICE_DEBUG("CDev::~CDev");
if (_registered) {
unregister_driver(_devname);
@@ -92,9 +92,9 @@ VDev::~VDev()
}
int
VDev::register_class_devname(const char *class_devname)
CDev::register_class_devname(const char *class_devname)
{
PX4_DEBUG("VDev::register_class_devname %s", class_devname);
DEVICE_DEBUG("CDev::register_class_devname %s", class_devname);
if (class_devname == nullptr) {
return -EINVAL;
@@ -121,9 +121,9 @@ VDev::register_class_devname(const char *class_devname)
}
int
VDev::register_driver(const char *name, void *data)
CDev::register_driver(const char *name, void *data)
{
PX4_DEBUG("VDev::register_driver %s", name);
DEVICE_DEBUG("CDev::register_driver %s", name);
int ret = 0;
if (name == nullptr || data == nullptr) {
@@ -141,7 +141,7 @@ VDev::register_driver(const char *name, void *data)
}
devmap[name] = (void *)data;
PX4_DEBUG("Registered DEV %s", name);
DEVICE_DEBUG("Registered DEV %s", name);
pthread_mutex_unlock(&devmutex);
@@ -149,9 +149,9 @@ VDev::register_driver(const char *name, void *data)
}
int
VDev::unregister_driver(const char *name)
CDev::unregister_driver(const char *name)
{
PX4_DEBUG("VDev::unregister_driver %s", name);
DEVICE_DEBUG("CDev::unregister_driver %s", name);
int ret = -EINVAL;
if (name == nullptr) {
@@ -161,7 +161,7 @@ VDev::unregister_driver(const char *name)
pthread_mutex_lock(&devmutex);
if (devmap.erase(name) > 0) {
PX4_DEBUG("Unregistered DEV %s", name);
DEVICE_DEBUG("Unregistered DEV %s", name);
ret = 0;
}
@@ -171,9 +171,9 @@ VDev::unregister_driver(const char *name)
}
int
VDev::unregister_class_devname(const char *class_devname, unsigned class_instance)
CDev::unregister_class_devname(const char *class_devname, unsigned class_instance)
{
PX4_DEBUG("VDev::unregister_class_devname");
DEVICE_DEBUG("CDev::unregister_class_devname");
char name[32];
snprintf(name, sizeof(name), "%s%u", class_devname, class_instance);
int ret = -EINVAL;
@@ -182,7 +182,7 @@ VDev::unregister_class_devname(const char *class_devname, unsigned class_instanc
pthread_mutex_lock(&devmutex);
if (devmap.erase(name) > 0) {
PX4_DEBUG("Unregistered class DEV %s", name);
DEVICE_DEBUG("Unregistered class DEV %s", name);
ret = 0;
}
@@ -192,9 +192,9 @@ VDev::unregister_class_devname(const char *class_devname, unsigned class_instanc
}
int
VDev::init()
CDev::init()
{
PX4_DEBUG("VDev::init");
DEVICE_DEBUG("CDev::init");
// base class init first
int ret = Device::init();
@@ -222,9 +222,9 @@ out:
* Default implementations of the character device interface
*/
int
VDev::open(file_t *filep)
CDev::open(file_t *filep)
{
PX4_DEBUG("VDev::open");
DEVICE_DEBUG("CDev::open");
int ret = PX4_OK;
lock();
@@ -247,16 +247,16 @@ VDev::open(file_t *filep)
}
int
VDev::open_first(file_t *filep)
CDev::open_first(file_t *filep)
{
PX4_DEBUG("VDev::open_first");
DEVICE_DEBUG("CDev::open_first");
return PX4_OK;
}
int
VDev::close(file_t *filep)
CDev::close(file_t *filep)
{
PX4_DEBUG("VDev::close");
DEVICE_DEBUG("CDev::close");
int ret = PX4_OK;
lock();
@@ -280,37 +280,37 @@ VDev::close(file_t *filep)
}
int
VDev::close_last(file_t *filep)
CDev::close_last(file_t *filep)
{
PX4_DEBUG("VDev::close_last");
DEVICE_DEBUG("CDev::close_last");
return PX4_OK;
}
ssize_t
VDev::read(file_t *filep, char *buffer, size_t buflen)
CDev::read(file_t *filep, char *buffer, size_t buflen)
{
PX4_DEBUG("VDev::read");
DEVICE_DEBUG("CDev::read");
return -ENOSYS;
}
ssize_t
VDev::write(file_t *filep, const char *buffer, size_t buflen)
CDev::write(file_t *filep, const char *buffer, size_t buflen)
{
PX4_DEBUG("VDev::write");
DEVICE_DEBUG("CDev::write");
return -ENOSYS;
}
off_t
VDev::seek(file_t *filep, off_t offset, int whence)
CDev::seek(file_t *filep, off_t offset, int whence)
{
PX4_DEBUG("VDev::seek");
DEVICE_DEBUG("CDev::seek");
return -ENOSYS;
}
int
VDev::ioctl(file_t *filep, int cmd, unsigned long arg)
CDev::ioctl(file_t *filep, int cmd, unsigned long arg)
{
PX4_DEBUG("VDev::ioctl");
DEVICE_DEBUG("CDev::ioctl");
int ret = -ENOTTY;
switch (cmd) {
@@ -342,9 +342,9 @@ VDev::ioctl(file_t *filep, int cmd, unsigned long arg)
}
int
VDev::poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
CDev::poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
{
PX4_DEBUG("VDev::Poll %s", setup ? "setup" : "teardown");
DEVICE_DEBUG("CDev::Poll %s", setup ? "setup" : "teardown");
int ret = PX4_OK;
/*
@@ -358,7 +358,7 @@ VDev::poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
* benefit.
*/
fds->priv = (void *)filep;
PX4_DEBUG("VDev::poll: fds->priv = %p", filep);
DEVICE_DEBUG("CDev::poll: fds->priv = %p", filep);
/*
* Handle setup requests.
@@ -395,9 +395,9 @@ VDev::poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
}
void
VDev::poll_notify(pollevent_t events)
CDev::poll_notify(pollevent_t events)
{
PX4_DEBUG("VDev::poll_notify events = %0x", events);
DEVICE_DEBUG("CDev::poll_notify events = %0x", events);
/* lock against poll() as well as other wakeups */
lock();
@@ -412,16 +412,16 @@ VDev::poll_notify(pollevent_t events)
}
void
VDev::poll_notify_one(px4_pollfd_struct_t *fds, pollevent_t events)
CDev::poll_notify_one(px4_pollfd_struct_t *fds, pollevent_t events)
{
PX4_DEBUG("VDev::poll_notify_one");
DEVICE_DEBUG("CDev::poll_notify_one");
int value;
px4_sem_getvalue(fds->sem, &value);
/* update the reported event set */
fds->revents |= fds->events & events;
PX4_DEBUG(" Events fds=%p %0x %0x %0x %d", fds, fds->revents, fds->events, events, value);
DEVICE_DEBUG(" Events fds=%p %0x %0x %0x %d", fds, fds->revents, fds->events, events, value);
/* if the state is now interesting, wake the waiter if it's still asleep */
/* XXX semcount check here is a vile hack; counting semphores should not be abused as cvars */
@@ -431,20 +431,20 @@ VDev::poll_notify_one(px4_pollfd_struct_t *fds, pollevent_t events)
}
pollevent_t
VDev::poll_state(file_t *filep)
CDev::poll_state(file_t *filep)
{
PX4_DEBUG("VDev::poll_notify");
DEVICE_DEBUG("CDev::poll_notify");
/* by default, no poll events to report */
return 0;
}
int
VDev::store_poll_waiter(px4_pollfd_struct_t *fds)
CDev::store_poll_waiter(px4_pollfd_struct_t *fds)
{
/*
* Look for a free slot.
*/
PX4_DEBUG("VDev::store_poll_waiter");
DEVICE_DEBUG("CDev::store_poll_waiter");
for (unsigned i = 0; i < _max_pollwaiters; i++) {
if (nullptr == _pollset[i]) {
@@ -482,9 +482,9 @@ VDev::store_poll_waiter(px4_pollfd_struct_t *fds)
}
int
VDev::remove_poll_waiter(px4_pollfd_struct_t *fds)
CDev::remove_poll_waiter(px4_pollfd_struct_t *fds)
{
PX4_DEBUG("VDev::remove_poll_waiter");
DEVICE_DEBUG("CDev::remove_poll_waiter");
for (unsigned i = 0; i < _max_pollwaiters; i++) {
if (fds == _pollset[i]) {
@@ -499,9 +499,9 @@ VDev::remove_poll_waiter(px4_pollfd_struct_t *fds)
return -EINVAL;
}
VDev *VDev::getDev(const char *path)
CDev *CDev::getDev(const char *path)
{
PX4_DEBUG("VDev::getDev");
PX4_DEBUG("CDev::getDev");
pthread_mutex_lock(&devmutex);
@@ -509,7 +509,7 @@ VDev *VDev::getDev(const char *path)
if (item != devmap.end()) {
pthread_mutex_unlock(&devmutex);
return (VDev *)item->second;
return (CDev *)item->second;
}
pthread_mutex_unlock(&devmutex);
@@ -517,7 +517,7 @@ VDev *VDev::getDev(const char *path)
return nullptr;
}
void VDev::showDevices()
void CDev::showDevices()
{
int i = 0;
PX4_INFO("PX4 Devices:");
@@ -547,7 +547,7 @@ void VDev::showDevices()
} while (i == 0);
}
void VDev::showTopics()
void CDev::showTopics()
{
PX4_INFO("Devices:");
@@ -562,7 +562,7 @@ void VDev::showTopics()
pthread_mutex_unlock(&devmutex);
}
void VDev::showFiles()
void CDev::showFiles()
{
PX4_INFO("Files:");
+6 -6
View File
@@ -209,7 +209,7 @@ private:
/**
* Abstract class for any virtual character device
*/
class __EXPORT VDev : public Device
class __EXPORT CDev : public Device
{
public:
/**
@@ -218,12 +218,12 @@ public:
* @param name Driver name
* @param devname Device node name
*/
VDev(const char *name, const char *devname);
CDev(const char *name, const char *devname);
/**
* Destructor
*/
virtual ~VDev();
virtual ~CDev();
virtual int init();
@@ -322,7 +322,7 @@ public:
*/
virtual int ioctl(file_t *filep, int cmd, unsigned long arg);
static VDev *getDev(const char *path);
static CDev *getDev(const char *path);
static void showFiles(void);
static void showDevices(void);
static void showTopics(void);
@@ -447,8 +447,8 @@ private:
int remove_poll_waiter(px4_pollfd_struct_t *fds);
/* do not allow copying this class */
VDev(const VDev &);
//VDev operator=(const VDev&);
CDev(const CDev &);
//CDev operator=(const CDev&);
};
#if 0
+16 -16
View File
@@ -72,14 +72,14 @@ extern "C" {
return ret;
}
inline VDev *get_vdev(int fd)
inline CDev *get_vdev(int fd)
{
pthread_mutex_lock(&filemutex);
bool valid = (fd < PX4_MAX_FD && fd >= 0 && filemap[fd] != nullptr);
VDev *dev;
CDev *dev;
if (valid) {
dev = (VDev *)(filemap[fd]->vdev);
dev = (CDev *)(filemap[fd]->vdev);
} else {
dev = nullptr;
@@ -92,7 +92,7 @@ extern "C" {
int px4_open(const char *path, int flags, ...)
{
PX4_DEBUG("px4_open");
VDev *dev = VDev::getDev(path);
CDev *dev = CDev::getDev(path);
int ret = 0;
int i;
mode_t mode;
@@ -163,7 +163,7 @@ extern "C" {
{
int ret;
VDev *dev = get_vdev(fd);
CDev *dev = get_vdev(fd);
if (dev) {
pthread_mutex_lock(&filemutex);
@@ -193,7 +193,7 @@ extern "C" {
{
int ret;
VDev *dev = get_vdev(fd);
CDev *dev = get_vdev(fd);
if (dev) {
PX4_DEBUG("px4_read fd = %d", fd);
@@ -215,7 +215,7 @@ extern "C" {
{
int ret;
VDev *dev = get_vdev(fd);
CDev *dev = get_vdev(fd);
if (dev) {
PX4_DEBUG("px4_write fd = %d", fd);
@@ -238,7 +238,7 @@ extern "C" {
PX4_DEBUG("px4_ioctl fd = %d", fd);
int ret = 0;
VDev *dev = get_vdev(fd);
CDev *dev = get_vdev(fd);
if (dev) {
ret = dev->ioctl(filemap[fd], cmd, arg);
@@ -297,11 +297,11 @@ extern "C" {
fds[i].revents = 0;
fds[i].priv = nullptr;
VDev *dev = get_vdev(fds[i].fd);
CDev *dev = get_vdev(fds[i].fd);
// If fd is valid
if (dev) {
PX4_DEBUG("%s: px4_poll: VDev->poll(setup) %d", thread_name, fds[i].fd);
PX4_DEBUG("%s: px4_poll: CDev->poll(setup) %d", thread_name, fds[i].fd);
ret = dev->poll(filemap[fds[i].fd], &fds[i], true);
if (ret < 0) {
@@ -358,11 +358,11 @@ extern "C" {
// go through all fds and count how many have data
for (i = 0; i < nfds; ++i) {
VDev *dev = get_vdev(fds[i].fd);
CDev *dev = get_vdev(fds[i].fd);
// If fd is valid
if (dev) {
PX4_DEBUG("%s: px4_poll: VDev->poll(teardown) %d", thread_name, fds[i].fd);
PX4_DEBUG("%s: px4_poll: CDev->poll(teardown) %d", thread_name, fds[i].fd);
ret = dev->poll(filemap[fds[i].fd], &fds[i], false);
if (ret < 0) {
@@ -396,23 +396,23 @@ extern "C" {
return -1;
}
VDev *dev = VDev::getDev(pathname);
CDev *dev = CDev::getDev(pathname);
return (dev != nullptr) ? 0 : -1;
}
void px4_show_devices()
{
VDev::showDevices();
CDev::showDevices();
}
void px4_show_topics()
{
VDev::showTopics();
CDev::showTopics();
}
void px4_show_files()
{
VDev::showFiles();
CDev::showFiles();
}
void px4_enable_sim_lockstep()
+1 -1
View File
@@ -44,7 +44,7 @@
using namespace device;
VFile::VFile(const char *fname, mode_t mode) :
VDev("vfile", fname)
CDev("vfile", fname)
{
}
+1 -1
View File
@@ -44,7 +44,7 @@
#include <unistd.h>
#include <stdio.h>
class VFile : public device::VDev
class VFile : public device::CDev
{
public: