[Modbus] 如何 用 C# 開發 Modbus Master Protocol - (06) 實作 ModbusException

[Modbus] 如何 用 C# 開發 Modbus Master Protocol - (06) 實作 ModbusException

根據 Modbus 文件我需要一個自訂的 ModbusException

請參考 MSDN :設計自訂例外狀況 http://msdn.microsoft.com/zh-tw/library/ms229064.aspx

下圖為文件部份資料。

image

 

所以我將文件提供的資料,建立了以下 ModbusException 類別:

[Serializable]
public class ModbusException : Exception
{
    private static List<ModbusException> s_ModbusExceptionCollection;

    public virtual byte Code { get; set; }

    public virtual string Description { get; set; }

    public ModbusException()
        : base("show message") { }

    public ModbusException(string message)
        : base(message) { }

    public ModbusException(string message, Exception inner)
        : base(message, inner) { }

    protected ModbusException(SerializationInfo info, StreamingContext context)
        : base(info, context) { }

    private static IEnumerable<ModbusException> ModbusExceptionCollection
    {
        get
        {
            if (s_ModbusExceptionCollection == null)
            {
                s_ModbusExceptionCollection = new List<ModbusException>();
                s_ModbusExceptionCollection.Add(new ModbusException("ILLEGAL FUNCTION") { Code = 0x01, Description = "The function code received in the query is not an allowable action for the server. This may be because the function code is only applicable to newer devices, and was not implemented in the unit selected. It could also indicate that the serveris in the wrong state to process a request of this type, for example because it is unconfigured and is being asked to return register values." });
                s_ModbusExceptionCollection.Add(new ModbusException("ILLEGAL DATA ADDRESS") { Code = 0x02, Description = "The data address received in the query is not an allowable address for the  server. More specifically, the combination of reference number and transfer length is invalid. For a controller with 100 registers, the PDU addresses the first register as 0, and the last one as 99. If a request is submitted with a starting register address of 96 and a quantity of registers of 4, then this request will successfully operate (address-wise at least) on registers 96, 97, 98, 99. If a request is submitted with a starting register address of 96 and a quantity of registers of 5, then this request will fail with Exception Code 0x02 “Illegal Data Address” since it attempts to operate on registers 96, 97, 98, 99 and 100, and there is no register with address 100." });
                s_ModbusExceptionCollection.Add(new ModbusException("ILLEGAL DATA VALUE") { Code = 0x03, Description = "A value contained in the query data field is not an allowable value for server. This indicates a fault in the structure of the remainder of a complex request, such as that the implied length is incorrect. It specifically does NOT mean that a data item submitted for storage in a register has a value outside the expectation of the application program, since the MODBUS protocol is unaware of the significance of any particular value of any particular register." });
                s_ModbusExceptionCollection.Add(new ModbusException("SERVER DEVICE FAILURE") { Code = 0x04, Description = "An unrecoverable error occurred while the serverwas attempting to perform the requested action." });
                s_ModbusExceptionCollection.Add(new ModbusException("ACKNOWLEDGE") { Code = 0x05, Description = "Specialized use in conjunction with programming commands.The server  has accepted the request and is processing it, but a long duration of time will be required to do so. This response is returned to prevent a timeout error from occurring in the client. The client can next issue a Poll Program Complete message to determine if processing is completed." });
                s_ModbusExceptionCollection.Add(new ModbusException("SERVER DEVICE BUSY") { Code = 0x06, Description = "Specialized use in conjunction with programming commands.The server  is engaged in processing a long–duration program command. The client  should retransmit the message later when the server is free." });
                s_ModbusExceptionCollection.Add(new ModbusException("MEMORY PARITY ERROR") { Code = 0x08, Description = "Specialized use in conjunction with function codes 20 and 21 and reference type 6, to indicate that the extended file area failed to pass a consistency check.The server  attempted to read record file, but detected a parity error in the memory. The client can retry the request, but service may be required MODBUS Application Protocol Specification V1.1b3  ModbusApril 26, 2012  http://www.modbus.org  49/50on the server device." });
                s_ModbusExceptionCollection.Add(new ModbusException("GATEWAY PATH UNAVAILABLE") { Code = 0x0A, Description = "Specialized use in conjunction with gateways,indicates that the gateway was unable to allocate an internal communication path from the input port to the output port for processing the request. Usually means that the gateway is misconfigured or overloaded." });
                s_ModbusExceptionCollection.Add(new ModbusException("GATEWAY TARGET DEVICE FAILED TO RESPOND") { Code = 0x0B, Description = "Specialized use in conjunction with gateways, indicates that no response was obtained from the target device. Usually means that the device is not present on the network." });
            }
            return s_ModbusExceptionCollection;
        }
    }

    public static ModbusException GetModbusException(byte Code)
    {
        var query = (from ex in ModbusException.ModbusExceptionCollection
                     where ex.Code == Code
                     select ex).FirstOrDefault();

        return query;
    }
}
 
 
調用時機:

 

當取得 ModbusReponse 的結果,Function Code 大於 0x80 時調用。

image

 

調用方式
var ex = ModbusException.GetModbusException(0x01);

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo