some progress with python wrapper

This commit is contained in:
Thomas Kunze 2018-12-22 01:55:08 +01:00
parent 7a77b1e29a
commit 405aab0e5e
12 changed files with 229 additions and 176 deletions

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "knxPython/pybind11"]
path = knxPython/pybind11
url = https://github.com/pybind/pybind11.git
branch = stable

View File

@ -4,8 +4,8 @@
cmake_minimum_required(VERSION 2.7)
project(knx)
set(LIBRARIES_FROM_REFERENCES "")
add_library(knx SHARED ../src/knx/address_table_object.cpp ../src/knx/apdu.cpp ../src/knx/application_layer.cpp ../src/knx/application_program_object.cpp ../src/knx/association_table_object.cpp ../src/knx/bau.cpp ../src/knx/bau07B0.cpp ../src/knx/bau57B0.cpp ../src/knx/bau_systemB.cpp ../src/knx/bits.cpp ../src/knx/cemi_frame.cpp ../src/knx/datapoint_types.cpp ../src/knx/data_link_layer.cpp ../src/knx/device_object.cpp ../src/knx/group_object.cpp ../src/knx/group_object_table_object.cpp ../src/knx/interface_object.cpp ../src/knx/ip_data_link_layer.cpp ../src/knx/ip_parameter_object.cpp ../src/knx/memory.cpp ../src/knx/network_layer.cpp ../src/knx/npdu.cpp ../src/knx/platform.cpp ../src/knx/table_object.cpp ../src/knx/tpdu.cpp ../src/knx/tpuart_data_link_layer.cpp ../src/knx/transport_layer.cpp ../src/linux_platform.cpp knxmodule.cpp)
target_link_libraries(knx python3.5m "${LIBRARIES_FROM_REFERENCES}")
include_directories(/usr/include/python3.5m ../src)
SET_TARGET_PROPERTIES(knx PROPERTIES PREFIX "")
add_subdirectory(pybind11)
pybind11_add_module(knx ../src/knx/address_table_object.cpp ../src/knx/apdu.cpp ../src/knx/application_layer.cpp ../src/knx/application_program_object.cpp ../src/knx/association_table_object.cpp ../src/knx/bau.cpp ../src/knx/bau07B0.cpp ../src/knx/bau57B0.cpp ../src/knx/bau_systemB.cpp ../src/knx/bits.cpp ../src/knx/cemi_frame.cpp ../src/knx/datapoint_types.cpp ../src/knx/data_link_layer.cpp ../src/knx/device_object.cpp ../src/knx/group_object.cpp ../src/knx/group_object_table_object.cpp ../src/knx/interface_object.cpp ../src/knx/ip_data_link_layer.cpp ../src/knx/ip_parameter_object.cpp ../src/knx/memory.cpp ../src/knx/network_layer.cpp ../src/knx/npdu.cpp ../src/knx/platform.cpp ../src/knx/table_object.cpp ../src/knx/tpdu.cpp ../src/knx/tpuart_data_link_layer.cpp ../src/knx/transport_layer.cpp ../src/linux_platform.cpp knxmodule.cpp)
include_directories(../src)

View File

@ -862,7 +862,8 @@
#endif
// --- Include directories begin --- //
///usr/include/python3.5m
///usr/include/python3.5dm
///usr/include/python3.5
///usr/include/c++/6
///usr/include/x86_64-linux-gnu/c++/6
///usr/include/c++/6/backward
@ -871,6 +872,8 @@
///usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
///usr/include/x86_64-linux-gnu
///usr/include
//../src
//pybind11\include
// --- Include directories end --- //

View File

