1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4
5 #include "aos/kernel.h"
6 #include "mbmaster.h"
7 #include "ulog/ulog.h"
8 #if AOS_COMP_CLI
9 #include "aos/cli.h"
10 #endif
11
12 /* Define the parameters */
13 #define SERIAL_PORT (1) /* uart port */
14 #define SERIAL_BAUD_RATE (9600) /* uart baud rate */
15 #define DEVICE1_SLAVE_ADDR_1 (0x1) /* remote deveice address */
16 #define DEVICE1_SLAVE_ADDR_2 (0x2) /* remote deveice address */
17 #define DEVICE1_REG1_ADDR (0x0) /* register address of remote device */
18 #define RECV_LEN_MAX (20) /* buffer len, must >= (REQ_REGISTER_NUMBER * 2) */
19 #define REQ_REGISTER_NUMBER (10) /* Number of registers requested */
20
21 /* mode name used by ulog */
22 #define MODBUSM_APP "modbus_app"
23
mb_master_main(void)24 void mb_master_main(void)
25 {
26 uint8_t buf[RECV_LEN_MAX];
27 uint8_t len;
28 mb_status_t status;
29 uint16_t simulator1 = 0, simulator2 = 0;
30 uint16_t data_write = 0, data_resp = 0;
31 uint16_t *register_buf;
32
33 /* The handler is allocated by calling the aos_mbmaster_rtu_init */
34 mb_handler_t *mb_handler_master;
35
36 /**
37 * Initialize the modbus communication port, using rtu mode.
38 * Need to set the appropriatet port number, baud rate, parity
39 * according to the actual situation.
40 */
41 status = mbmaster_rtu_init(&mb_handler_master, SERIAL_PORT, SERIAL_BAUD_RATE, MB_PAR_NONE, 500);
42 LOGD(MODBUS_MOUDLE, "mbmaster_rtu_init status is %d\n", status);
43 if (status != MB_SUCCESS) {
44 LOGE(MODBUSM_APP, "mbmaster init error\n");
45 return;
46 }
47
48 /* note: This example loops every 2 seconds, first sending a write request, then sending a read request. */
49 while (1) {
50 #if 1
51 /**
52 * Initiate write single registers request.
53 * data_resp: respond from the remote device. If the write operation succeeds,
54 * it's equal to data_write.
55 */
56 status = mbmaster_write_single_register(mb_handler_master, DEVICE1_SLAVE_ADDR_1, DEVICE1_REG1_ADDR,
57 data_write, NULL, &data_resp, NULL, AOS_WAIT_FOREVER);
58 if (status == MB_SUCCESS) {
59 if (data_write != data_resp) {
60 LOGE(MODBUSM_APP, "write single register error\n");
61 } else {
62 LOGI(MODBUSM_APP, "write single register ok\n");
63 }
64 } else {
65 LOGE(MODBUSM_APP, "write single register error\n");
66 }
67
68 data_write++; /* generate a new value */
69
70 aos_msleep(1000 * 3);
71 #endif
72
73 #if 1
74 memset(buf, 0, RECV_LEN_MAX);
75 /**
76 * Initiate read holding registers request
77 * The buf length needs to be greater than or equal to (REQ_REGISTER_NUMBER * 2)
78 */
79 status = mbmaster_read_holding_registers(mb_handler_master, DEVICE1_SLAVE_ADDR_2, DEVICE1_REG1_ADDR,
80 REQ_REGISTER_NUMBER, buf, &len, AOS_WAIT_FOREVER);
81 if (status == MB_SUCCESS) {
82 /* The register length on modbus is 16 bits */
83 register_buf = (uint16_t *)buf;
84 simulator1 = register_buf[0];
85 simulator2 = register_buf[1];
86 LOGI(MODBUSM_APP, "read holding register simulator1: %d,simulator2: %d\n", simulator1, simulator2);
87 } else {
88 LOGE(MODBUSM_APP, "read holding register error\n");
89 }
90 #endif
91 aos_msleep(1000 * 3);
92 }
93 }
94
mb_slave_main(uint8_t dev_addr)95 void mb_slave_main(uint8_t dev_addr)
96 {
97 uint8_t buf[RECV_LEN_MAX];
98 uint8_t len;
99 mb_status_t status;
100 uint16_t simulator1 = 0, simulator2 = 0;
101 uint16_t data_write = 0, data_resp = 0;
102 uint16_t *register_buf;
103
104 /* The handler is allocated by calling the aos_mbmaster_rtu_init */
105 mb_handler_t *mb_handler_slave = NULL;
106
107 /**
108 * Initialize the modbus communication port, using rtu mode.
109 * Need to set the appropriatet port number, baud rate, parity
110 * according to the actual situation.
111 */
112 status = mbmaster_rtu_init(&mb_handler_slave, SERIAL_PORT, SERIAL_BAUD_RATE, MB_PAR_NONE, 100);
113 LOGD(MODBUS_MOUDLE, "mbmaster_rtu_init status is %d\n", status);
114 if (status != MB_SUCCESS) {
115 LOGE(MODBUSM_APP, "mbmaster init error\n");
116 return;
117 }
118
119 /* wait slave respond */
120 LOGD(MODBUS_MOUDLE, "device [0x%x] waiting for cmd\n", dev_addr);
121 while (1) {
122 /* frame recv */
123 status = mb_handler_slave->frame_recv(mb_handler_slave);
124 if (status == MB_SUCCESS) {
125 /* frame handle and response */
126 status = mb_handler_slave->adu_disassemble(mb_handler_slave);
127 if (status == MB_SUCCESS) {
128 uint8_t addr = mb_handler_slave->slave_addr;
129 uint8_t len = mb_handler_slave->pdu_length;
130 uint8_t offset = mb_handler_slave->pdu_offset;
131 uint8_t *data = mb_handler_slave->mb_frame_buff;
132
133 if (addr == dev_addr) {
134 switch (addr) {
135 case DEVICE1_SLAVE_ADDR_1:
136 // no need to process 0x06
137 mb_handler_slave->pdu_length = len;
138 break;
139
140 case DEVICE1_SLAVE_ADDR_2:
141 // 0x01 0x03 0x00 0x00 0x00 0x0a 0xc5 0xcd
142 {
143 uint16_t reg_start = data[2] << 8 | data[3];
144 uint16_t reg_len = data[4] << 8 | data[5];
145
146 mb_handler_slave->pdu_length = reg_len * 2 + 2;
147
148 data[ADU_SER_PDU_OFF + 1] = reg_len * 2;
149 for (uint16_t k = 0; k < reg_len; k++) {
150 data[ADU_SER_PDU_OFF + 2 + k * 2] = 0x00;
151 data[ADU_SER_PDU_OFF + 2 + k * 2 + 1] = k & 0xFF;
152 }
153 break;
154 }
155
156 default:
157 LOGE(MODBUS_MOUDLE, "Unsupported device addr [0x%2X]\n", addr);
158 }
159
160 status = mb_handler_slave->adu_assemble(mb_handler_slave);
161 status = mb_handler_slave->frame_send(mb_handler_slave, 100);
162 if (status != MB_SUCCESS) {
163 LOGD(MODBUS_MOUDLE, "Failed to send response to master\n");
164 }
165 }
166 }
167 }
168 }
169 }
170
mbmaster_comp_example(int argc,char * argv[])171 int mbmaster_comp_example(int argc, char *argv[])
172 {
173 aos_set_log_level(AOS_LL_DEBUG);
174
175 LOGI(MODBUSM_APP, "mbmaster test\n");
176
177 mb_master_main();
178
179 return 0;
180 }
181
mbslave_comp_example(int argc,char * argv[])182 int mbslave_comp_example(int argc, char *argv[])
183 {
184 aos_set_log_level(AOS_LL_DEBUG);
185
186 if (argc == 1) {
187 mb_slave_main(DEVICE1_SLAVE_ADDR_1);
188 } else {
189 mb_slave_main(*argv[1] - 48);
190 }
191
192 return 0;
193 }
194
195 #if AOS_COMP_CLI
196 /* reg args: fun, cmd, description*/
197 ALIOS_CLI_CMD_REGISTER(mbmaster_comp_example, mbmaster_example, mbmaster component base master example)
198 ALIOS_CLI_CMD_REGISTER(mbslave_comp_example, mbslave_example, mbmaster component base salve example)
199 #endif
200
201