Write a stable code of the Modbus bit experience

Source: Internet
Author: User
Tags new set

1. Introduction

Modbus is an important protocol in the industrial field, the physical layer has a common RS485 twisted pair and TCP, so it is often said that Modbus 485 development and Modbus TCP development.

The former is the serial communication, relatively simple. The latter relates to network protocols, which have several levels of complexity.

However, if there is a stable TCP communication to do the foreshadowing, the two types of Modbus difference is not big, is the data packet parsing, can share most of the code.

This article does not discuss how the Modbus protocol reads or writes a register or coil, and these things look at the documentation or search the blog tutorial online.

The objective of this paper is to discuss how to write a stable modbus communication driver, since Modbus TCP operation of Modbus in addition to a special 7-byte header and no CRC, the other parts and Modbus 485 no difference, so this article on Modbus TCP also has reference significance.

2. RS485 Communication

Some application scenarios do not use Modbus protocol, but simple serial communication, and then add and check, Transport layer using RS485, such applications can be classified as RS485 communication category.

In fact, personal feeling, are to do this, it is better to use Modbus directly to do, the complexity is not much, the benefits are many. For example, the use of Modbus a large number of popular testing tools to do system testing. The system can be made into a standard product, but also conducive to customer use and testing. There are also ready-made general-purpose protocols, which are generally more stable than the protocols they set.

For example, I have seen a few of the company's products:

This is a motor controller, using RS485 communication, but the essence is serial communication, plus the head 0x4a, and Terminator 0d,0a, as well as and checksum.

This is a BMS manufacturer's manual, RS485 communication, and above, is based on the RS485 serial communication.

This type of driver needs to be considered from the stability and legibility, if the stability of poor will cause system control failure, if the poor legibility will cause difficult to maintain, the difference between these control instructions is very small, if a separate write command, very easy to error. The corresponding initiatives are as follows:

1) Avoid each instruction to write part of the code, need to be unified processing, such as check function, send function, receive function and so on.

The communication protocol is known, from which you can know the actual data length of the communication (which does not include the header and checksum of the packet), so you can control how many bytes read and write, and know when to start the check, and those data participate in the checksum calculation.

2) Set up a list of instructions for the instruction, so that you can add the function to the list, then you will be able to include the instruction word directly.

3) Appropriate abstraction. Write a callback function for the action of each instruction, so that you can manipulate the specific action function directly in the application layer with a simple callback function pointer, rather than applying the logic layer to manipulate the interface of the specific drive plane.

4) Timeout, there must be a timeout mechanism. How to deal with communication failure? Communication, the general line is broken how to deal with it? You cannot have the system death a few bytes later.

5) Novice and some small companies often do not pay attention to a problem--do not close the communication port.

If the communication is initiated by you, the communication port should be closed whether the communication is completed or timed out or failed.

Because logically speaking, there should be no data to disturb the work of the system after this moment.

Motor_send_cmd (Cmd_type);//Send commandif(Xqueuereceive (Motorqueue, &motormsg, $) = = Pdpass)//Wait Response{Check= Motor_rcv_check (&motormsg, &motor_cmd_struct); if(check) {...} Else //check failed{motor_rs485_mode (Uart_off); }}Else //Timeout{motor_rs485_mode (Uart_off);}

3. Modbus Drive

  With the above high-quality 485 serial communication driver, the modification of Modbus communication protocol is very simple. However, the Modbus TCP receive section has no frame interval timeout, because it is guaranteed by the TCP protocol.

A more complete Modbus driver should pay attention to the following points:

1) Receive time-out mechanism, can not rely on the number of bytes transmitted to stop receiving and distinguish the frame interval, because the possible communication is broken, so in accordance with the Protocol, serial communication in the case of a bit idle is considered a frame end.

2) Response time-out mechanism, Modbus is the master-slave question-and-answer communication, then the host needs to know exactly how long from the machine will answer, the host waiting for the maximum time to answer from the machine is from the machine's largest reply interval, more than this time from the machine even if the calculation can not reply, Because the host may have started sending data to other slave computers at this point.

3) Modbus address may be many, then need a table to manage, cannot write a if--else if--else if to handle an address operation.

