一组RS485设备操作命令

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ZNJM2.Win
{
    public class CommandBase
    {
        public byte Addr { get; set; }

        public List<byte> CmdBytes { get; protected set; }
        public string Name { get; set; }
        public Object Result { get; set; }
        public DateTime? BTime { get; set; }
        public DateTime? ETime { get; set; }
        public int delayMillis { get; set; }
        protected Func<byte[], int, byte[]> CRC { get; set; }
        /// <summary>
        /// 执行次数
        /// </summary>
        public long? RunCount { get; set; }
        /// <summary>
        /// 错误次数
        /// 每次成功执行后设置成0
        /// </summary>
        public long? ErrCount { get; set; }
        public Exception Err { get; set; }

        public List<byte> ReturnBytes { get; set; }

        /// <summary>
        ///  如 01 02,
        ///     01-02,
        ///     0102,
        ///   等形式
        /// </summary>
        public string CmdText { get; set; }
        public string CmdHexString
        {
            get
            {
                return BitConverter.ToString(CmdBytes.ToArray());
            }
        }
        public CommandBase()
        {
            CmdBytes=new List<byte>();
            ReturnBytes = new List<byte>();
            Addr = 0x01;
            ErrCount = 0;
            RunCount = 0;
            CRC = CRCUtil.CRC16;

        }

        #region 方法

        /// <summary>
        /// 生成命令的字节数组
        ///  如 01 02
        ///     01-02
        ///     0102
        ///   等形式
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public virtual List<byte> ParserCmd()
        {
            var cmdBytes = ParserCmdWithoutCRC();
            var crc2 = CRC(cmdBytes, cmdBytes.Length);

            CmdBytes = new List<byte>(cmdBytes.Concat(crc2));
            return CmdBytes;

        }

        protected virtual byte[] ParserCmdWithoutCRC()
        {
            string cmdText = CmdText;
            var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim();
            if (string.IsNullOrWhiteSpace(cmd))
            {
                throw new Exception("空字符串!");
            }
            if ((cmd.Length % 2) != 0)
            {
                throw new Exception("命令字符窜长度必须是2的倍数!");
            }
            cmd = BitConverter.ToString(new byte[] { Addr }) + cmd;
            var cmdBytes = new byte[cmd.Length / 2];
            for (int i = 0; i < cmd.Length; i = i + 2)
            {
                cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
            }
            return cmdBytes;
        }

        protected virtual bool VerifyResult()
        {

            if (ReturnBytes.Count <= 0)
            {
                Err=new Exception("零长度返回!");
                ErrCount++;
                return false;

            }
            if (ReturnBytes.Count <= 2)
            {
                Err = new Exception("返回字节少于2!");
                ErrCount++;
                return false;
            }

            //CRC Check\
            var len = ReturnBytes.Count;
            var crc = CRC(ReturnBytes.ToArray(), len-2);
            if (crc[0] != ReturnBytes[len - 2] || crc[1] != ReturnBytes[len - 1])
            {
                Err = new Exception("CRC校验错误!");
                ErrCount++;
                return false;
            }

            if (ReturnBytes[0] != Addr)
            {
                Err = new Exception("非期望的设备地址!");
                ErrCount++;
                return false;
            }
            if (ReturnBytes[1] != CmdBytes[1])
            {
                Err = new Exception("非期望的命令!");
                ErrCount++;
                return false;
            }

            return true;
        }

        public virtual bool ParserReturn()
        {
            return VerifyResult();

        }
        #endregion
    }
    public class RFIDCmdBase : CommandBase
    {
        public RFIDCmdBase()
        {

            CRC = CRCUtil.CRC16ForRFID;

        }

        /// <summary>
        /// 生成命令的字节数组
        ///  如 01 02
        ///     01-02
        ///     0102
        ///   等形式
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public override List<byte> ParserCmd()
        {
            var cmdBytes = ParserCmdWithoutCRC();
            var crc2 = CRC(cmdBytes, cmdBytes.Length);

            CmdBytes = new List<byte>(cmdBytes.Concat(crc2));
            return CmdBytes;

        }

        protected override byte[] ParserCmdWithoutCRC()
        {
            string cmdText = CmdText;
            var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim();
            if (string.IsNullOrWhiteSpace(cmd))
            {
                throw new Exception("空字符串!");
            }
            if ((cmd.Length % 2) != 0)
            {
                throw new Exception("命令字符窜长度必须是2的倍数!");
            }
            cmd = BitConverter.ToString(new byte[] { Addr }) + cmd;
            var cmdBytes = new byte[cmd.Length / 2];
            for (int i = 0; i < cmd.Length; i = i + 2)
            {
                cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
            }

            var lenV = (byte)(cmdBytes.Length + 2); //添加命令长度
            return new byte[] { lenV }.Concat(cmdBytes).ToArray();

        }

        protected override bool VerifyResult()
        {

            if (ReturnBytes.Count <= 0)
            {
                Err = new Exception("零长度返回!");
                ErrCount++;
                return false;

            }
            if (ReturnBytes.Count <= 5)
            {
                Err = new Exception("返回字节少于5!");
                ErrCount++;
                return false;
            }

            //CRC Check\
            var len = ReturnBytes.Count;
            var crc = CRC(ReturnBytes.ToArray(), len - 2);
            if (crc[0] != ReturnBytes[len - 2] || crc[1] != ReturnBytes[len - 1])
            {
                Err = new Exception("CRC校验错误!");
                ErrCount++;
                return false;
            }

            if (ReturnBytes[1] != Addr)
            {
                Err = new Exception("非期望的设备地址!");
                ErrCount++;
                return false;
            }
            if (ReturnBytes[2] != CmdBytes[2])
            {
                Err = new Exception("非期望的命令!");
                ErrCount++;
                return false;
            }

            return true;
        }

    }

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace ZNJM2.Win
{
    #region 开关命令
    public class PowerSwitchQuery : CommandBase
    {
        public PowerSwitchQuery(byte addr)
        {
            Addr = addr;
            CmdText = "03";
            CmdBytes = ParserCmd();
            Name = "开关-状态";
        }

        public override bool ParserReturn()
        {
            bool flag = false;
            flag = base.VerifyResult();
            if (flag && ReturnBytes.Count >= 5)
            {
                flag = true;
                Result = ReturnBytes[2] == 0 ? "Off" : "On";
                ErrCount = 0;
                Err = null;

            }

            return flag;

        }
    }

    public class PowerSwitchOn : CommandBase
    {
        public PowerSwitchOn(byte addr)
        {
            Addr = addr;
            CmdText = "0601";
            CmdBytes = ParserCmd();
            Name = "开关-打开";
        }
    }

    public class PowerSwitchOff : CommandBase
    {
        public PowerSwitchOff(byte addr)
        {
            Addr = addr;
            CmdText = "0600";
            CmdBytes = ParserCmd();
            Name = "开关-关闭";
        }
    }
    #endregion

    #region 计米器
    public class LengthCounterQuery : CommandBase
    {
        public LengthCounterQuery(byte addr)
        {
            Addr = addr;
            CmdText = "03 00 01";
            ParserCmd();
            Name = "计米器-读数";
        }

        public override bool ParserReturn()
        {
            var flag=base.ParserReturn();

            if (ReturnBytes.Count > 6 && flag)
            {

                var vhex = BitConverter.ToString(new byte[] { ReturnBytes[5], ReturnBytes[6], ReturnBytes[3], ReturnBytes[4] });
                var value = int.Parse(vhex.Replace("-", ""), NumberStyles.HexNumber);
                Result = value;
                ErrCount = 0;
                Err = null;

            }
            return flag;

        }

    }

    //清空读数
    public class LengthCounterCls : CommandBase
    {
        public LengthCounterCls(byte addr)
        {
            Addr = addr;
            CmdText = "06 00 0C 01";
            ParserCmd();
            Name = "计米器-清零";
        }

    }
    #endregion

    #region 电表

        //public class VoltageQuery : CommandBase
        //{
        //    public VoltageQuery(byte addr)
        //    {
        //        Addr = addr;
        //        CmdText = "03-00-0C-00-02";
        //        CmdBytes = ParserCmd();
        //        Name = "电表-电压";
        //    }
        //    public override bool ParserReturn()
        //    {
        //        bool flag = false;
        //        flag = base.VerifyResult();
        //        if (flag && ReturnBytes.Count >= 7)
        //        {
        //            flag = true;
        //            Result = BitConverter.ToString(ReturnBytes.ToArray(), 0);
        //            Console.WriteLine(Result.ToString());

        //            var tempArr = new byte[4];
        //            ReturnBytes.CopyTo(3, tempArr, 0, 4);

        //            Result = BitConverter.ToSingle(tempArr.Reverse().ToArray(), 0);

        //            ErrCount = 0;
        //            Err = null;

        //        }

        //        return flag;

        //    }
        //}
        //public class ElectricCurrent : CommandBase
        //{
        //    public ElectricCurrent(byte addr)
        //    {
        //        Addr = addr;
        //        CmdText = "03-00-0A-00-02";
        //        CmdBytes = ParserCmd();
        //        Name = "电表-电流";
        //    }
        //    public override bool ParserReturn()
        //    {
        //        bool flag = false;
        //        flag = base.VerifyResult();
        //        if (flag && ReturnBytes.Count >= 7)
        //        {
        //            flag = true;
        //            Result = BitConverter.ToString(ReturnBytes.ToArray(), 0);
        //            Console.WriteLine(Result.ToString());
        //            ===========
        //            var tempArr = new byte[4];
        //            ReturnBytes.CopyTo(3, tempArr, 0, 4);

        //            Result = BitConverter.ToSingle(tempArr.Reverse().ToArray(), 0);

        //            ErrCount = 0;
        //            Err = null;

        //        }

        //        return flag;

        //    }
        //}
        //public class ElectricEnergy : CommandBase
        //{
        //    public ElectricEnergy(byte addr)
        //    {
        //        Addr = addr;
        //        CmdText = "03-00-1A-00-02";
        //        CmdBytes = ParserCmd();
        //        Name = "电表-电能";
        //    }
        //    public override bool ParserReturn()
        //    {
        //        bool flag = false;
        //        flag = base.VerifyResult();
        //        if (flag && ReturnBytes.Count >= 7)
        //        {
        //            flag = true;
        //            Result = BitConverter.ToString(ReturnBytes.ToArray(), 0);
        //            Console.WriteLine(Result.ToString());
        //           // ===========
        //            var tempArr = new byte[4];
        //            ReturnBytes.CopyTo(3, tempArr, 0, 4);

        //            Result = BitConverter.ToSingle(tempArr.Reverse().ToArray(), 0);

        //            ErrCount = 0;
        //            Err = null;

        //        }

        //        return flag;

        //    }
        //}
    #endregion

    #region 电表DDS238-1Z系列
        public class VoltageQuery : CommandBase
        {
            public VoltageQuery(byte addr)
            {
                Addr = addr;
                CmdText = "03-00-0C-00-01";
                CmdBytes = ParserCmd();
                Name = "电表-电压";
            }
            public override bool ParserReturn()
            {
                bool flag = false;
                flag = base.VerifyResult();
                if (flag && ReturnBytes.Count >= 7)
                {
                    flag = true;
                    Result = BitConverter.ToString(ReturnBytes.ToArray(), 0);
                    Console.WriteLine(Result.ToString());

                    var tempArr = new byte[2];
                    ReturnBytes.CopyTo(3, tempArr, 0, tempArr.Length);

                    Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), 0) * 0.1;

                    ErrCount = 0;
                    Err = null;

                }

                return flag;

            }
        }
        public class ElectricCurrent : CommandBase
        {
            public ElectricCurrent(byte addr)
            {
                Addr = addr;
                CmdText = "03-00-0d-00-01";
                CmdBytes = ParserCmd();
                Name = "电表-电流";
            }
            public override bool ParserReturn()
            {
                bool flag = false;
                flag = base.VerifyResult();
                if (flag && ReturnBytes.Count >= 5)
                {
                    flag = true;
                    Result = BitConverter.ToString(ReturnBytes.ToArray(), 0);
                    Console.WriteLine(Result.ToString());
                   // ===========
                    var tempArr = new byte[2];
                    ReturnBytes.CopyTo(3, tempArr, 0, tempArr.Length);

                    Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), 0) * 0.01;

                    ErrCount = 0;
                    Err = null;

                }

                return flag;

            }
        }
        public class ElectricEnergy : CommandBase
        {
            public ElectricEnergy(byte addr)
            {
                Addr = addr;
                CmdText = "03-00-00-00-02";
                CmdBytes = ParserCmd();
                Name = "电表-电能";
            }
            public override bool ParserReturn()
            {
                bool flag = false;
                flag = base.VerifyResult();
                if (flag && ReturnBytes.Count >= 7)
                {
                    flag = true;
                    Result = BitConverter.ToString(ReturnBytes.ToArray(), 0);
                    Console.WriteLine(Result.ToString());
                    // ===========
                    var tempArr = new byte[4];
                    ReturnBytes.CopyTo(3, tempArr, 0, tempArr.Length);

                    Result = BitConverter.ToUInt32(tempArr.Reverse().ToArray(), 0) * 0.01;

                    ErrCount = 0;
                    Err = null;

                }

                return flag;

            }
        }

        public class ElectricFrequency : CommandBase
        {
            public ElectricFrequency(byte addr)
            {
                Addr = addr;
                CmdText = "03-00-11-00-01";
                CmdBytes = ParserCmd();
                Name = "电表-频率";
            }
            public override bool ParserReturn()
            {
                bool flag = false;
                flag = base.VerifyResult();
                if (flag && ReturnBytes.Count >= 7)
                {
                    flag = true;
                    Result = BitConverter.ToString(ReturnBytes.ToArray(), 0);
                    Console.WriteLine(Result.ToString());
                    // ===========
                    var tempArr = new byte[2];
                    ReturnBytes.CopyTo(3, tempArr, 0, tempArr.Length);

                    Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), 0) * 0.01;

                    ErrCount = 0;
                    Err = null;

                }

                return flag;

            }
        }
    #endregion

