parent
81f6c8f2e9
commit
ab646c3a47
@ -1,8 +1,191 @@ |
|||||||
#include <stdio.h> |
#include <stdio.h> |
||||||
#include "modbus.h" |
#include "modbus.h" |
||||||
|
|
||||||
|
/* https://gist.github.com/ccbrown/9722406 */ |
||||||
|
void hexdump(const void *data, size_t size) |
||||||
|
{ |
||||||
|
char ascii[17]; |
||||||
|
size_t i, j; |
||||||
|
ascii[16] = '\0'; |
||||||
|
for (i = 0; i < size; ++i) { |
||||||
|
printf("%02X ", ((unsigned char *) data)[i]); |
||||||
|
const uint8_t c = ((unsigned char *) data)[i]; |
||||||
|
if (c >= ' ' && c <= '~') { |
||||||
|
ascii[i % 16] = (char) c; |
||||||
|
} else { |
||||||
|
ascii[i % 16] = '.'; |
||||||
|
} |
||||||
|
if ((i + 1) % 8 == 0 || i + 1 == size) { |
||||||
|
printf(" "); |
||||||
|
if ((i + 1) % 16 == 0) { |
||||||
|
printf("| %s \n", ascii); |
||||||
|
} else if (i + 1 == size) { |
||||||
|
ascii[(i + 1) % 16] = '\0'; |
||||||
|
if ((i + 1) % 16 <= 8) { |
||||||
|
printf(" "); |
||||||
|
} |
||||||
|
for (j = (i + 1) % 16; j < 16; ++j) { |
||||||
|
printf(" "); |
||||||
|
} |
||||||
|
printf("| %s \n", ascii); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static ssize_t parsehex(const char *s, uint8_t *out, size_t cap) |
||||||
|
{ |
||||||
|
uint8_t buf = 0; |
||||||
|
uint8_t v; |
||||||
|
bool first = true; |
||||||
|
char c; |
||||||
|
size_t sz = 0; |
||||||
|
while (0 != (c = *s++)) { |
||||||
|
if (c >= '0' && c <= '9') { |
||||||
|
v = c - '0'; |
||||||
|
} else if (c >= 'a' && c <= 'f') { |
||||||
|
v = 10 + (c - 'a'); |
||||||
|
} else if (c >= 'A' && c <= 'F') { |
||||||
|
v = 10 + (c - 'A'); |
||||||
|
} else { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
if (first) { |
||||||
|
buf |= (v & 15) << 4; |
||||||
|
first = false; |
||||||
|
} else { |
||||||
|
buf |= (v & 15); |
||||||
|
if (cap == 0) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
out[sz++] = buf; |
||||||
|
buf = 0; |
||||||
|
first = true; |
||||||
|
cap--; |
||||||
|
} |
||||||
|
} |
||||||
|
return (ssize_t) sz; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
ModbusException_t soa(ModbusSlave_t *ms, ModbusFunction_t fcx, uint8_t slave_id) { |
||||||
|
printf("Start of access: fc%02d, slave %d\n", fcx, slave_id); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
void eoa(ModbusSlave_t *ms) { |
||||||
|
printf("End of access\n"); |
||||||
|
} |
||||||
|
ModbusException_t rh(ModbusSlave_t *ms, uint16_t i, uint16_t *out) { |
||||||
|
printf("rh %d\n", i); |
||||||
|
switch (i) { |
||||||
|
case 107: |
||||||
|
*out = 0xAE41; |
||||||
|
break; |
||||||
|
case 108: |
||||||
|
*out = 0x5652; |
||||||
|
break; |
||||||
|
case 109: |
||||||
|
*out = 0x4340; |
||||||
|
break; |
||||||
|
default: |
||||||
|
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
ModbusException_t ri(ModbusSlave_t *ms, uint16_t i, uint16_t *out) { |
||||||
|
printf("ri %d\n", i); |
||||||
|
switch (i) { |
||||||
|
case 8: |
||||||
|
*out = 0xa; |
||||||
|
break; |
||||||
|
default: |
||||||
|
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
ModbusException_t rc(ModbusSlave_t *ms, uint16_t i, bool *out) { |
||||||
|
uint8_t store[] = { |
||||||
|
0b11001101, |
||||||
|
0b01101011, |
||||||
|
0b10110010, |
||||||
|
0b00001110, |
||||||
|
0b00011011, |
||||||
|
}; |
||||||
|
|
||||||
|
if (i >= 19 && i <= 55) { |
||||||
|
int pos = i-19; |
||||||
|
*out = 0 != (store[pos/8] & (1 << (pos%8))); |
||||||
|
} else { |
||||||
|
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
ModbusException_t rd(ModbusSlave_t *ms, uint16_t i, bool *out) { |
||||||
|
uint8_t store[] = { |
||||||
|
0b10101100, |
||||||
|
0b11011011, |
||||||
|
0b00110101, |
||||||
|
}; |
||||||
|
|
||||||
|
if (i >= 196 && i <= 217) { |
||||||
|
int pos = i - 196; |
||||||
|
*out = 0 != (store[pos/8] & (1 << (pos%8))); |
||||||
|
} else { |
||||||
|
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
ModbusException_t wc(ModbusSlave_t *pSlave, uint16_t i, bool b) { |
||||||
|
printf("Write coil %d <- %d\n", i, b); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
ModbusException_t wh(ModbusSlave_t *pSlave, uint16_t i, uint16_t i1) { |
||||||
|
printf("Write reg %d <- %d\n", i, i1); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
int main() |
int main() |
||||||
{ |
{ |
||||||
printf("Hello, World!\n"); |
#define buflen 1024 |
||||||
|
uint8_t buf[buflen]; |
||||||
|
uint8_t buf2[buflen]; |
||||||
|
|
||||||
|
// 11 03 006B 0003 7687
|
||||||
|
// 11 04 0008 0001 B298
|
||||||
|
// 11 01 0013 0025 0E84
|
||||||
|
// 11 02 00C4 0016 BAA9
|
||||||
|
// 11 05 00AC FF00 4E8B
|
||||||
|
// 11 06 0001 0003 9A9B
|
||||||
|
// 11 0F 0013 000A 02 CD01 BF0B
|
||||||
|
// 11 10 0001 0002 04 000A 0102 C6F0
|
||||||
|
ssize_t pldlen = parsehex("11 03 006B 0003 7687", buf, buflen); |
||||||
|
|
||||||
|
ModbusSlave_t ms = { |
||||||
|
.addr = 17, |
||||||
|
.proto = MB_PROTO_RTU, |
||||||
|
.startOfAccess = soa, |
||||||
|
.endOfAccess = eoa, |
||||||
|
.readHolding = rh, |
||||||
|
.readInput = ri, |
||||||
|
.readCoil = rc, |
||||||
|
.readDiscrete = rd, |
||||||
|
.writeCoil = wc, |
||||||
|
.writeHolding = wh, |
||||||
|
}; |
||||||
|
|
||||||
|
printf("Req:\n"); |
||||||
|
hexdump(buf, pldlen); |
||||||
|
|
||||||
|
size_t respsize; |
||||||
|
ModbusError_t e = mb_handleRequest(&ms, buf, pldlen, buf2, buflen, &respsize); |
||||||
|
if (e) { |
||||||
|
printf("Err %d\n", e); |
||||||
|
} else { |
||||||
|
printf("Resp:\n"); |
||||||
|
hexdump(buf2, respsize); |
||||||
|
} |
||||||
|
|
||||||
return 0; |
return 0; |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue