Custom Module Source
The following is an example source code file for a custom module which implements a custom stream transmitter and receiver as described in stream interfaces documentation. This source code expands the example to expose status variables to the Python layer. Instructions for wrapping these modules in PyRogue Devices are included in Wrapping Custom Module With PyRogue Device.
This module is compiled with the Building The Custom Module described in this section.
// Source for MyModule.cpp
#include <rogue/interfaces/stream/Slave.h>
#include <rogue/interfaces/stream/Master.h>
#include <rogue/interfaces/stream/Frame.h>
#include <rogue/interfaces/stream/FrameLock.h>
#include <rogue/interfaces/stream/FrameIterator.h>
// Custom stream slave class
class MyCustomSlave : public rogue::interfaces::stream::Slave {
// Total frame counter, exposed to Python
uint32_t frameCount_;
// Total byte count, exposed to Python
uint32_t byteCount_;
public:
// Create a static class creator to return our custom class wrapped with a shared pointer
static boost::shared_ptr<MyCustomSlave> create() {
static boost::shared_ptr<MyCustomSlave> ret = boost::make_shared<MyCustomSlave>();
return(ret);
}
// Return received frame counter
uint32_t getFrameCount() {
return frameCount_;
}
// Return total bytes received
uint32_t getTotalBytes() {
return byteCount_;
}
MyCustomSlave() : rogue::interfaces::stream::Slave() {
frameCount_ = 0;
byteCount_ = 0;
}
// Receive a frame
void acceptFrame ( boost::shared_ptr<rogue::interfaces::stream::Frame> frame ) {
// Acquire lock on frame. Will be release when lock class goes out of scope
rogue::interfaces::stream::FrameLockPtr lock = frame->lock();
// Increment frame counter
frameCount_++;
// Increment byte counter
byteCount_ += frame->getPayload();
}
// Expose methods to python
static void setup_python() {
boost::python::class_<MyCustomSlave, boost::shared_ptr<MyCustomSlave>,
boost::python::bases<rogue::interfaces::stream::Slave>,
boost::noncopyable >("MyCustomSlave",
boost::python::init<>())
.def("getFrameCount", &MyCustomSlave::getFrameCount)
.def("getTotalBytes", &MyCustomSlave::getTotalBytes)
;
boost::python::implicitly_convertible<boost::shared_ptr<MyCustomSlave>,
rogue::interfaces::stream::SlavePtr>();
};
};
// Custom stream master class
class MyCustomMaster : public rogue::interfaces::stream::Master {
// Total frame counter, exposed to Python
uint32_t frameCount_;
// Total byte count, exposed to Python
uint32_t byteCount_;
// Frame size configuration
uint32_t frameSize_;
public:
// Create a static class creator to return our custom class wrapped with a shared pointer
static boost::shared_ptr<MyCustomMaster> create() {
static boost::shared_ptr<MyCustomMaster> ret = boost::make_shared<MyCustomMaster>();
return(ret);
}
// Standard class creator which is called by create
MyCustomMaster() : rogue::interfaces::stream::Master() {
frameCount_ = 0;
byteCount_ = 0;
frameSize_ = 0;
}
// Return received frame counter
uint32_t getFrameCount() {
return frameCount_;
}
// Return total bytes received
uint32_t getTotalBytes() {
return byteCount_;
}
// Set frame size
void setFrameSize(uint32_t size) {
frameSize_ = size;
}
// Get frame size
uint32_t getFrameSize() {
return frameSize_;
}
// Generate and send a frame
void myFrameGen() {
rogue::interfaces::stream::FramePtr frame;
rogue::interfaces::stream::FrameIterator it;
uint32_t x;
// Here we request a frame capable of holding 100 bytes
frame = reqFrame(frameSize_,true);
// Unlike the python API we must now specify the new payload size
frame->setPayload(frameSize_);
// Set an incrementing value to the first 10 locations
x = 0;
for ( it=frame->begin(); it < frame->end(); ++it ) *it = x++;
//Send frame
sendFrame(frame);
// Increment frame counter
frameCount_++;
// Increment byte counter
byteCount_ += frameSize_;
}
// Expose methods to python
static void setup_python() {
boost::python::class_<MyCustomMaster, boost::shared_ptr<MyCustomMaster>,
boost::python::bases<rogue::interfaces::stream::Master>,
boost::noncopyable >("MyCustomMaster",
boost::python::init<>())
.def("getFrameCount", &MyCustomMaster::getFrameCount)
.def("getTotalBytes", &MyCustomMaster::getTotalBytes)
.def("setFrameSize", &MyCustomMaster::setFrameSize)
.def("getFrameSize", &MyCustomMaster::getFrameSize)
.def("myFrameGen", &MyCustomMaster::myFrameGen)
;
boost::python::implicitly_convertible<boost::shared_ptr<MyCustomMaster>,
rogue::interfaces::stream::MasterPtr>();
};
};
// Setup this module in python
BOOST_PYTHON_MODULE(MyModule) {
PyEval_InitThreads();
try {
MyCustomSlave::setup_python();
MyCustomMaster::setup_python();
} catch (...) {
printf("Failed to load module. import rogue first\n");
}
printf("Loaded my module\n");
};