#region RFID指令

     public class RFIDGetReaderInfo : RFIDCmdBase
        {
            /// <summary>
            /// 功率
            /// </summary>
            public byte Power { get; set; }
            /// <summary>
            /// 命令最大响应时间
            /// 单位100ms
            /// </summary>
            public byte CmdDelay { get; set; }
            public RFIDGetReaderInfo(byte addr)
        {
            Addr = addr;
            CmdText = "21";
            CmdBytes = ParserCmd();
            Name = "标签-获取读卡器信息";

        }

             public override bool ParserReturn()
        {

            bool flag = true;
            flag = base.VerifyResult();
            var RetArr=ReturnBytes.ToArray();
            var status = BitConverter.ToString(RetArr,3,1);
            if (ReturnBytes[3] != 0x00)
            {
                Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x00));
                ErrCount++;
                return false;
            }
            if (flag && ReturnBytes.Count >= 7)
            {
                flag = true;
                Result = BitConverter.ToString(RetArr, 0);
                //Console.WriteLine(Result.ToString());

                Power = RetArr[0x0A];
                CmdDelay = RetArr[0x0B];

                ErrCount = 0;
                Err = null;

            }

            return flag;

        }
        }
     public class RFIDQueryTID : RFIDCmdBase
    {

         public int? LblNum { get; set; }
         public List<String> LblList { get; set; }
        public RFIDQueryTID(byte addr)
        {
            Addr = addr;
            CmdText = "01 02 04";
            LblList = new List<string>();
            CmdBytes = ParserCmd();
            Name = "标签-查询TID";

        }

        public override bool ParserReturn()
        {
            LblNum = 0;
            LblList.Clear();

            bool flag = true;
            flag = base.VerifyResult();
            var RetArr=ReturnBytes.ToArray();
            var status = BitConverter.ToString(RetArr,3,1);
            if (ReturnBytes[3] != 0x01)
            {
                Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x01));
                ErrCount++;
                return false;
            }
            if (flag && ReturnBytes.Count >= 7)
            {
                flag = true;
                Result = BitConverter.ToString(RetArr, 0);
                //Console.WriteLine(Result.ToString());

                LblNum = ReturnBytes[4];
                int offset=5;
                for (int i = 0; i < LblNum; i++)
                {
                    var lblLen=ReturnBytes[offset];
                    var tmpArr=new byte[lblLen];
                    var startIndex=offset +1;
                    Array.Copy(RetArr, startIndex, tmpArr, 0, lblLen);
                    LblList.Add(BitConverter.ToString(tmpArr).Replace("-", ""));
                    offset += lblLen + 1;

                }

                ErrCount = 0;
                Err = null;

            }

            return flag;

        }
    }
     public class RFIDQueryEPC : RFIDCmdBase
     {

         public int? LblNum { get; set; }
         public List<String> LblList { get; set; }
         public List<List<byte>> LblBytesList { get; set; }
         public RFIDQueryEPC(byte addr)
         {
             Addr = addr;
             CmdText = "01";
             LblList = new List<string>();
             LblBytesList = new List<List<byte>>();
             CmdBytes = ParserCmd();
             Name = "标签-查询EPC";

         }

         public override bool ParserReturn()
         {
             LblNum = 0;
             LblList.Clear();

             bool flag = true;
             flag = base.VerifyResult();
             var RetArr = ReturnBytes.ToArray();
             var status = BitConverter.ToString(RetArr, 3, 1);
             if (ReturnBytes[3] != 0x01)
             {
                 Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x01));
                 ErrCount++;
                 return false;
             }
             if (flag && ReturnBytes.Count >= 7)
             {
                 flag = true;
                 Result = BitConverter.ToString(RetArr, 0);
                 //Console.WriteLine(Result.ToString());

                 LblNum = ReturnBytes[4];
                 int offset = 5;
                 for (int i = 0; i < LblNum; i++)
                 {
                     var lblLen = ReturnBytes[offset];
                     var tmpArr = new byte[lblLen];
                     var startIndex = offset + 1;
                     Array.Copy(RetArr, startIndex, tmpArr, 0, lblLen);
                     LblList.Add(BitConverter.ToString(tmpArr).Replace("-", ""));
                     LblBytesList.Add(tmpArr.ToList());
                     offset += lblLen + 1;

                 }

                 ErrCount = 0;
                 Err = null;

             }

             return flag;

         }
     }
     public class RFIDQueryTopOne : RFIDCmdBase
     {
         public int? LblNum { get; set; }
         public List<String> LblList { get; set; }
         public RFIDQueryTopOne(byte addr)
        {
            Addr = addr;
            CmdText = "0F";
            LblList = new List<string>();
            CmdBytes = ParserCmd();
            Name = "标签-查询单张";

        }

        public override bool ParserReturn()
        {
            LblNum = 0;
            LblList.Clear();

            bool flag = true;
            flag = base.VerifyResult();
            var RetArr=ReturnBytes.ToArray();
            var status = BitConverter.ToString(RetArr,3,1);
            if (ReturnBytes[3] != 0x01)
            {
                Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x01));
                ErrCount++;
                return false;
            }
            if (flag && ReturnBytes.Count >= 7)
            {
                flag = true;
                Result = BitConverter.ToString(RetArr, 0);
                //Console.WriteLine(Result.ToString());

                LblNum = ReturnBytes[4];
                int offset=5;
                for (int i = 0; i < LblNum; i++)
                {
                    var lblLen=ReturnBytes[offset];
                    var tmpArr=new byte[lblLen];
                    var startIndex=offset +1;
                    Array.Copy(RetArr, startIndex, tmpArr, 0, lblLen);
                    LblList.Add(BitConverter.ToString(tmpArr).Replace("-", ""));
                    offset += lblLen + 1;

                }

                ErrCount = 0;
                Err = null;

            }

            return flag;

        }
     }
     public class RFIDSetPower : RFIDCmdBase
     {
         /// <summary>
         ///
         /// </summary>
         /// <param name="addr"></param>
         /// <param name="power">功率 1-30</param>
         public RFIDSetPower(byte addr,byte power)
        {
            Addr = addr;
            CmdText = "2f" + BitConverter.ToString(new byte[]{power});

            CmdBytes = ParserCmd();
            Name = "标签-设置功率";

        }
         public override bool ParserReturn()
         {

             bool flag = true;
             flag = base.VerifyResult();
             var RetArr = ReturnBytes.ToArray();
             var status = BitConverter.ToString(RetArr, 3, 1);
             if (ReturnBytes[3] != 0x00)
             {
                 Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x01));
                 ErrCount++;
                 return false;
             }
             if (flag && ReturnBytes.Count >= 7)
             {
                 flag = true;
                 Result = "成功";

                 ErrCount = 0;
                 Err = null;

             }

             return flag;

         }
     }
     public class RFIDReadUserArea : RFIDCmdBase
     {

         public List<byte> ResultBytes { get; private set; }
         public List<byte> EPC { get; set; }
         private byte WordPtr { get; set; }
         private byte Num { get; set; }

         private RFIDReadUserArea()
         {
             CmdText = "02";
             ResultBytes = new List<byte>();
             Name = "标签-查询用户区域数据";
         }
         /// <summary>
         ///
         /// </summary>
         /// <param name="addr"></param>
         /// <param name="startAdd">开始位置(单位:字)</param>
         /// <param name="wordLen">字数,一个字二字节</param>
         public RFIDReadUserArea(byte addr,byte[] EPCArr,byte startAdd,byte wordLen):this()
         {
             Addr = addr;
             WordPtr = startAdd;
             Num = wordLen;

             if(EPCArr!=null)EPC = new List<byte>(EPCArr);
             CmdBytes = ParserCmd();

         }
         /// <summary>
         ///
         /// </summary>
         /// <param name="addr"></param>
         /// <param name="startAdd">开始位置(单位:字)</param>
         /// <param name="wordLen">字数,一个字二字节</param>
         public RFIDReadUserArea(byte addr, string EPCStr, byte startAdd, byte wordLen):this()
         {

             Addr = addr;
             WordPtr = startAdd;
             Num = wordLen;

             #region EPC
             var epc = EPCStr.Replace("-", "").Replace(" ", "");
             var epcdBytes = new byte[epc.Length / 2];
             for (int i = 0; i < epc.Length; i = i + 2)
             {
                 epcdBytes[i / 2] = byte.Parse(epc.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
             }
              EPC = new List<byte>(epcdBytes);
             #endregion

              CmdBytes = ParserCmd();

         }
         protected override byte[] ParserCmdWithoutCRC()
         {
             string cmdText = CmdText;
             var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim();
             if (string.IsNullOrWhiteSpace(cmd))
             {
                 throw new Exception("空字符串!");
             }
             if ((cmd.Length % 2) != 0)
             {
                 throw new Exception("命令字符窜长度必须是2的倍数!");
             }
             cmd = BitConverter.ToString(new byte[] { Addr }) + cmd;
             var cmdBytes = new byte[cmd.Length / 2];
             for (int i = 0; i < cmd.Length; i = i + 2)
             {
                 cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
             }
             //构建命令的data部分
             var data=new List<byte>();
             data.Add((byte)(EPC.Count / 2));//ENum
             data.AddRange(EPC);//EPC
             data.Add(0x03);//Mem
             data.Add(WordPtr);
             data.Add(Num);
             data.AddRange(new byte[] { 00, 00, 00, 00 });//Pwd
             #region 掩模
             //一字节为单位
             //不设置表示对整个EPC序列进行匹配
             //设置后,只对设置指定的开始位置到设定的字节数个字节进行匹配
             //如设置0开始,3字节,则进行的匹配是 xx-xx-xx-_________________
             //即只匹配前三个字节
             //data.AddRange(new byte[] { 0x0B, 0x01 });
             #endregion

             var lenV = (byte)(cmdBytes.Length + data.Count+ 2 ); //添加命令长度
             return new byte[] { lenV }.Concat(cmdBytes).Concat(data).ToArray();
         }
         public override bool ParserReturn()
         {

             ResultBytes.Clear();

             bool flag = true;
             flag = base.VerifyResult();
             var RetArr = ReturnBytes.ToArray();
             var status = BitConverter.ToString(RetArr, 3, 1);
             if (ReturnBytes[3] != 0x00)
             {
                 Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x00));
                 ErrCount++;
                 return false;
             }
             if (flag && ReturnBytes.Count >= (4 + (Num * 2) +2))
             {
                 flag = true;

                 var tmpArr = new byte[Num * 2];
                 Array.Copy(RetArr, 4, tmpArr, 0, tmpArr.Length);
                 ResultBytes.AddRange(tmpArr);
                 Result = BitConverter.ToString(tmpArr);

                 ErrCount = 0;
                 Err = null;

             }

             return flag;

         }
     }

     public class RFIDWriteUserArea : RFIDCmdBase
     {

         public List<byte> ResultBytes { get; set; }
         public List<byte> EPC { get; set; }
         private byte WordPtr { get; set; }
         private byte Num { get; set; }
         private byte[] Data { get; set; }
         private RFIDWriteUserArea()
         {
             CmdText = "03";
             ResultBytes = new List<byte>();
             Name = "标签-写用户区域数据";
         }
         /// <summary>
         ///
         /// </summary>
         /// <param name="addr"></param>
         /// <param name="startAdd">开始位置(单位:字)</param>
         /// <param name="datas">要写入的字,一个字二字节,datas长度必须是2的整数倍</param>
         public RFIDWriteUserArea(byte addr, byte[] EPCArr, byte startAdd, byte[] datas)
             : this()
         {
             Addr = addr;
             WordPtr = startAdd;
             Data = datas;
             if ((datas.Length % 2) != 0)
             {
                 throw new Exception("数据长度必须是2的整数倍!");
             }

             if (EPCArr != null) EPC = new List<byte>(EPCArr);
             CmdBytes = ParserCmd();

         }
         /// <summary>
         ///
         /// </summary>
         /// <param name="addr"></param>
         /// <param name="startAdd">开始位置(单位:字)</param>
         /// <param name="data">Unicode</param>
         public RFIDWriteUserArea(byte addr, string EPCStr, byte startAdd, string data)
             : this()
         {

             Addr = addr;
             WordPtr = startAdd;

             #region Data
             Data = Encoding.Unicode.GetBytes(data);
             #endregion
             #region EPC
             var epc = EPCStr.Replace("-", "").Replace(" ", "");
             var epcdBytes = new byte[epc.Length / 2];
             for (int i = 0; i < epc.Length; i = i + 2)
             {
                 epcdBytes[i / 2] = byte.Parse(epc.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
             }
             EPC = new List<byte>(epcdBytes);
             #endregion

             CmdBytes = ParserCmd();

         }
         protected override byte[] ParserCmdWithoutCRC()
         {
             string cmdText = CmdText;
             var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim();
             if (string.IsNullOrWhiteSpace(cmd))
             {
                 throw new Exception("空字符串!");
             }
             if ((cmd.Length % 2) != 0)
             {
                 throw new Exception("命令字符窜长度必须是2的倍数!");
             }
             cmd = BitConverter.ToString(new byte[] { Addr }) + cmd;
             var cmdBytes = new byte[cmd.Length / 2];
             for (int i = 0; i < cmd.Length; i = i + 2)
             {
                 cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
             }
             //构建命令的data部分
             var data = new List<byte>();
             var dataWords =(Data.Length / 2) ;
             data.Add((byte)dataWords);//WNUM
             data.Add((byte)(EPC.Count / 2));//ENum
             data.AddRange(EPC);//EPC
             data.Add(0x03);//Mem,0x03是用户区
             data.Add(WordPtr);
             data.AddRange(Data);
             data.AddRange(new byte[] { 00, 00, 00, 00 });//Pwd
             #region 掩模
             //一字节为单位
             //不设置表示对整个EPC序列进行匹配
             //设置后,只对设置指定的开始位置到设定的字节数个字节进行匹配
             //如设置0开始,3字节,则进行的匹配是 xx-xx-xx-_________________
             //即只匹配前三个字节
             //data.AddRange(new byte[] { 0x0B, 0x01 });
             #endregion

             var lenV = (byte)(cmdBytes.Length + data.Count + 2); //添加命令长度

             return new byte[] { lenV }.Concat(cmdBytes).Concat(data).ToArray();
         }
         public override bool ParserReturn()
         {

             ResultBytes.Clear();

             bool flag = true;
             flag = base.VerifyResult();
             var RetArr = ReturnBytes.ToArray();
             var status = BitConverter.ToString(RetArr, 3, 1);
             if (ReturnBytes[3] != 0x00)
             {
                 Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, "0x00"));
                 ErrCount++;
                 return false;
             }
             if (flag && ReturnBytes.Count >= 6)
             {
                 flag = true;

                 Result = "写入成功!";

                 ErrCount = 0;
                 Err = null;

             }

             return flag;

         }
     }
