6#include "dawn/proto/modbus/rtu.hxx"
8#include "dawn/io/common.hxx"
12int CProtoModbusRtu::configureDesc(
const CDescObject &desc)
17 for (
size_t i = 0; i < desc.
getSize(); i++)
23 DAWNERR(
"Unsupported Modbus RTU config 0x%08" PRIx32
"\n", item->
cfgid.
v);
33 SProtoModbusIOBind *tmp =
reinterpret_cast<SProtoModbusIOBind *
>(item->
data + j);
37 j +=
sizeof(SProtoModbusIOBind) / 4 + tmp->size;
45 path =
reinterpret_cast<const char *
>(&item->
data);
51 baud =
static_cast<uint32_t
>(item->
data[0]);
57 DAWNERR(
"Unsupported Modbus RTU config 0x%08" PRIx32
"\n", item->
cfgid.
v);
66void CProtoModbusRtu::allocObject(SProtoModbusIOBind *alloc)
68 for (
size_t i = 0; i < alloc->size; i++)
70 DAWNINFO(
"allocate object 0x%" PRIx32
"\n", alloc->objid[i]);
79 valloc_push_back(alloc);
82void CProtoModbusRtu::thread()
84 DAWNINFO(
"start modbus thread\n");
92 ret = nxmb_poll(mbhandle);
93 if (ret < 0 && ret != -ETIMEDOUT && ret != -EAGAIN)
95 DAWNERR(
"nxmb_poll error: %d\n", ret);
106int CProtoModbusRtu::modbusInitialize()
108 struct nxmb_config_s config;
111 memset(&config, 0,
sizeof(config));
112 config.unit_id = saddr;
113 config.is_client =
false;
114 config.mode = NXMB_MODE_RTU;
120 config.transport.serial.parity = NXMB_PAR_NONE;
124 config.transport.serial.parity = NXMB_PAR_ODD;
128 config.transport.serial.parity = NXMB_PAR_EVEN;
131 DAWNERR(
"ERROR: Invalid parity setting: %d\n", parity);
135 config.transport.serial.devpath = path;
136 config.transport.serial.baudrate = baud;
138 ret = nxmb_create(&mbhandle, &config);
141 DAWNERR(
"ERROR: nxmb_create failed: %d\n", ret);
145 memset(&callbacks, 0,
sizeof(callbacks));
146#ifdef CONFIG_DAWN_PROTO_MODBUS_COIL
147 callbacks.coil_cb = [](FAR uint8_t *buf,
150 enum nxmb_regmode_e mode,
151 FAR
void *priv) ->
int
152 {
return static_cast<CProtoModbusRegs *
>(priv)->coilsCb(buf, addr, ncoils, mode, priv); };
154#ifdef CONFIG_DAWN_PROTO_MODBUS_DISCRETE
155 callbacks.discrete_cb =
156 [](FAR uint8_t *buf, uint16_t addr, uint16_t ndiscrete, FAR
void *priv) ->
int
157 {
return static_cast<CProtoModbusRegs *
>(priv)->discreteCb(buf, addr, ndiscrete, priv); };
159#ifdef CONFIG_DAWN_PROTO_MODBUS_INPUT
160 callbacks.input_cb = [](FAR uint8_t *buf, uint16_t addr, uint16_t nregs, FAR
void *priv) ->
int
161 {
return static_cast<CProtoModbusRegs *
>(priv)->inputCb(buf, addr, nregs, priv); };
163#ifdef CONFIG_DAWN_PROTO_MODBUS_HOLDING
164 callbacks.holding_cb = [](FAR uint8_t *buf,
167 enum nxmb_regmode_e mode,
168 FAR
void *priv) ->
int
169 {
return static_cast<CProtoModbusRegs *
>(priv)->holdingCb(buf, addr, nregs, mode, priv); };
173 ret = nxmb_set_callbacks(mbhandle, &callbacks);
176 DAWNERR(
"ERROR: nxmb_set_callbacks failed: %d\n", ret);
177 nxmb_destroy(mbhandle);
181 ret = nxmb_enable(mbhandle);
184 DAWNERR(
"ERROR: nxmb_enable failed: %d\n", ret);
185 nxmb_destroy(mbhandle);
197CProtoModbusRtu::~CProtoModbusRtu()
208 ret = configureDesc(
getDesc());
211 DAWNERR(
"Modbus RTU configure failed (error %d)\n", ret);
226 ret = modbusInitialize();
237 DAWNERR(
"failed to create registers %d\n", ret);
238 if (mbhandle != NULL)
240 nxmb_disable(mbhandle);
241 nxmb_destroy(mbhandle);
256 if (mbhandle != NULL)
258 nxmb_disable(mbhandle);
259 nxmb_destroy(mbhandle);
275 DAWNERR(
"failed to start thread %d\n", ret);
void setObjectMapItem(SObjectId::ObjectId id, CObject *obj)
Set an item in the object map.
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
CDescObject & getDesc()
Get descriptor object for this object.
@ PROTO_CLASS_MODBUS_RTU
Modbus RTU (serial implementation).
Modbus register management base class (shared RTU/TCP logic).
int configure()
Configure object from descriptor data.
int init()
One-time initialize object after bindings are resolved.
int doStop()
Stop implementation hook.
int doStart()
Start implementation hook.
int deinit()
De-initialize object.
bool hasThread() const
Check if a background thread is active.
@ PROTO_MODBUS_CFG_IOBIND
I/O object binding (register map).
@ PROTO_MODBUS_CFG_PATH
Serial device path.
@ PROTO_MODBUS_CFG_BAUD
Serial baud rate.
bool workerThreadRunning() const
Check if the worker thread is running.
int stopWorkerThread()
Stop the worker thread.
int startWorkerThread(Func &&func)
Start the worker thread with a given function.
CThreadedObject & workerThread()
Get a reference to this thread controller.
Out-of-tree user-extension hooks for Dawn.
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.