4) If the table manages thousands of addresses, then the search for the address needs an efficient algorithm, the sequential search must be too low, it is best to use two points to find.

5) Some write registers may need to set the machine, such as online change baud rate, if the baud rate and the new set baud rate, then do not need to execute the serial port initialization code, so at each address table row, need a specific callback function, search for an address, you can manipulate the callback function, Perform some actions.

6) If a resource has more than one task access, you need to read and write mutexes.

7) If a resource reads and writes is not atomic, then it needs to be locked. To avoid half the change, read it by other tasks, and read half the old value half the new value.

8) Modular, read-write register interface needs to be packaged up, external exposure to 3 parameters, Function,addr,*value can be.

/** * @brief modbus callbcak function. cmd like:mac>up\r\n * @param value to read or write.  * @retval 1=success, 0=fail. */uint8_t lockup_w (uint16_t*value) {    .... //Specific Executive Section
return 1;}/** * @brief modbus Callbcak function. * @param value to read or write. * @retval 1=success, 0=fail. */uint8_t Lockdown_r (uint16_t*value) { if(*value) { *value =0; } return 1;}/** * @brief modbus callbcak function. cmd like:mac>down\r\n * @param value to read or write. * @retval 1=success, 0=fail. */uint8_t lockdown_w (uint16_t*value) { .....
return 1;}/** * @brief modbus Callbcak function. * @param value to write. * @retval 1=success, 0=fail. */uint8_t Mdtimeout_r (uint16_t*value) { ....
return 1;}/** * @brief modbus Callbcak function. * @param value to read. * @retval 1=success, 0=fail. */uint8_t mdtimeout_w (uint16_t*value) {systemticklimitcfg (TMOUT_MB,*value); return 1;}
Table data structure, in addition to the basic address, you can also include the range of variables, magnification, callback functions, etc.
typedef struct
{
uint8_t func;
uint16_t addr;
uint16_t min;
uint16_t Max;
uint16_t *value;
uint8_t (*pfunc) (uint16_t *value);
}mb_reg_struct;

/** * @brief modbus table.*/mb_reg_struct mbreg[]={ /*func, addr, Min, Max, &value, CallBack ()*/ {0x03,1,0,1, &holdreg.up, Lockup_r}, {0x03,2,0,1, &holdreg.dowm, Lockdown_r}, {0x06,1,0,1, &holdreg.up, Lockup_w}, {0x06,2,0,1, &holdreg.dowm, Lockdown_w}, {0x04,1,1, the, &inputreg.md_addr, Pnone}, {0x04,2,0,0xFF, &inputreg.lock_stats, Pnone}, {0x04,3,0, -, &Inputreg.soc, Pnone}, {0x04,4,0,127, &Inputreg.rssi, Pnone}, {0x04,5,0,1, &Inputreg.search, Pnone}, {0x04,6,0,0, &inputreg.reserve[0], Pnone}, {0x04,7,0,0, &inputreg.reserve[1], Pnone}, {0x04,8,0,0, &inputreg.reserve[2], Pnone}, {0x04,9,0,0xFFFF, &inputreg.mac_ble[0], Pnone}, {0x04,Ten,0,0xFFFF, &inputreg.mac_ble[1], Pnone}, {0x04, One,0,0xFFFF, &inputreg.mac_ble[2], Pnone}, {0x04, A,0,0xFFFF, &inputreg.mac_ble[3], Pnone}, {0x04, -,0,0xFFFF, &inputreg.mac_ble[4], Pnone}, {0x04, -,0,0xFFFF, &inputreg.mac_ble[5], Pnone}, {0x04, the,0,0xFFFF, &inputreg.mac_lock[0], Pnone}, {0x04, -,0,0xFFFF, &inputreg.mac_lock[1], Pnone}, {0x04, -,0,0xFFFF, &inputreg.mac_lock[2], Pnone}, {0x04, -,0,0xFFFF, &inputreg.mac_lock[3], Pnone}, {0x04, +,0,0xFFFF, &inputreg.mac_lock[4], Pnone}, {0x04, -,0,0xFFFF, &inputreg.mac_lock[5], pnone},};

Write a stable code of the Modbus bit experience

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.