#endregion
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ZNJM2.Win
{
    #region 校验
    public static class CRCUtil
    {
        private static readonly byte[] aucCRCHi = {
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
            0x00, 0xC1, 0x81, 0x40
        };
        private static readonly byte[] aucCRCLo = {
            0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
            0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
            0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
            0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
            0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
            0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
            0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
            0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
            0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
            0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
            0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
            0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
            0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
            0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
            0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
            0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
            0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
            0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
            0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
            0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
            0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
            0x41, 0x81, 0x80, 0x40
        };
        /// <summary>
        /// CRC效验
        /// </summary>
        /// <param name="pucFrame">效验数据</param>
        /// <param name="usLen">数据长度</param>
        /// <returns>效验结果</returns>
        public static byte[] CRC16(byte[] pucFrame, int usLen)
        {
            int i = 0;
            byte ucCRCHi = 0xFF;
            byte ucCRCLo = 0xFF;
            UInt16 iIndex = 0x0000;

            while (usLen-- > 0)
            {
                iIndex = (UInt16)(ucCRCLo ^ pucFrame[i++]);
                ucCRCLo = (byte)(ucCRCHi ^ aucCRCHi[iIndex]);
                ucCRCHi = aucCRCLo[iIndex];
            }

            var tmpArr = BitConverter.GetBytes((ucCRCHi << 8 | ucCRCLo));
            var bytes = new byte[] { tmpArr[0], tmpArr[1] };
            return bytes;

        }

        public static byte[] CRC16ForRFID(byte[] datas, int len)
        {
            uint i, j;
            uint crc16 = 0xffff;
            for (i = 0; i < len; i++)
            {
                crc16 ^= datas[i];
                for (j = 0; j < 8; j++)
                {
                    if ((crc16 & 0x01) == 1)
                    {
                        //标准crc16使用0xA001,RFID里使用0x8408
                        //crc16 = (crc16 >> 1) ^ 0xA001;
                        crc16 = (crc16 >> 1) ^ 0x8408;
                    }
                    else
                    {
                        crc16 = crc16 >> 1;
                    }
                }
            }
            var bs = BitConverter.GetBytes(crc16);
            return new byte[] { bs[0], bs[1] };
        }

        public static byte[] Crc16(byte[] datas, int length)
        {
            uint i, j;
            uint crc16 = 0xffff;
            for (i = 0; i < length; i++)
            {
                crc16 ^= datas[i];
                for (j = 0; j < 8; j++)
                {
                    if ((crc16 & 0x01) == 1)
                    {

                        crc16 = (crc16 >> 1) ^ 0xA001;

                    }
                    else
                    {
                        crc16 = crc16 >> 1;
                    }
                }
            }
            var bs = BitConverter.GetBytes(crc16);
            return new byte[] { bs[0], bs[1] };
        }

        public static byte[] ParserHexStr(string str)
        {
            string cmdText = str;
            var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim();
            if (string.IsNullOrWhiteSpace(cmd))
            {
                throw new Exception("空字符串!");
            }
            if ((cmd.Length % 2) != 0)
            {
                throw new Exception("命令字符窜长度必须是2的倍数!");
            }

            var cmdBytes = new byte[cmd.Length / 2];
            for (int i = 0; i < cmd.Length; i = i + 2)
            {
                cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
            }
            return cmdBytes;
        }
    }
    #endregion
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.Net;

namespace ZNJM2.Win
{
    public partial class Form3 : Form
    {

        private bool Enable = false;
        public Form3()
        {
            InitializeComponent();
        }
        public SerialPort COMPort { get; private set; }

        private void EnsureCOMPortOpen()
        {
            if (COMPort == null)
            {
                //配置COMPort
                COMPort = new SerialPort("COM2", 57600, Parity.None, 8, StopBits.One);
                COMPort.Encoding = Encoding.ASCII;
                COMPort.ReadTimeout = 1000;
                COMPort.WriteTimeout = 500;
                COMPort.ReadBufferSize = 512;
                COMPort.WriteBufferSize = 512;

                //COMPort.DtrEnable = true;
            }
            if (!COMPort.IsOpen)
            {
                COMPort.Open();
            }
            Thread.Sleep(100);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Enable = true;

            ThreadPool.QueueUserWorkItem(o =>
            {
                Do();
            }, null);
            button1.Enabled = false;
            button2.Enabled = true;
        }
        public void Do()
        {
            try
            {

                EnsureCOMPortOpen();
                Console.WriteLine("串口打开!");
                byte[] buffer = new byte[COMPort.ReadBufferSize];
                List<byte> myBuff=new List<byte>();

                //D7-A3-88-40 4.27
                //00 00 01 ab

                var cmds = new List<CommandBase>();
                //cmds.Add(new VoltageQuery(01));
                //cmds.Add(new ElectricCurrent(01));
                //cmds.Add(new ElectricEnergy(01));
                //cmds.Add(new ElectricFrequency(01));
                //cmds.Add(new RFIDQueryTID(00));
                //cmds.Add(new RFIDQueryEPC(00));
                //cmds.Add(new RFIDSetPower(00, 5));
                //cmds.Add(new RFIDQueryTopOne(00));
               // cmds.Add(new RFIDGetReaderInfo(00));

                string strV = "张三李四网无123456789abc";
                var writeBytes = new List<byte>();
                writeBytes.AddRange(BitConverter.GetBytes(DateTime.Now.Ticks));
                writeBytes.AddRange(Encoding.UTF8.GetBytes(strV));
                var readWords = 0;
                if ((writeBytes.Count % 2) == 0)
                {
                    readWords = writeBytes.Count / 2;
                }
                else
                {
                    readWords = (writeBytes.Count / 2) + 1;
                    writeBytes.Add(0x00);
                }
                Console.WriteLine(BitConverter.ToString(writeBytes.ToArray()));

                cmds.Add(new RFIDWriteUserArea(00, CRCUtil.ParserHexStr("E20040807212025312409A77"), 00, writeBytes.ToArray()));
                cmds.Add(new RFIDReadUserArea(00, "E20040807212025312409A77", 00, (byte)readWords));
                //cmds.Add(new RFIDReadUserArea(00, "E20040807212023812309C8B", 00, 1));
                while (Enable)
                {
                    foreach (var cmd in cmds)
                    {
                        Console.WriteLine("==========================");
                        Console.WriteLine(cmd.Name);

                        COMPort.Write(cmd.CmdBytes.ToArray(), 0, cmd.CmdBytes.Count);
                        Thread.Sleep(100 * 3);

                        int len = COMPort.Read(buffer, 0, buffer.Length);

                        byte[] tempArr = new byte[len];
                        Array.Copy(buffer, tempArr, len);
                        cmd.ReturnBytes = new List<byte>(tempArr);

                        Console.WriteLine("RAW:" +BitConverter.ToString(tempArr));

                        if (cmd.ParserReturn())
                        {
                            #region
                            if (cmd is RFIDReadUserArea)
                            {
                                var t = (RFIDReadUserArea)cmd;
                                Console.WriteLine("ReadData:" +t.Result);

                                var dt=new DateTime( BitConverter.ToInt64(t.ResultBytes.ToArray(), 0));
                                Console.WriteLine(dt.ToString());
                                Console.WriteLine("UTF-8:" + Encoding.UTF8.GetString(t.ResultBytes.ToArray(), 8,t.ResultBytes.Count -8 ));
                            }
                            if (cmd is RFIDWriteUserArea)
                            {
                                Console.WriteLine("ReadData:" + cmd.Result);
                            }
                            #endregion
                            #region QueryTID
                            if (cmd is RFIDQueryTID)
                            {

                                Console.WriteLine("LblNum:" + ((RFIDQueryTID)cmd).LblNum);
                                foreach (var lbl in ((RFIDQueryTID)cmd).LblList)
                                {
                                    Console.WriteLine(lbl);
                                }
                            }
                            #endregion
                            #region RFIDQueryEPC
                            if (cmd is RFIDQueryEPC)
                            {

                                Console.WriteLine("LblNum:" + ((RFIDQueryEPC)cmd).LblNum);

                                foreach (var lbl in ((RFIDQueryEPC)cmd).LblList)
                                {

                                    Console.WriteLine(lbl);
                                }
                            }
                            #endregion
                            #region RFIDGetReaderInfo
                            if (cmd is RFIDGetReaderInfo)
                            {

                                Console.WriteLine("Power:" + ((RFIDGetReaderInfo)cmd).Power);
                                Console.WriteLine("CmdDelay:" + ((RFIDGetReaderInfo)cmd).CmdDelay);
                            }
                            #endregion
                            if (cmd is RFIDQueryTopOne)
                            {
                                Console.WriteLine("LblNum:" + ((RFIDQueryTopOne)cmd).LblNum);
                                foreach (var lbl in ((RFIDQueryTopOne)cmd).LblList)
                                {
                                    Console.WriteLine(lbl);
                                }
                            }
                        }
                        else
                        {
                            Console.WriteLine(cmd.Err.ToString());
                           // COMPort.Read(buffer, 0, buffer.Length);
                        }

                    }
                    //using (WebClient wc = new WebClient())
                    //{
                    //    var url = string.Format(@"http://192.168.9.6:7896/Default.aspx?rnd={0}&m=U&V={1}&I={2}&E={3}",
                    //        DateTime.Now.Ticks,
                    //        cmds.OfType<VoltageQuery>().FirstOrDefault().Result,
                    //        cmds.OfType<ElectricCurrent>().FirstOrDefault().Result,
                    //        cmds.OfType<ElectricEnergy>().FirstOrDefault().Result
                    //        );
                    //    Console.WriteLine(url);
                    //    wc.DownloadString(url);
                    //    wc.Dispose();
                    //}
                    Thread.Sleep(1000 * 2);

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);

            }
            finally
            {
                if (COMPort != null && COMPort.IsOpen)
                {
                    COMPort.Close();
                }
                if (Enable)
                {
                    ThreadPool.QueueUserWorkItem(o =>
                    {
                        Do();
                    }, null);
                }
                Console.WriteLine("结束!");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Enable = false;
            button1.Enabled = true;
            button2.Enabled = false;
        }
    }
}

时间: 2024-10-09 20:45:11

一组RS485设备操作命令的相关文章

register_chrdev_region/alloc_chrdev_region和cdev注册字符设备驱动

内核提供了三个函数来注册一组字符设备编号,这三个函数分别是 register_chrdev_region().alloc_chrdev_region() 和 register_chrdev(). (1)register_chrdev  比较老的内核注册的形式   早期的驱动(2)register_chrdev_region/alloc_chrdev_region + cdev  新的驱动形式 (3)register_chrdev()函数是老版本里面的设备号注册函数,可以实现静态和动态注册两种方法

分布式块设备drbd基础概念及、原理及其主从模式配置

一.drbd基础 1.drbd基础概念 drbd(全称为Distributed Replicated Block Device,简称drbd)分布式块设备复制,说白了就是在不同节点上两个相同大小的设备块级别之间的数据同步镜像.drbd是由内核模块和相关脚本而构成,用以构建高可用性的集群.在高可用(HA)解决方案中使用drbd的功能,可以代替使用一个共享盘阵存储设备.因为数据同时存在于本地主机和远程主机上,在遇到需要切换的时候,远程主机只需要使用它上面的那份备份数据,就可以继续提供服务了. 2.d

字符设备 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev() (转载)

1. 字符设备结构体 内核中所有已分配的字符设备编号都记录在一个名为 chrdevs 散列表里.该散列表中的每一个元素是一个 char_device_struct 结构,它的定义如下: static struct char_device_struct {        struct char_device_struct *next;    // 指向散列冲突链表中的下一个元素的指针        unsigned int major;                 // 主设备号       

Linux字符设备驱动框架

字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l /dev的时候,就能看到大量的设备文件,c就是字符设备,b就是块设备,网络设备没有对应的设备文件.编写一个外部模块的字符设备驱动,除了要实现编写一个模块所需要的代码之外,还需要编写作为一个字符设备的代码. 驱动模型 Linux一切皆文件,那么作为一个设备文件,它的操作方法接口封装在struct fi

字符设备 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()

1. 字符设备结构体 内核中所有已分配的字符设备编号都记录在一个名为 chrdevs 散列表里.该散列表中的每一个元素是一个 char_device_struct 结构,它的定义如下: static struct char_device_struct {       struct char_device_struct *next;    // 指向散列冲突链表中的下一个元素的指针       unsigned int major;                 // 主设备号       un

什么是操作系统?

我们应知道,在一个计算机系统中,硬件与软件资源可分为:处理器.存储器.I/O设备和信息(数据和程序)四类.而OS它是一个计算机系统资源的管理者,并实现了对计算机资源的抽象,连接了用户与计算机硬件系统,作为用户与计算机硬件系统之间的接口(软件接口). 一.             关于OS对计算机系统资源的管理: OS的主要功能就是: (1).处理机管理:分配和控制处理机 (2).存储器管理:内存分配与回收 (3).I/O设备管理:I/O设备分配与操作 (4).文件管理:文件的存取.共享和保护 注

OS概论1

1.设计现代OS的主要目标是什么? 在计算机上配置操作系统,其主要目标是:方便性,有效性,可扩充性,开放性. 一个没有OS的操作系统,就必须用机器语言书写程序,如果在计算机上配置了OS,系统便可以使用编译命令将用户使用高级语言书写的程序翻译成机器代码,或者直接通过OS所 提供的各种命令操作计算机系统,极大地方便了用户. 在未配置OS的计算机系统中,处理机,I/O等设备经常处于空闲状态,各种资源无法得到充分的利用,而OS可以通过合理地组织计算机的工作流程,加速程序的运行,缩短程序的 运行周期,从而

【操作系统常考知识总结】-转

1.进程是并发过程中程序的执行过程 2.进程的特征:结构特征动态性并发性独立性异步性 3.临界区指在每个进程中访问临界资源的那段代码 4,现在操作系统中申请资源的基本单位是进程,在CPU得到执行的基本单位是线程,进程是由程序段.数据段.PCB组成的 5,对临界资源应采取互斥访问方式来实现共享 6,P.V操作是一种低级进程通信原语 7,对于记录性信号量,在执行一次P操作时,信号量的值应当减1,当其值为小于0时进程应阻塞:在执行V操作时,信号量的值应当加1:当其值小于等于0时,应唤醒阻塞队列中的进程

操作系统常考知识点总结

1.进程管理 1.进程是并发过程中程序的执行过程 2.进程的特征:结构特征动态性并发性独立性异步性 3.临界区指在每个进程中访问临界资源的那段代码 4,现在操作系统中申请资源的基本单位是进程,在CPU得到执行的基本单位是线程,进程是由程序段.数据段.PCB组成的 5,对临界资源应采取互斥访问方式来实现共享 6,P.V操作是一种低级进程通信原语 7,对于记录性信号量,在执行一次P操作时,信号量的值应当减1,当其值为小于0时进程应阻塞:在执行V操作时,信号量的值应当加1:当其值小于等于0时,应唤醒阻