@ -4,13 +4,41 @@
<Project xsi:type="com.visualgdb.project.linux">
<CustomSourceDirectories>
<Directories />
<PathStyle>RemoteUnix</PathStyle>
<PathStyle>Win10LXSS</PathStyle>
</CustomSourceDirectories>
<BuildHost>
<HostName>localhost</HostName>
<Transport>LinuxSubsystem</Transport>
<UserName>Linux</UserName>
<HostName>Suzail</HostName>
<Transport>SSH</Transport>
<UserName>tkunze</UserName>
</BuildHost>
<MainSourceTransferCommand>
<SkipWhenRunningCommandList>false</SkipWhenRunningCommandList>
<RemoteHost>
<HostName>Suzail</HostName>
<Transport>SSH</Transport>
<UserName>tkunze</UserName>
</RemoteHost>
<LocalDirectory>$(ProjectDir)\..</LocalDirectory>
<RemoteDirectory>/tmp/VisualGDB/$(ProjectDirUnixStyle)/..</RemoteDirectory>
<FileMasks>
<string>*.cpp</string>
<string>*.h</string>
<string>*.hpp</string>
<string>*.c</string>
<string>*.cc</string>
<string>*.cxx</string>
<string>*.mak</string>
<string>Makefile</string>
<string>*.txt</string>
<string>*.cmake</string>
<string>*.py</string>
</FileMasks>
<TransferNewFilesOnly>true</TransferNewFilesOnly>
<IncludeSubdirectories>true</IncludeSubdirectories>
<SelectedDirectories />
<DeleteDisappearedFiles>false</DeleteDisappearedFiles>
<ApplyGlobalExclusionList>true</ApplyGlobalExclusionList>
</MainSourceTransferCommand>
<AllowChangingHostForMainCommands>false</AllowChangingHostForMainCommands>
<SkipBuildIfNoSourceFilesChanged>false</SkipBuildIfNoSourceFilesChanged>
<IgnoreFileTransferErrors>false</IgnoreFileTransferErrors>
@ -25,18 +53,17 @@
<Revision>0</Revision>
</Version>
</ToolchainID>
<RelativeSourceDirectory />
<RelativeSourceDirectory>knxPython</RelativeSourceDirectory>
<ConfigurationType>DEBUG</ConfigurationType>
<BinaryDirectory>Debug</BinaryDirectory>
<MainCMakeTarget>knx</MainCMakeTarget>
<MakeCommandTemplate>
<SkipWhenRunningCommandList>false</SkipWhenRunningCommandList>
<RemoteHost>
<HostName>BuildMachine</HostName>
<Transport>BuiltinShortcut</Transport>
</RemoteHost>
<Command>ninja</Command>
<Arguments />
<Command>$(ToolchainMake)</Command>
<Arguments>$(ToolchainMakeArgs)</Arguments>
<WorkingDirectory>$(BuildDir)</WorkingDirectory>
<BackgroundMode xsi:nil="true" />
</MakeCommandTemplate>
@ -49,10 +76,10 @@
<Command>$(ToolchainCMake)</Command>
<BackgroundMode xsi:nil="true" />
</CMakeCommand>
<UpdateSourcesInCMakeFile>true</UpdateSourcesInCMakeFile>
<UpdateSourcesInCMakeFile>false</UpdateSourcesInCMakeFile>
<ExplicitDebugTarget>$(BuildDir)/main.py</ExplicitDebugTarget>
<ExportCompileCommands>false</ExportCompileCommands>
<DisableToolchainFile>false</DisableToolchainFile>
<CMakeMakefileType>Ninja</CMakeMakefileType>
<DeployAsRoot>false</DeployAsRoot>
</Build>
<CustomBuild>
@ -93,14 +120,14 @@
<AdditionalGDBSettings>
<Features>
<DisableAutoDetection>false</DisableAutoDetection>
<UseFrameParameter>false</UseFrameParameter>
<SimpleValuesFlagSupported>false</SimpleValuesFlagSupported>
<ListLocalsSupported>false</ListLocalsSupported>
<ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable>
<ThreadInfoSupported>false</ThreadInfoSupported>
<PendingBreakpointsSupported>false</PendingBreakpointsSupported>
<SupportTargetCommand>false</SupportTargetCommand>
<ReliableBreakpointNotifications>false</ReliableBreakpointNotifications>
<UseFrameParameter>true</UseFrameParameter>
<SimpleValuesFlagSupported>true</SimpleValuesFlagSupported>
<ListLocalsSupported>true</ListLocalsSupported>
<ByteLevelMemoryCommandsAvailable>true</ByteLevelMemoryCommandsAvailable>
<ThreadInfoSupported>true</ThreadInfoSupported>
<PendingBreakpointsSupported>true</PendingBreakpointsSupported>
<SupportTargetCommand>true</SupportTargetCommand>
<ReliableBreakpointNotifications>true</ReliableBreakpointNotifications>
</Features>
<EnableSmartStepping>false</EnableSmartStepping>
<FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications>
@ -121,9 +148,10 @@
<MaxBreakpointLimit>0</MaxBreakpointLimit>
</AdditionalGDBSettings>
<LaunchGDBSettings xsi:type="GDBLaunchParametersPython">
<DebuggedProgram>$(SourceDir)/main.py</DebuggedProgram>
<DebuggedProgram>$(TargetPath)</DebuggedProgram>
<GDBServerPort>2000</GDBServerPort>
<ProgramArguments />
<WorkingDirectory>$(BuildDir)/Debug</WorkingDirectory>
<ProgramEnvironment>PYTHONPATH=%PYTHONPATH%:$(SourceDir)/$(ConfigurationName)</ProgramEnvironment>
<PythonExecutable>python3</PythonExecutable>
<StepAndBreakpointSupport>true</StepAndBreakpointSupport>
@ -131,10 +159,12 @@
<StopAtFirstPythonStatement>false</StopAtFirstPythonStatement>
</LaunchGDBSettings>
<GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC>
<DeploymentTargetPath />
<X11WindowMode>Local</X11WindowMode>
<KeepConsoleAfterExit>false</KeepConsoleAfterExit>
<RunGDBUnderSudo>false</RunGDBUnderSudo>
<DeploymentMode>Auto</DeploymentMode>
<LdLibraryPath />
<DeployWhenLaunchedWithoutDebugging>true</DeployWhenLaunchedWithoutDebugging>
<SuppressTTYCreation>false</SuppressTTYCreation>
</Debug>

