version 1.15.0_alpha
add PIGPIO class gcc warnings fix
This commit is contained in:
@@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0)
|
||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||
project(pip)
|
||||
set(_PIP_MAJOR 1)
|
||||
set(_PIP_MINOR 14)
|
||||
set(_PIP_MINOR 15)
|
||||
set(_PIP_REVISION 0)
|
||||
set(_PIP_SUFFIX beta)
|
||||
set(_PIP_SUFFIX alpha)
|
||||
set(_PIP_COMPANY SHS)
|
||||
set(_PIP_DOMAIN org.SHS)
|
||||
|
||||
@@ -84,6 +84,8 @@ set(PIP_SRC_DIRS "src_main" "src_crypt" "src_compress" "src_usb" "src_fftw" "src
|
||||
set(PIP_LIBS_TARGETS pip)
|
||||
set(LIBS_MAIN)
|
||||
set(LIBS_STATUS)
|
||||
set(HDRS)
|
||||
set(PHDRS)
|
||||
|
||||
if (TESTS)
|
||||
set(PIP_SRC_CONCURRENT_TEST "src_concurrent/test")
|
||||
@@ -110,12 +112,16 @@ set_version(PIP
|
||||
REVISION "${_PIP_REVISION}"
|
||||
BUILD "${BUILD_NUMBER}"
|
||||
SUFFIX "${_PIP_SUFFIX}"
|
||||
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h")
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/piversion.h")
|
||||
set_deploy_property(pip ${PIP_LIB_TYPE}
|
||||
LABEL "PIP main library"
|
||||
FULLNAME "${_PIP_DOMAIN}.pip"
|
||||
COMPANY "${_PIP_COMPANY}"
|
||||
INFO "Platform-Independent Primitives")
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h")
|
||||
file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h")
|
||||
endif()
|
||||
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/piversion.h")
|
||||
message(STATUS "Building PIP version ${PIP_VERSION} (${PIP_LIB_TYPE})")
|
||||
|
||||
|
||||
|
||||
17
main.cpp
17
main.cpp
@@ -111,10 +111,27 @@ private:
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
PIKbdListener kbd;
|
||||
|
||||
#include "pigpio.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
PIGPIO::instance()->initPin(4, PIGPIO::Out);
|
||||
/*PIGPIO::instance()->pinBeginWatch(4);
|
||||
PIGPIO::instance()->start(10);
|
||||
CONNECTL(PIGPIO::instance(), pinChanged, [](int pin, bool value){
|
||||
piCout << "pin" << pin << "->" << value;}
|
||||
);*/
|
||||
kbd.enableExitCapture();
|
||||
kbd.start();
|
||||
bool val = false;
|
||||
while (!PIKbdListener::exiting) {
|
||||
piMSleep(500);
|
||||
PIGPIO::instance()->pinSet(4, val);
|
||||
piCout << PIGPIO::instance()->pinState(4);
|
||||
val = !val;
|
||||
}
|
||||
/*PIStringList dl = PISerial::availableDevices();
|
||||
piCout << dl;
|
||||
PISerial ser(dl[0]);
|
||||
|
||||
@@ -17,8 +17,15 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wnonnull"
|
||||
#endif
|
||||
#include "pistreampacker.h"
|
||||
#include "piiodevice.h"
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/** \class PIStreamPacker
|
||||
* \brief Simple packet wrap aroud any PIIODevice
|
||||
|
||||
@@ -215,9 +215,9 @@
|
||||
#define PRIVATE_DEFINITION_END(c) \
|
||||
}; \
|
||||
c::__PrivateInitializer__::__PrivateInitializer__() {p = new c::__Private__();} \
|
||||
c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ & o) {/*if (p) delete p;*/ p = new c::__Private__();} \
|
||||
c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ & ) {/*if (p) delete p;*/ p = new c::__Private__();} \
|
||||
c::__PrivateInitializer__::~__PrivateInitializer__() {delete p; p = 0;} \
|
||||
c::__PrivateInitializer__ & c::__PrivateInitializer__::operator =(const c::__PrivateInitializer__ & o) {if (p) delete p; p = new c::__Private__(); return *this;}
|
||||
c::__PrivateInitializer__ & c::__PrivateInitializer__::operator =(const c::__PrivateInitializer__ & ) {if (p) delete p; p = new c::__Private__(); return *this;}
|
||||
|
||||
#define PRIVATE (__privateinitializer__.p)
|
||||
#define PRIVATEWB __privateinitializer__.p
|
||||
|
||||
@@ -201,9 +201,9 @@
|
||||
typedef name __PIObject__; \
|
||||
public: \
|
||||
static const PIString __classNameS() {return PIStringAscii(#name);} \
|
||||
static const uint __classNameIDS() {static uint ret = PIStringAscii(#name).hash(); return ret;} \
|
||||
static uint __classNameIDS() {static uint ret = PIStringAscii(#name).hash(); return ret;} \
|
||||
virtual const char * className() const {return #name;} \
|
||||
virtual const uint classNameID() const {static uint ret = PIStringAscii(#name).hash(); return ret;} \
|
||||
virtual uint classNameID() const {static uint ret = PIStringAscii(#name).hash(); return ret;} \
|
||||
private: \
|
||||
virtual int ptrOffset() const {name * o = (name*)100; return int(llong((PIObject*)o) - llong(o));} \
|
||||
class __BaseInitializer__ { \
|
||||
@@ -515,10 +515,10 @@ public:
|
||||
//! Returns object class name
|
||||
virtual const char * className() const {return "PIObject";}
|
||||
|
||||
virtual const uint classNameID() const {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
|
||||
virtual uint classNameID() const {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
|
||||
|
||||
static const PIString __classNameS() {return PIStringAscii("PIObject");}
|
||||
static const uint __classNameIDS() {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
|
||||
static uint __classNameIDS() {static uint ret = PIStringAscii("PIObject").hash(); return ret;}
|
||||
|
||||
//! Returns parent object class name
|
||||
virtual const char * parentClassName() const {return "";}
|
||||
|
||||
@@ -36,7 +36,8 @@ PIIntrospectionThreads::PIIntrospectionThreads() {
|
||||
|
||||
void PIIntrospectionThreads::threadNew(PIThread * t) {
|
||||
PIMutexLocker _ml(mutex);
|
||||
ThreadInfo & ti(threads[t]);
|
||||
//ThreadInfo & ti(threads[t]);
|
||||
threads.insert(t, ThreadInfo());
|
||||
//piCout << "register thread" << id << name;
|
||||
}
|
||||
|
||||
|
||||
256
src_main/io_devices/pigpio.cpp
Normal file
256
src_main/io_devices/pigpio.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
GPIO
|
||||
Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pigpio.h"
|
||||
#ifdef LINUX
|
||||
# define GPIO_SYS_CLASS
|
||||
#endif
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
# include <cstdlib>
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
|
||||
|
||||
/*! \class PIGPIO
|
||||
* \brief GPIO support
|
||||
*
|
||||
* \section PIGPIO_sec0 Synopsis
|
||||
* This class provide initialize, get/set and watch functions for GPIO.
|
||||
*
|
||||
* Currently supported only \"/sys/class/gpio\" mechanism on Linux.
|
||||
*
|
||||
* This class should be used with \a PIGPIO::instance() singleton.
|
||||
*
|
||||
*
|
||||
*
|
||||
* \section PIGPIO_sec1 API
|
||||
* There are several function to directly read or write pin states.
|
||||
*
|
||||
* Also you can start %PIGPIO as thread to watch pin states and receive
|
||||
* \a pinChanged() event.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
PIGPIO::PIGPIO(): PIThread() {
|
||||
}
|
||||
|
||||
|
||||
PIGPIO::~PIGPIO() {
|
||||
stop();
|
||||
waitForFinish(100);
|
||||
PIMutexLocker ml(mutex);
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
PIVector<int> ids = gpio_.keys();
|
||||
for(int i = 0; i < ids.size_s(); i++) {
|
||||
GPIOData & g(gpio_[ids[i]]);
|
||||
if (g.fd != -1) {
|
||||
::close(g.fd);
|
||||
g.fd = -1;
|
||||
}
|
||||
}
|
||||
gpio_.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIGPIO * PIGPIO::instance() {
|
||||
static PIGPIO ret;
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIString PIGPIO::GPIOName(int gpio_num) {
|
||||
return PIStringAscii("gpio") + PIString::fromNumber(gpio_num);
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::exportGPIO(int gpio_num) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
int fd = ::open(("/sys/class/gpio/" + GPIOName(gpio_num) + "/value").dataAscii(), O_RDONLY);
|
||||
if (fd != -1) {
|
||||
::close(fd);
|
||||
return;
|
||||
}
|
||||
int ret = 0;
|
||||
ret = system(PIString("echo " + PIString::fromNumber(gpio_num) + " >> /sys/class/gpio/export").dataAscii());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::openGPIO(GPIOData & g) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
if (g.fd != -1) {
|
||||
::close(g.fd);
|
||||
g.fd = -1;
|
||||
}
|
||||
PIString fp = "/sys/class/gpio/" + g.name + "/value";
|
||||
g.fd = ::open(fp.dataAscii(), O_RDWR);
|
||||
//piCoutObj << "initGPIO" << g.num << ":" << fp << g.fd << errorString();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIGPIO::getPinState(int gpio_num) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
GPIOData & g(gpio_[gpio_num]);
|
||||
char r = 0;
|
||||
int ret = 0;
|
||||
if (g.fd != -1) {
|
||||
::lseek(g.fd, 0, SEEK_SET);
|
||||
ret = ::read(g.fd, &r, sizeof(r));
|
||||
if (ret > 0) {
|
||||
if (r == '1') return true;
|
||||
if (r == '0') return false;
|
||||
}
|
||||
}
|
||||
//piCoutObj << "pinState" << gpio_num << ":" << ret << (int)r << errorString();
|
||||
//initGPIO(gpio_num, PIGPIO::In); TODO: discuss - why?
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::begin() {
|
||||
PIMutexLocker ml(mutex);
|
||||
if (watch_state.isEmpty()) return;
|
||||
PIVector<int> ids = watch_state.keys();
|
||||
for(int i = 0; i < ids.size_s(); i++) {
|
||||
GPIOData & g(gpio_[ids[i]]);
|
||||
if (g.num != -1 && !g.name.isEmpty()) {
|
||||
openGPIO(g);
|
||||
watch_state[ids[i]] = getPinState(ids[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::run() {
|
||||
PIMutexLocker ml(mutex);
|
||||
if (watch_state.isEmpty()) return;
|
||||
PIVector<int> ids = watch_state.keys();
|
||||
for(int i = 0; i < ids.size_s(); i++) {
|
||||
GPIOData & g(gpio_[ids[i]]);
|
||||
if (g.num != -1 && !g.name.isEmpty()) {
|
||||
bool v = getPinState(g.num);
|
||||
//piCoutObj << "*** pin state ***" << ids[i] << "=" << v;
|
||||
if (watch_state[g.num] != v) {
|
||||
watch_state[g.num] = v;
|
||||
pinChanged(g.num, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::end() {
|
||||
PIMutexLocker ml(mutex);
|
||||
if (watch_state.isEmpty()) return;
|
||||
PIVector<int> ids = watch_state.keys();
|
||||
for(int i = 0; i < ids.size_s(); i++) {
|
||||
GPIOData & g(gpio_[ids[i]]);
|
||||
if (g.fd != -1) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
::close(g.fd);
|
||||
#endif
|
||||
g.fd = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::initPin(int gpio_num, Direction dir) { //, PullUpDownControl pull) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
PIMutexLocker ml(mutex);
|
||||
GPIOData & g(gpio_[gpio_num]);
|
||||
if (g.num == -1) {
|
||||
g.num = gpio_num;
|
||||
g.name = GPIOName(gpio_num);
|
||||
exportGPIO(gpio_num);
|
||||
}
|
||||
g.dir = dir;
|
||||
int ret = 0;
|
||||
switch(dir) {
|
||||
case In:
|
||||
ret = system(("echo in >> /sys/class/gpio/" + g.name + "/direction").dataAscii());
|
||||
break;
|
||||
case Out:
|
||||
ret = system(("echo out >> /sys/class/gpio/" + g.name + "/direction").dataAscii());
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
openGPIO(g);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::pinSet(int gpio_num, bool value) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
PIMutexLocker ml(mutex);
|
||||
GPIOData & g(gpio_[gpio_num]);
|
||||
int ret = 0;
|
||||
if (g.fd != -1) {
|
||||
if (value) ret = ::write(g.fd, "1", 1);
|
||||
else ret = ::write(g.fd, "0", 1);
|
||||
}
|
||||
//piCoutObj << "pinSet" << gpio_num << ":" << ret << errorString();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool PIGPIO::pinState(int gpio_num) {
|
||||
PIMutexLocker ml(mutex);
|
||||
return getPinState(gpio_num);
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::pinBeginWatch(int gpio_num) {
|
||||
PIMutexLocker ml(mutex);
|
||||
GPIOData & g(gpio_[gpio_num]);
|
||||
if (g.fd != -1) {
|
||||
#ifdef GPIO_SYS_CLASS
|
||||
::close(g.fd);
|
||||
#endif
|
||||
g.fd = -1;
|
||||
}
|
||||
watch_state.insert(gpio_num, false);
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::pinEndWatch(int gpio_num) {
|
||||
PIMutexLocker ml(mutex);
|
||||
watch_state.remove(gpio_num);
|
||||
}
|
||||
|
||||
|
||||
void PIGPIO::clearWatch() {
|
||||
PIMutexLocker ml(mutex);
|
||||
watch_state.clear();
|
||||
}
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
117
src_main/io_devices/pigpio.h
Normal file
117
src_main/io_devices/pigpio.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*! \file pigpio.h
|
||||
* \brief GPIO
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
GPIO
|
||||
Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIGPIO_H
|
||||
#define PIGPIO_H
|
||||
|
||||
#include "pithread.h"
|
||||
|
||||
|
||||
class PIGPIO: public PIThread
|
||||
{
|
||||
PIOBJECT_SUBCLASS(PIGPIO, PIThread)
|
||||
public:
|
||||
PIGPIO();
|
||||
virtual ~PIGPIO();
|
||||
|
||||
//! \brief Work mode for pin
|
||||
enum Direction {
|
||||
In /** Input direction (read) */,
|
||||
Out /** Output direction (write) */
|
||||
};
|
||||
//enum PullUpDownControl {NoPull, PullUp, PullDown};
|
||||
|
||||
|
||||
//! \brief Returns singleton object of %PIGPIO
|
||||
static PIGPIO * instance();
|
||||
|
||||
|
||||
//! \brief Initialize pin \"gpio_num\" for \"dir\" mode
|
||||
void initPin(int gpio_num, Direction dir = PIGPIO::In);//, PullUpDownControl pull);
|
||||
|
||||
|
||||
//! \brief Set pin \"gpio_num\" value to \"value\"
|
||||
void pinSet (int gpio_num, bool value);
|
||||
|
||||
//! \brief Set pin \"gpio_num\" value to \b true
|
||||
void pinHigh (int gpio_num) {pinSet(gpio_num, true );}
|
||||
|
||||
//! \brief Set pin \"gpio_num\" value to \b false
|
||||
void pinLow (int gpio_num) {pinSet(gpio_num, false);}
|
||||
|
||||
//! \brief Returns pin \"gpio_num\" state
|
||||
bool pinState(int gpio_num);
|
||||
|
||||
|
||||
//! \brief Starts watch for pin \"gpio_num\".
|
||||
//! \details Pins watching starts only with \a PIThread::start() function!
|
||||
//! This function doesn`t affect thread state
|
||||
void pinBeginWatch(int gpio_num);
|
||||
|
||||
//! \brief End watch for pin \"gpio_num\".
|
||||
//! \details Pins watching starts only with \a PIThread::start() function!
|
||||
//! This function doesn`t affect thread state
|
||||
void pinEndWatch (int gpio_num);
|
||||
|
||||
//! \brief End watch for all pins.
|
||||
//! \details Pins watching starts only with \a PIThread::start() function!
|
||||
//! This function doesn`t affect thread state
|
||||
void clearWatch();
|
||||
|
||||
|
||||
EVENT2(pinChanged, int, gpio_num, bool, new_value)
|
||||
|
||||
//! \events
|
||||
//! \{
|
||||
|
||||
//! \fn void pinChanged(int gpio_num, bool new_value)
|
||||
//! \brief Raise on pin \"gpio_num\" state changes to \"new_value\"
|
||||
//! \details Important! This event will be raised only with started
|
||||
//! thread.
|
||||
|
||||
//! \}
|
||||
|
||||
private:
|
||||
struct GPIOData {
|
||||
GPIOData() {dir = PIGPIO::In; num = fd = -1;}
|
||||
PIString name;
|
||||
int dir;
|
||||
int num;
|
||||
int fd;
|
||||
};
|
||||
void exportGPIO(int gpio_num);
|
||||
void openGPIO(GPIOData & g);
|
||||
bool getPinState(int gpio_num);
|
||||
void begin();
|
||||
void run();
|
||||
void end();
|
||||
|
||||
static PIString GPIOName(int gpio_num);
|
||||
|
||||
PIMap<int, GPIOData> gpio_;
|
||||
PIMap<int, bool> watch_state;
|
||||
PIMutex mutex;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // PIDIR_H
|
||||
@@ -375,7 +375,6 @@ void PISystemMonitor::gatherThread(llong id) {
|
||||
ts.name = tbid.value(id, "<PIThread>");
|
||||
#else
|
||||
ts.name = tbid.value(id, "<non-PIThread>");
|
||||
PISystemTime ct = PISystemTime::current();
|
||||
# ifndef WINDOWS
|
||||
PIFile f(PRIVATE->proc_dir + "task/" + PIString::fromNumber(id) + "/stat");
|
||||
//piCout << f.path();
|
||||
@@ -399,6 +398,7 @@ void PISystemMonitor::gatherThread(llong id) {
|
||||
ts.user_time = PISystemTime::fromMilliseconds(sl[12].toInt() * 10.);
|
||||
ts.kernel_time = PISystemTime::fromMilliseconds(sl[13].toInt() * 10.);
|
||||
# else
|
||||
PISystemTime ct = PISystemTime::current();
|
||||
FILETIME times[4];
|
||||
HANDLE thdl = OpenThread(THREAD_QUERY_INFORMATION, FALSE, DWORD(id));
|
||||
if (thdl == NULL) {
|
||||
|
||||
Reference in New Issue
Block a user