Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:

jobs:
clang_format_check:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04

steps:
# checkout
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ env:

jobs:
cross-build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
matrix:
arch:
Expand Down Expand Up @@ -52,14 +52,14 @@ jobs:
run: |
./package-sdk.sh -p ${{ matrix.arch[2] }} -n neuron-sdk-$VERSION

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: neuron-sdk
name: neuron-sdk-${{ matrix.arch[2] }}
path: |
neuron-sdk-*.tar.gz

build-debug-sdk:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
matrix:
arch:
Expand All @@ -83,7 +83,7 @@ jobs:
run: |
./package-sdk.sh -p ${{ matrix.arch[2] }} -n neuron-sdk-debug-$VERSION

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: neuron-sdk
path: |
Expand All @@ -102,7 +102,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: neuron-sdk

Expand Down
5 changes: 5 additions & 0 deletions include/neuron/tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ typedef enum {
NEU_DATATAG_ENDIAN_BL32 = 5, // #BL 2,1,4,3
NEU_DATATAG_ENDIAN_L64 = 6, // #L 8,7,6,5,4,3,2,1
NEU_DATATAG_ENDIAN_B64 = 7, // #B 1,2,3,4,5,6,7,8
NEU_DATATAG_ENDIAN_LL64 = 8,
NEU_DATATAG_ENDIAN_LB64 = 9,
NEU_DATATAG_ENDIAN_BB64 = 10,
NEU_DATATAG_ENDIAN_BL64 = 11,
} neu_datatag_endian_e;

typedef enum {
Expand All @@ -63,6 +67,7 @@ typedef union {
} value32;
struct {
neu_datatag_endian_e endian;
bool is_default;
} value64;
struct {
uint16_t length;
Expand Down
36 changes: 36 additions & 0 deletions include/neuron/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,42 @@ static inline uint64_t neu_htonll(uint64_t u)
return ret;
}

static inline uint64_t neu_htonlb(uint64_t u)
{
uint8_t *in = (uint8_t *) &u;
uint64_t out = 0;
uint8_t *out_bytes = (uint8_t *) &out;

out_bytes[0] = in[1];
out_bytes[1] = in[0];
out_bytes[2] = in[3];
out_bytes[3] = in[2];
out_bytes[4] = in[5];
out_bytes[5] = in[4];
out_bytes[6] = in[7];
out_bytes[7] = in[6];

return out;
}

static inline uint64_t neu_htonbl(uint64_t u)
{
uint8_t *in = (uint8_t *) &u;
uint64_t out = 0;
uint8_t *out_bytes = (uint8_t *) &out;

out_bytes[0] = in[6];
out_bytes[1] = in[7];
out_bytes[2] = in[4];
out_bytes[3] = in[5];
out_bytes[4] = in[2];
out_bytes[5] = in[3];
out_bytes[6] = in[0];
out_bytes[7] = in[1];

return out;
}

static inline uint64_t neu_ntohll(uint64_t u)
{
return neu_htonll(u);
Expand Down
35 changes: 32 additions & 3 deletions plugins/modbus/modbus-rtu.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@
},
{
"type": 7,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 8,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 9,
"regex": "^[0-9]+![3-4][0-9]+(#BB|#BL|#LL|#LB|)$"
},
{
"type": 10,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 11,
Expand Down Expand Up @@ -106,6 +106,35 @@
"max": 10000
}
},
"endianess_64": {
"name": "Endianess of 8-Byte Data",
"name_zh": "8 字节数据字节序",
"description": "Tag byte order, applicable to int64, uint64 and double types",
"description_zh": "点位字节序,适用于 int64,uint64 和 double 类型",
"attribute": "required",
"type": "map",
"default": 1,
"valid": {
"map": [
{
"key": "12 34 56 78",
"value": 1
},
{
"key": "21 43 65 87",
"value": 2
},
{
"key": "87 65 43 21",
"value": 3
},
{
"key": "78 56 34 12",
"value": 4
}
]
}
},
"interval": {
"name": "Send Interval",
"name_zh": "指令发送间隔",
Expand Down
35 changes: 32 additions & 3 deletions plugins/modbus/modbus-tcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@
},
{
"type": 7,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 8,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 9,
"regex": "^[0-9]+![3-4][0-9]+(#BB|#BL|#LL|#LB|)$"
},
{
"type": 10,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 11,
Expand Down Expand Up @@ -93,6 +93,35 @@
"max": 10000
}
},
"endianess_64": {
"name": "Endianess of 8-Byte Data",
"name_zh": "8 字节数据字节序",
"description": "Tag byte order, applicable to int64, uint64 and double types",
"description_zh": "点位字节序,适用于 int64,uint64 和 double 类型",
"attribute": "required",
"type": "map",
"default": 1,
"valid": {
"map": [
{
"key": "12 34 56 78",
"value": 1
},
{
"key": "21 43 65 87",
"value": 2
},
{
"key": "87 65 43 21",
"value": 3
},
{
"key": "78 56 34 12",
"value": 4
}
]
}
},
"interval": {
"name": "Send Interval",
"name_zh": "指令发送间隔",
Expand Down
7 changes: 7 additions & 0 deletions plugins/modbus/modbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ typedef enum modbus_area {
MODBUS_AREA_HOLD_REGISTER = 4,
} modbus_area_e;

typedef enum modbus_endianess_64 {
MODBUS_LL = 1, // 12 34 56 78
MODBUS_LB = 2, // 21 43 65 87
MODBUS_BB = 3, // 87 65 43 21
MODBUS_BL = 4, // 78 56 34 12
} modbus_endianess_64;

struct modbus_header {
uint16_t seq;
uint16_t protocol;
Expand Down
40 changes: 34 additions & 6 deletions plugins/modbus/modbus_point.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ modbus_read_cmd_sort_t *modbus_tag_sort(UT_array *tags, uint16_t max_byte)
return sort_result;
}

int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option,
modbus_endianess_64 endianess_64, bool default_tag_endian_64)
{
int n = 0;
switch (type) {
Expand All @@ -240,6 +241,9 @@ int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
case NEU_TYPE_DOUBLE:
case NEU_TYPE_INT64:
case NEU_TYPE_UINT64:
if (default_tag_endian_64) {
modbus_convert_endianess_64(value, endianess_64);
}
n = sizeof(uint64_t);
value->u64 = neu_htonll(value->u64);
break;
Expand Down Expand Up @@ -273,7 +277,8 @@ int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
return n;
}

modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags)
modbus_write_cmd_sort_t *
modbus_write_tags_sort(UT_array *tags, modbus_endianess_64 endianess_64)
{
neu_tag_sort_result_t *result =
neu_tag_sort(tags, tag_sort_write, tag_cmp_write);
Expand All @@ -295,14 +300,17 @@ modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags)
utarray_foreach(result->sorts[i].tags, modbus_point_write_t **, tag_s)
{
if ((*tag_s)->point.area == MODBUS_AREA_COIL) {
n_byte_tag = cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
(*tag_s)->point.option);
n_byte_tag =
cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
(*tag_s)->point.option, endianess_64, true);
data_bit[k / 8] += ((*tag_s)->value.i8) << k % 8;
n_byte += n_byte_tag;
k++;
} else {
n_byte_tag = cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
(*tag_s)->point.option);
n_byte_tag =
cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
(*tag_s)->point.option, endianess_64,
(*tag_s)->point.option.value64.is_default);
memcpy(sort_result->cmd[i].bytes +
2 *
((*tag_s)->point.start_address -
Expand Down Expand Up @@ -512,4 +520,24 @@ static bool tag_sort_write(neu_tag_sort_t *sort, void *tag,
}

return true;
}

void modbus_convert_endianess_64(neu_value_u * value,
modbus_endianess_64 endianess_64)
{
switch (endianess_64) {
case MODBUS_LL:
break;
case MODBUS_BB:
value->u64 = neu_htonll(value->u64);
break;
case MODBUS_LB:
value->u64 = neu_htonlb(value->u64);
break;
case MODBUS_BL:
value->u64 = neu_htonbl(value->u64);
break;
default:
break;
}
}
10 changes: 7 additions & 3 deletions plugins/modbus/modbus_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,13 @@ typedef struct modbus_write_cmd_sort {
modbus_write_cmd_t *cmd;
} modbus_write_cmd_sort_t;

modbus_read_cmd_sort_t * modbus_tag_sort(UT_array *tags, uint16_t max_byte);
modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags);
void modbus_tag_sort_free(modbus_read_cmd_sort_t *cs);
modbus_read_cmd_sort_t *modbus_tag_sort(UT_array *tags, uint16_t max_byte);
modbus_write_cmd_sort_t *
modbus_write_tags_sort(UT_array *tags, modbus_endianess_64 endianess_64);
void modbus_tag_sort_free(modbus_read_cmd_sort_t *cs);