View File

@ -44,7 +44,7 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<NMakeIncludeSearchPath>$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\python3.5m;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\c++\6;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\x86_64-linux-gnu\c++\6;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\c++\6\backward;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\lib\gcc\x86_64-linux-gnu\6\include;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\local\include;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\lib\gcc\x86_64-linux-gnu\6\include-fixed;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\x86_64-linux-gnu;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include;..\src;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
<NMakeIncludeSearchPath>$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\python3.5dm;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\python3.5;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\c++\6;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\x86_64-linux-gnu\c++\6;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\c++\6\backward;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\lib\gcc\x86_64-linux-gnu\6\include;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\local\include;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\lib\gcc\x86_64-linux-gnu\6\include-fixed;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include\x86_64-linux-gnu;$(LOCALAPPDATA)\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\rootfs\usr\include;..\..\src;..\pybind11\include;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
<NMakeForcedIncludes>$(ProjectDir)\gcc_Debug.h;$(VISUALGDB_DIR)\gcc_compat.h;$(NMakeForcedIncludes)</NMakeForcedIncludes>
<NMakeBuildCommandLine>"$(VISUALGDB_DIR)\VisualGDB.exe" /build "$(ProjectPath)" "/solution:$(SolutionPath)" "/config:$(Configuration)" "/platform:$(Platform)"</NMakeBuildCommandLine>
<NMakeCleanCommandLine>"$(VISUALGDB_DIR)\VisualGDB.exe" /clean "$(ProjectPath)" "/solution:$(SolutionPath)" "/config:$(Configuration)" "/platform:$(Platform)"</NMakeCleanCommandLine>

View File

@ -1,174 +1,158 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>
namespace py = pybind11;
#include <Python.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <stdlib.h>
#include <thread>
#include <stdint.h>
#include <vector>
#include "linux_platform.h"
#include "knx/bau57B0.h"
#include "knx/group_object_table_object.h"
LinuxPlatform platfrom;
Bau57B0 bau(platfrom);
LinuxPlatform platform;
Bau57B0 bau(platform);
#if 1 // this code will go to python later
float currentValue = 0;
float maxValue = 0;
float minValue = RAND_MAX;
long lastsend = 0;
//float currentValue = 0;
//float maxValue = 0;
//float minValue = RAND_MAX;
//long lastsend = 0;
//
//GroupObject groupObjects[]
//{
// GroupObject(2),
// GroupObject(2),
// GroupObject(2),
// GroupObject(1)
//}
//;
//#define CURR groupObjects[0]
//#define MAX groupObjects[1]
//#define MIN groupObjects[2]
//#define RESET groupObjects[3]
//
//void measureTemp()
//{
// long now = platform.millis();
// if ((now - lastsend) < 2000)
// return;
//
// lastsend = now;
// int r = rand();
// currentValue = (r * 1.0) / (RAND_MAX * 1.0);
// currentValue *= 100 * 100;
//
// CURR.objectWrite(currentValue);
//
// if (currentValue > maxValue)
// {
// maxValue = currentValue;
// MAX.objectWrite(maxValue);
// }
//
// if (currentValue < minValue)
// {
// minValue = currentValue;
// MIN.objectWrite(minValue);
// }
//}
GroupObject groupObjects[]
{
GroupObject(2),
GroupObject(2),
GroupObject(2),
GroupObject(1)
}
;
#define CURR groupObjects[0]
#define MAX groupObjects[1]
#define MIN groupObjects[2]
#define RESET groupObjects[3]
//void resetCallback(GroupObject& go)
//{
// if (go.objectReadBool())
// {
// maxValue = 0;
// minValue = 10000;
// }
//}
void measureTemp()
{
long now = platfrom.millis();
if ((now - lastsend) < 2000)
return;
lastsend = now;
int r = rand();
currentValue = (r * 1.0) / (RAND_MAX * 1.0);
currentValue *= 100 * 100;
CURR.objectWrite(currentValue);
if (currentValue > maxValue)
{
maxValue = currentValue;
MAX.objectWrite(maxValue);
}
if (currentValue < minValue)
{
minValue = currentValue;
MIN.objectWrite(minValue);
}
}
void resetCallback(GroupObject& go)
{
if (go.objectReadBool())
{
maxValue = 0;
minValue = 10000;
}
}
void appLoop()
{
if (!bau.configured())
return;
measureTemp();
}
//void appLoop()
//{
// if (!bau.configured())
// return;
//
// measureTemp();
//}
void setup()
{
srand((unsigned int)time(NULL));
bau.readMemory();
GroupObjectTableObject& got(bau.groupObjectTable());
got.groupObjects(groupObjects, 4);
// GroupObjectTableObject& got(bau.groupObjectTable());
// got.groupObjects(groupObjects, 4);
DeviceObject& devObj(bau.deviceObject());
devObj.manufacturerId(0xfa);
RESET.updateHandler = resetCallback;
// RESET.updateHandler = resetCallback;
if (bau.parameters().loadState() == LS_LOADED)
{
printf("Timeout: %d\n", bau.parameters().getWord(0));
printf("Zykl. senden: %d\n", bau.parameters().getByte(2));
printf("Min/Max senden: %d\n", bau.parameters().getByte(3));
printf("Aenderung senden: %d\n", bau.parameters().getByte(4));
printf("Abgleich %d\n", bau.parameters().getByte(5));
}
bau.enabled(true);
}
#endif
static void* loop(void* x)
bool threadEnabled = false;
static void loop()
{
while (1)
{
bau.loop();
appLoop();
platfrom.mdelay(100);
//appLoop();
platform.mdelay(100);
}
pthread_exit(NULL);
}
static pthread_t workerThread;
static std::thread workerThread;
static PyObject* Start(PyObject* self, PyObject* args)
bool started = false;
static void Start()
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
if (started)
return;
setup();
int res = pthread_create(&workerThread, NULL, loop, NULL);
if (res)
{
printf("error %d\n", res);
return NULL;
}
Py_RETURN_NONE;
workerThread = std::thread(loop);
workerThread.detach();
}
static PyObject* ProgramMode(PyObject* self, PyObject* args)
static bool ProgramMode(bool value)
{
if (PyArg_ParseTuple(args, ""))
{
//no arguments
return Py_BuildValue("i", bau.deviceObject().progMode());
}
PyErr_Clear();
int value = 0;
if (!PyArg_ParseTuple(args, "i", &value))
return NULL;
bau.deviceObject().progMode(value);
return Py_BuildValue("i", bau.deviceObject().progMode());
return bau.deviceObject().progMode();
}
static PyMethodDef knxMethods[] =
static bool ProgramMode()
{
{"Start", Start, METH_VARARGS, "Start knx handling thread." },
{"ProgramMode", ProgramMode, METH_VARARGS, "Activate/deactivate programing mode." },
{ NULL, NULL, 0, NULL } /* End of list */
};
static struct PyModuleDef knxModule = {
PyModuleDef_HEAD_INIT,
"knx",
NULL,
0,
knxMethods,
NULL,
NULL,
NULL,
NULL
};
PyMODINIT_FUNC PyInit_knx(void)
{
PyObject* m = PyModule_Create(&knxModule);
return m;
return bau.deviceObject().progMode();
}
static void RegisterGroupObjects(std::vector<GroupObject>& gos)
{
GroupObjectTableObject& got(bau.groupObjectTable());
got.groupObjects(gos.data(), gos.size());
}
PYBIND11_MAKE_OPAQUE(std::vector<GroupObject>);
PYBIND11_MODULE(knx, m) {
m.doc() = "wrapper for knx device lib"; // optional module docstring
py::bind_vector<std::vector<GroupObject>>(m, "GroupObjectList");
m.def("Start", &Start, "Start knx handling thread.");
m.def("ProgramMode", (bool (*)())&ProgramMode, "get programing mode active.");
m.def("ProgramMode", (bool(*)(bool))&ProgramMode, "Activate / deactivate programing mode.");
m.def("RegisterGroupObjects", &RegisterGroupObjects);
py::class_<GroupObject>(m, "GroupObject")
.def(py::init<uint8_t>())
.def("objectWrite", (void(GroupObject::*)(float))&GroupObject::objectWrite);
}