void modbus_convert_endianess_64(neu_value_u * value,
modbus_endianess_64 endianess_64);

#ifdef __cplusplus
}
Expand Down
9 changes: 8 additions & 1 deletion plugins/modbus/modbus_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,10 @@ int modbus_value_handle(void *ctx, uint8_t slave_id, uint16_t n_byte,
case NEU_TYPE_DOUBLE:
case NEU_TYPE_INT64:
case NEU_TYPE_UINT64:
if ((*p_tag)->option.value64.is_default) {
modbus_convert_endianess_64(&dvalue.value,
plugin->endianess_64);
}
dvalue.value.u64 = neu_ntohll(dvalue.value.u64);
break;
case NEU_TYPE_BIT: {
Expand Down Expand Up @@ -485,6 +489,9 @@ int modbus_write(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
case NEU_TYPE_DOUBLE:
case NEU_TYPE_INT64:
case NEU_TYPE_UINT64:
if (tag->option.value64.is_default) {
modbus_convert_endianess_64(&value, plugin->endianess_64);
}
value.u64 = neu_htonll(value.u64);
n_byte = sizeof(uint64_t);
break;
Expand Down Expand Up @@ -552,7 +559,7 @@ int modbus_write_tags(neu_plugin_t *plugin, void *req, UT_array *tags)

utarray_push_back(gtags->tags, &p);
}
gtags->cmd_sort = modbus_write_tags_sort(gtags->tags);
gtags->cmd_sort = modbus_write_tags_sort(gtags->tags, plugin->endianess_64);
for (uint16_t i = 0; i < gtags->cmd_sort->n_cmd; i++) {
uint16_t response_size = 0;

Expand Down
2 changes: 2 additions & 0 deletions plugins/modbus/modbus_req.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ struct neu_plugin {
uint16_t interval;
uint16_t retry_interval;
uint16_t max_retries;

modbus_endianess_64 endianess_64;
};

void modbus_conn_connected(void *data, int fd);
Expand Down
Loading
Loading