View File

@ -3,6 +3,14 @@ import time
import sys
print("start")
gos = knx.GroupObjectList()
gos.append(knx.GroupObject(2))
gos.append(knx.GroupObject(2))
gos.append(knx.GroupObject(2))
gos.append(knx.GroupObject(1))
curr = gos[0]
knx.RegisterGroupObjects(gos)
knx.Start()
while True:
time.sleep(1)
cmd = sys.stdin.read(1)
@ -14,4 +22,10 @@ while True:
elif cmd == 'p':
currentMode = knx.ProgramMode(not knx.ProgramMode())
print("set programming mode to " + str(currentMode))
elif cmd == 'w':
cmd = sys.stdin.read(4)
print(cmd)
value = float(cmd)
curr.objectWrite(value)
print("wrote " + str(value) + " to curr")
print("end")

1
knxPython/pybind11 Submodule

@ -0,0 +1 @@
Subproject commit 9a19306fbf30642ca331d0ec88e7da54a96860f9

View File

@ -13,6 +13,17 @@ GroupObject::GroupObject(uint8_t size)
updateHandler = 0;
}
GroupObject::GroupObject(const GroupObject& other)
{
_data = new uint8_t[other._dataLength];
_commFlag = other._commFlag;
_table = other._table;
_dataLength = other._dataLength;
_asap = other._asap;
updateHandler = other.updateHandler;
memcpy(_data, other._data, _dataLength);
}
GroupObject::~GroupObject()
{
delete[] _data;

View File

@ -24,6 +24,7 @@ class GroupObject
friend class GroupObjectTableObject;
public:
GroupObject(uint8_t size);
GroupObject(const GroupObject& other);
virtual ~GroupObject();
// config flags from ETS
bool responseUpdateEnable();

View File

@ -25,6 +25,7 @@
#include "knx/group_object_table_object.h"
#include "knx/application_program_object.h"
#include "knx/ip_parameter_object.h"
#include "knx/bits.h"
#define MAX_MEM 4096
@ -129,8 +130,8 @@ void LinuxPlatform::setupMultiCast(uint32_t addr, uint16_t port)
fatalError();
}
/* Broadcast auf dieser Maschine zulassen */
loop = 1;
/* loopback */
loop = 0;
if (setsockopt(_socketFd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
{
perror("setsockopt:IP_MULTICAST_LOOP");
@ -184,6 +185,7 @@ bool LinuxPlatform::sendBytes(uint8_t* buffer, uint16_t len)
return false;
}
} while (retVal == -1);
// printHex("<-", buffer, len);
return true;
}
@ -194,6 +196,9 @@ int LinuxPlatform::readBytes(uint8_t * buffer, uint16_t maxLen)
sin_len = sizeof(sin);
ssize_t len = recvfrom(_socketFd, buffer, maxLen, 0, (struct sockaddr *) &sin, &sin_len);
// if (len > 0)
// printHex("->", buffer, len);
return len;
}

View File

@ -11,37 +11,37 @@ public:
LinuxPlatform();
// ip stuff
uint32_t currentIpAddress();
uint32_t currentSubnetMask();
uint32_t currentDefaultGateway();
void macAddress(uint8_t* addr);
uint32_t currentIpAddress() override;
uint32_t currentSubnetMask() override;
uint32_t currentDefaultGateway() override;
void macAddress(uint8_t* addr) override;
// basic stuff
uint32_t millis();
void mdelay(uint32_t millis);
void restart();
void fatalError();
uint32_t millis() override;
void mdelay(uint32_t millis) override;
void restart() override;
void fatalError() override;
//multicast
void setupMultiCast(uint32_t addr, uint16_t port);
void closeMultiCast();
bool sendBytes(uint8_t* buffer, uint16_t len);
int readBytes(uint8_t* buffer, uint16_t maxLen);
void setupMultiCast(uint32_t addr, uint16_t port) override;
void closeMultiCast() override;
bool sendBytes(uint8_t* buffer, uint16_t len) override;
int readBytes(uint8_t* buffer, uint16_t maxLen) override;
//uart
void setupUart();
void closeUart();
int uartAvailable();
size_t writeUart(const uint8_t data);
size_t writeUart(const uint8_t *buffer, size_t size);
int readUart();
size_t readBytesUart(uint8_t *buffer, size_t length);
void setupUart() override;
void closeUart() override;
int uartAvailable() override;
size_t writeUart(const uint8_t data) override;
size_t writeUart(const uint8_t *buffer, size_t size) override;
int readUart() override;
size_t readBytesUart(uint8_t *buffer, size_t length) override;
//memory
uint8_t* getEepromBuffer(uint16_t size);
void commitToEeprom();
uint8_t* allocMemory(size_t size);
void freeMemory(uint8_t* ptr);
uint8_t* getEepromBuffer(uint16_t size) override;
void commitToEeprom() override;
uint8_t* allocMemory(size_t size) override;
void freeMemory(uint8_t* ptr) override;
private:
uint32_t _multicastAddr;
uint16_t _port;