C#串口=>发送和接收

2023-05-16

作用:串口发送命令后,等待下位机应答帧

代码:一旦读取到数据就立即返回给上层。

 public string TXandRX(byte[] buffer, string data)//发送
        {//RS485专用
            start = false;// 状态
            try
            {
                serialPort.Write(buffer, 0, buffer.Length);//串口发送
                #region 计时
                //====现在时间======================================
                StringBuilder ATtime = new StringBuilder(String.Format("{0,9}",
                    DateTime.Now.Second.ToString() + "s"
                    + DateTime.Now.Millisecond.ToString() + "ms:"));  //固定长度9 右对齐
                #endregion
                //ui显示发送的命令
                //wt_发送数据(str_发送后记时.Append(data).ToString());//ui显示发送的命令
                if (Help_ModBus.Wt_set != null)
                {// 数据包,文本
                    //Help_ModBus.Wt_set(buffer , data);
                    Help_ModBus.Wt_set(buffer, ATtime.ToString()+data);
                }

                //=======3 收尾===========================================
                #region 等待RX
                DateTime startTime = DateTime.Now;//记录开始时间
                do//应答帧等待
                {
                    if (start)
                    {
                        return get_RXstr;
                    }
                    if ((DateTime.Now - startTime).TotalMilliseconds > ReadTimeout)// 超时 1.5s
                    {
                        break;// 已经超时
                    }
                } while (true);
                #endregion
                return null;
            }
            catch (Exception ex) { throw ex; }//显示错误
        }

由接收事件去激活标志位:

 // 串口接收事件
        private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {   //throw new NotImplementedException();

            //===进入中断=========================================================================
            #region 空数据
            if (serialPort.BytesToRead == 0)//空
            {
                get_中断次数 += 1;
                if (get_中断次数 > get_中断MAX次数) get_中断MAX次数 = get_中断次数;
                //return;//空数据
                throw new NotImplementedException("空包");
            }
            #endregion
            get_中断次数 = 0;
            //====现在时间===================================59秒999ms:  长度9
            #region 标记时间
            StringBuilder str_接收事件记时 = new
             StringBuilder(string.Format("{0,9}",
               DateTime.Now.Second.ToString() + "s"
             + DateTime.Now.Millisecond.ToString() + "ms:"));  //固定长度9 右对齐
            AT_Time = str_接收事件记时.ToString();
            #endregion

            #region 加载数据
            byte[] buffer = new byte[serialPort.BytesToRead];//匹配的数据包
            serialPort.Read(buffer, 0, serialPort.BytesToRead);//加载数据

            //====解码显示=====================================
            string data = helpstring.BytesToHexStrings(buffer);
            #endregion
            get_RXstr=data;
            start = true;
            if (Help_ModBus.Wt_get != null)//被绑定
            {// 数据表, 时间
                Help_ModBus.Wt_get(buffer, AT_Time+data);  //↑  public event WT_串口接收事件 Wt_串口接收事件;//委托
            }
        }

整个文件参考:

using Models;//参数模型
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace help
{
    /// <summary>
    /// Help_SerialPort comx = new Help_SerialPort();//串口对象
    /// </summary>
    public class Help_SerialPort : SerialPort, Help_RTX
    {
        #region 全局
        //====1定义委托============================================
        public delegate void WT_GET_Data(byte[] butes, string data);//ui显示发送命令
        public delegate void WT_SET_Data(byte[] butes, string data);//其他能实现发送功能的对象


        #endregion
        #region 字段
        private SerialPort serialPort = null;//using System.IO.Ports;
        Help_String helpstring = new Help_String();//文本编辑
        int get_中断次数 = 0;
        static int get_中断MAX次数;
        bool start;
        string get_RXstr;

        #endregion
        #region 属性
        static public WT_GET_Data Wt_get;//get至ui层  ↑
        static public WT_SET_Data Wt_set;//ui至 终端     ↓
        public SerialPort serialport { get => serialPort; set => serialPort = value; }
        //================================================================
        public int ReadTimeout { get => serialPort.ReadTimeout; set => serialPort.ReadTimeout = value; }

        public int rx单帧字节
        {//   ReceivedBytesThreshold = 5;//过滤合并,帧最小5字节
            get { return serialPort.ReceivedBytesThreshold; }
            set { serialPort.ReceivedBytesThreshold = value; }
        }
        public string AT_Time { get; private set; }// 标记时间
        #region get参数
        //===get===96n81===============================================
        public bool isopen { get { return serialPort.IsOpen; } }
        public string[] get可用串口 { get { return SerialPort.GetPortNames(); } }
        /// <summary>
        ///  "110","300","600","1200","2400","4800","9600","14400","28800","19200",
        ///  "38400","56000","57600","115200","230400","460800","921600"
        /// </summary>
        public string[] get波特率 => new string[]{
                "110","300","600","1200","2400","4800","9600","14400","28800","19200",
                "38400","56000","57600","115200","230400","460800","921600"};
        /// <summary>
        /// None   Odd  Even  Mark  Space ,
        /// None 不发生奇偶校验检查。
        /// Odd  设置奇偶校验位,使位数等于奇数。
        /// Even 设置奇偶校验位,使位数等于偶数。
        /// Mark 将奇偶校验位保留为 1。
        /// Space将奇偶校验位保留为 0。
        /// </summary>
        public string[] get校验位 { get { return Enum.GetNames(typeof(Parity)); } } //  校验位
        /// <summary>
        /// "5", "6", "7", "8"
        ///  数据位的值 5至8。默认8
        /// </summary>
        public string[] get数据位 { get { return new string[] { "5", "6", "7", "8" }; } }

        /// <summary>
        /// None One  Two  OnePointFive 。
        /// 0  1  2  1.5
        /// </summary>
        public string[] get停止位 { get { return Enum.GetNames(typeof(StopBits)); } }  //
        #endregion
        #region set参数
        //===set===96n81==============================================
        /// <summary>
        /// serialPort1.PortName = name;
        /// </summary>
        /// <param name="name"></param>
        public void set串口名(string name)
        {
            try
            {
                serialPort.PortName = name;// 设置串口名
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
        }
        /// <summary>
        /// serialPort1.BaudRate = Convert.ToInt32(BaudRate, 10);//十进制的
        /// </summary>
        /// <param name="BaudRate"></param>
        public void set波特率(string BaudRate)
        {
            try
            {
                serialPort.BaudRate = Convert.ToInt32(BaudRate, 10);//十进制的
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
        }
        /// <summary>
        /// serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), Parity, true);//true 为忽略大小写
        /// </summary>
        /// <param name="Parity"></param>
        public void set校验位(string Parity)
        {
            try
            {
                serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), Parity, true);//true 为忽略大小写
                                                                                     //return Enum.GetNames(typeof(Parity));
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
        }
        /// <summary>
        /// serialPort1.DataBits = Convert.ToInt32(DataBits, 10);//十进制的
        /// </summary>
        /// <param name="DataBits"></param>
        public void set数据位(string DataBits)
        {
            try
            {
                serialPort.DataBits = Convert.ToInt32(DataBits, 10);//十进制的
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
        }
        /// <summary>
        /// serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), StopBits, true);
        /// "None"  "One"  "Two"  "OnePointFive"
        /// </summary>
        /// <param name="StopBits">StopBits.</param>
        public void set停止位(string StopBits)
        {
            try
            {
                serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), StopBits, true);
                //return Enum.GetNames(typeof(StopBits));
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
        }
        #endregion

        #endregion

        #region 构造
        public Help_SerialPort()
        {
            serialPort = new SerialPort();//实例对象
            serialPort.DataReceived += SerialPort1_DataReceived;//绑定一个委托    接收事件
            ReadTimeout = 200;// 等待RX 200ms
            rx单帧字节 = 5;
        }
        // 串口接收事件
        private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {   //throw new NotImplementedException();

            //===进入中断=========================================================================
            #region 空数据
            if (serialPort.BytesToRead == 0)//空
            {
                get_中断次数 += 1;
                if (get_中断次数 > get_中断MAX次数) get_中断MAX次数 = get_中断次数;
                //return;//空数据
                throw new NotImplementedException("空包");
            }
            #endregion
            get_中断次数 = 0;
            //====现在时间===================================59秒999ms:  长度9
            #region 标记时间
            StringBuilder str_接收事件记时 = new
             StringBuilder(string.Format("{0,9}",
               DateTime.Now.Second.ToString() + "s"
             + DateTime.Now.Millisecond.ToString() + "ms:"));  //固定长度9 右对齐
            AT_Time = str_接收事件记时.ToString();
            #endregion

            #region 加载数据
            byte[] buffer = new byte[serialPort.BytesToRead];//匹配的数据包
            serialPort.Read(buffer, 0, serialPort.BytesToRead);//加载数据

            //====解码显示=====================================
            string data = helpstring.BytesToHexStrings(buffer);
            #endregion
            get_RXstr=data;
            start = true;
            if (Help_ModBus.Wt_get != null)//被绑定
            {// 数据表, 时间
                Help_ModBus.Wt_get(buffer, AT_Time+data);  //↑  public event WT_串口接收事件 Wt_串口接收事件;//委托
            }
        }

        public Help_SerialPort(SerialPort comx)//类是引用类型
        {
            serialPort = comx;
            serialPort.DataReceived += SerialPort1_DataReceived;//绑定一个委托:接收事件
        }
        #endregion

        #region 方法
        
        #region 连接
        public void open串口()
        {
            try
            {
                serialPort.Open();
            }
            //catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
            catch (Exception ex) { throw ex; }
        }
        #endregion

        #region 断开
        public void close串口()
        { serialPort.Close(); }
        #endregion

        #region 发送
        /// <summary>
        /// Modbus帧专用发送
        /// </summary>
        /// <param name="buffer">发送的数据</param>
        /// <param name="data">wt_ui参考</param>
        public string TXandRX(byte[] buffer, string data)//发送
        {//RS485专用
            start = false;// 状态
            try
            {
                serialPort.Write(buffer, 0, buffer.Length);//串口发送
                #region 计时
                //====现在时间======================================
                StringBuilder ATtime = new StringBuilder(String.Format("{0,9}",
                    DateTime.Now.Second.ToString() + "s"
                    + DateTime.Now.Millisecond.ToString() + "ms:"));  //固定长度9 右对齐
                #endregion
                //ui显示发送的命令
                //wt_发送数据(str_发送后记时.Append(data).ToString());//ui显示发送的命令
                if (Help_ModBus.Wt_set != null)
                {// 数据包,文本
                    //Help_ModBus.Wt_set(buffer , data);
                    Help_ModBus.Wt_set(buffer, ATtime.ToString()+data);
                }

                //=======3 收尾===========================================
                #region 等待RX
                DateTime startTime = DateTime.Now;//记录开始时间
                do//应答帧等待
                {
                    if (start)
                    {
                        return get_RXstr;
                    }
                    if ((DateTime.Now - startTime).TotalMilliseconds > ReadTimeout)// 超时 1.5s
                    {
                        break;// 已经超时
                    }
                } while (true);
                #endregion
                return null;
            }
            catch (Exception ex) { throw ex; }//显示错误
        }

        public void TX_发送数据(byte[] data)//发送
        {
            try
            {
                serialPort.Write(data, 0, data.Length);
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
        }
        public void TX_发送数据(string data)//发送
        {
            try
            {
                byte[] buffer = Encoding.Default.GetBytes(data);//以计算机的编码发送
                serialPort.Write(buffer, 0, buffer.Length);//  开始发送
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }//显示错误
        }

        #endregion

        #endregion

        #region old
        //public override Socket connect连接(string t1, string t2)
        //{
        //    //base.connect连接(t1, t2);
        //    open串口();
        //    return null;
        //}
        //        public override string TX发送(string stringcmd)
        //        {
        //            //=======1 准备===========================================
        //            #region 帧头延时
        //            delay(delay_帧头等待);
        //            #endregion
        //            //=======2 加载===========================================
        //            //rx_str = null;//清空接收包
        //            byte[] buffer = TxCMD(stringcmd);//准备报文  //去除空白   StringsToHexBytes

        //            TXrs485_发送命令(buffer, stringcmd);// TX 发送数据
        //            #region 帧尾延时10ms
        //            //帧间隔3.5字符:   1除以波特率,乘以38.5  
        //            //delay((int)(uint)(1000.0 / comx.serialPort.BaudRate * 38.5));//每帧间隔3.5字符
        //            delay(ReadTimeout);//10ms 伺服手册规定

        //            #endregion

        //            //=======3 收尾===========================================
        //            #region 等待方法
        //            DateTime startTime = DateTime.Now;//记录开始时间
        //            do//应答帧等待
        //            {
        //                if (get_RXstr != null)
        //                {
        //                    return get_RXstr;
        //                }

        //                if ((DateTime.Now - startTime).TotalMilliseconds > ReadTimeout)// 超时 1.5s
        //                {
        //                    break;// 已经超时
        //                }
        //            } while (true);

        //            #endregion

        //#if (Debug3S)//数据帧节拍调试
        //            Thread.Sleep(3000);
        //#endif

        //            return null;
        //        }
        //public override void close关闭()
        //{
        //    //base.close关闭();
        //    close串口();
        //}
        #endregion

        #region 委托
        //呼叫委托
        void wt_发送数据(string data)
        {
#if (WT收发显示)
            //====3呼叫委托===========================//发送事件
            //if (wt_串口发送事件 != null)
            //{
            wt_串口发送事件(data);//上层ui显示
            //}
            //else
            //{// null 空对象报警
            //    throw new NotImplementedException();
            //}
#endif
        }

        //呼叫委托
        void wt_接收数据(string data)
        {
#if (WT收发显示)
            //====3呼叫委托===========================//接收事件
            //if (wt_串口接收事件 != null)
            //{
            wt_串口接收事件(data);//上层ui显示
            //}
            //else
            //{// null 空对象报警
            //    throw new NotImplementedException();
            //}
#endif
        }



        #endregion

        #region 文本处理
        #region 字符串转等效数组
        /// <summary>
        /// 字符串转等效数组
        /// </summary>
        /// <param name="data">原料</param>
        /// <returns>成品</returns>
        public byte[] StringsToHexBytes(string data)//change转换,string等效的byte[]
        {
            //清除所有空格
            string str = data.Replace(" ", "");
            //若字符个数为奇数,补一个0
            str += str.Length % 2 != 0 ? "0" : "";
            byte[] bytes = new byte[str.Length / 2];//用于返回结果
            for (int i = 0, c = bytes.Length; i < c; i++)//获取bytes值
            {
                bytes[i] = Convert.ToByte(str.Substring(i * 2, 2), 16);
            }
            return bytes;
        }
        #endregion
        #region 数组转等效字符串
        /// <summary>
        ///  数组转等效字符串
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public string BytesToHexStrings(byte[] data)//change转换 , byte[ ]等效的string
        {
            string str = string.Empty;
            for (int i = 0; i < data.Length; i++)
            {
                str += data[i].ToString("X2");
            }
            return str;
        }
        #endregion
        #region 数组计算CRC
        /// <summary>
        /// 数组计算CRC
        /// </summary>
        /// <param name="bytes">原料</param>
        /// <param name="b">false小端</param>
        /// <returns></returns>
        public byte[] getCRC16(byte[] bytes, bool b)//数组,端向,默认flase小端
        {
            int len = bytes.Length;
            if (len > 0)
            {
                ushort crc = 0xFFFF;

                for (int i = 0; i < len; i++)
                {
                    crc = (ushort)(crc ^ (bytes[i]));
                    for (int j = 0; j < 8; j++)
                    {
                        crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
                    }
                }
                byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
                byte lo = (byte)(crc & 0x00FF);         //低位置
                if (b)//端向
                {
                    return new byte[] { hi, lo };//大端
                }
                else
                {//默认小端
                    return new byte[] { lo, hi, };//小端
                }
            }
            return new byte[] { 0, 0 };
        }
        /// <summary>
        /// 字符串计算CRC
        /// </summary>
        /// <param name="cmd">字符串</param>
        /// <returns>CRC</returns>
        public string getCRC16(string cmd)
        {
            return BytesToHexStrings(getCRC16(StringsToHexBytes(cmd), false));//CRC
        }
        #endregion
        #region StringCMD
        /// <summary>
        /// 完整的命令
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public string getString帧CRC(string data)//转换   带CRC的命令(用于ui查看)
        {
            //return data + BytesToHexStrings(getCRC16(StringsToHexBytes(data), false));//命令+CRC
            return data + getCRC16(data); // 命令 + CRC
        }
        #endregion
        #region TxCMD
        /// <summary>
        /// 发送的数据帧
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] TxCMD(string data)//change转换   串口发送命令
        {
            data.Replace(" ", "");//去除空白
            byte[] buffer = StringsToHexBytes(data);
            return buffer;//TX的
        }
        #endregion


        #endregion

        #region WT_委托
        #endregion

        #region 接口
        public int connect<T>(T a, T b)
        {
            try
            {
                serialPort.PortName = "COM3";
                serialPort.BaudRate = 9600;
                serialPort.Parity = Parity.None;
                serialPort.StopBits = StopBits.One;
                serialPort.DataBits = 8;

                serialPort.Open();
                return 0;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public object TXs(string cmd)
        {
            byte[] buffer = TxCMD(cmd);//准备报文  //去除空白   StringsToHexBytes
            return  TXandRX(buffer, cmd);
           
        }

        public object RXs()
        {
            throw new NotImplementedException();
        }

        public int Close()
        {
            serialPort.Close();
            return 0;
        }


        #endregion
    }

    #region 串口日志
    public class RZ_日志
    {
        #region 字段
        //public DateTime sj_数据时间;
        public int ff_数据时间;//当前时间的   毫秒
        StringBuilder rz_日志生日;
        public StringBuilder rz_日志;

        #endregion
        #region 属性
        public int fz负载 { get; set; }


        public string ff_最后数据内容 { get; set; }
        public int 错误帧数 { get; set; }
        #endregion
        #region 构造
        public RZ_日志()
        {
            //rz_日志生日 = DateTime.Now.Millisecond;//当前时间   毫秒
            rz_日志生日 = new
              StringBuilder(string.Format("{0,9}",
              DateTime.Now.Hour.ToString() + "时"
              + DateTime.Now.Minute.ToString() + "分"
              + DateTime.Now.Second.ToString() + "秒"
              + DateTime.Now.Millisecond.ToString() + "ms:"));  //固定长度9 右对齐
        }
        #endregion
        #region 方法

        public void append(string data)
        {
            StringBuilder sj时间 = new
             StringBuilder(string.Format("{0,9}",
               DateTime.Now.Second.ToString() + "秒"
             + DateTime.Now.Millisecond.ToString() + "ms:"));  //固定长度9 右对齐
            sj时间.Append(data);
            rz_日志.Append(sj时间 + "\r\n");
        }

        public string show()
        {
            return rz_日志.ToString();
        }

        public void clear()
        {
            rz_日志.Clear();
        }

        public string show日志生日()
        {
            return rz_日志生日.ToString();
        }







        #endregion
        #region 委托

        #endregion




    }

    #endregion

    //    class Help_BaseData //全局
    //    {
    //#if (STATIC)
    //        public static SerialPort COMX = new SerialPort();// 字段,全局变量,串口
    //        //public static event WT_串口发送事件 Wt_串口发送事件;
    //        //public static event WT_串口接收事件 Wt_串口接收事件;//委托
    //        public static WT_串口发送事件 Wt_串口发送事件;
    //        public static WT_串口接收事件 Wt_串口接收事件;//委托
    //#else
    //        public SerialPort COMX = new SerialPort();// 字段,全局变量,串口
    //        public WT_串口发送事件 Wt_串口发送事件;
    //        public WT_串口接收事件 Wt_串口接收事件;//委托
    //#endif

    //    }



}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#串口=>发送和接收 的相关文章

随机推荐

  • 24从零开始学Java之如何正确地使用一维数组

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套开源项目资料 https github com SunLtd Lear
  • 25从零开始学Java之数组扩容与数组拷贝的实现过程与原理分析

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套开源项目资料 https github com SunLtd Lear
  • 26从零开始学Java之如何对数组进行排序与二分查找?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套开源项目资料 https github com SunLtd Lear
  • 27从零开始学Java之详解复杂的二维数组与多维数组

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 在前几篇文章中 xff0c 壹哥给大家介绍了Java里的一维数组 x
  • 28从零开始学Java之面向对象和面向过程到底有哪些区别?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 壹哥相信 xff0c 经过你对前面文章中技术点的学习 xff0c 现
  • 29从零开始学Java之如何正确创建Java里的类?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 在上一篇文章中 xff0c 壹哥给大家介绍了面向对象和面向过程的概念
  • 全面图解路由器接口及连接(图)

    路由器所在的网络位置比较复杂 xff0c 既可是内部子网边缘 xff0c 也可位于内 外部网络边缘 同时为了实现强大的适用性 xff0c 它需要连接各种网络 xff0c 这样 xff0c 它的接口也就必须多种多样 对于这些 xff0c 不要
  • blktrace,blkparse,btt工具的制作和使用

    1 软件包交叉编译安装 1 1 blktrace源码下载路径 https git kernel dk cgit blktrace 1 2 源码安装 tar zxvf blktrace 1 2 0 tar gz cd blktrace 1 2
  • cartographer之ceres编译

    1 首先下载ceres xff1b 2 进入ceres目录 xff1b 3 mkdir build amp amp cd build 4 cmake DEIGENSPARSE 5 make 6 sudo make install
  • 一个空文件夹和空文件占多少空间?

    用于显示文件夹和文件大小的命令 span class token function du span h 显示目前在 Linux 系统上的文件系统磁盘使用情况统计 span class token function df span i 一 问
  • 虚拟地址如何访问到物理地址

    环境 xff1a 32bit CPU 一 通过二级页表映射的方式访问物理地址 1 取一级页表的基地址Abase1 2 取虚拟地址的前12bit 31 20 地址O1 3 计算得到新地址Apgd 61 Abase1 amp 0xFFFFF00
  • 添加自定义的section

    一 基本知识点 编译出来的程序 xff08 o so exe ko等等 xff09 都是以elf格式进行排列保存的 elf文件分析情况 xff1a https blog csdn net edonlii article details 87
  • 如何打印堆栈

    一 打印堆栈可以方便问题定位 xff0c 找到具体的函数调用流程 二 打印堆栈的方法 2 1 用户态 include lt stdio h gt include lt stdlib h gt include lt stddef h gt i
  • 内存飞踩问题的几点思考

    1 程序编译 xff0c 链接后生成二进制可执行程序 二进制可执行文件以elf格式实现排列 可以通过readelf S xxxx查看具体section的划分 xff0c 粗略划分如下图所示 在这些section中 xff0c 代码段是只读的
  • CFS调度算法

    1 CFS调度算法 xff0c 顾名思义就是完全公平调度策略 比方说 xff0c 调度延迟时间是10ms xff0c 存在两个进程A和B xff0c 那么两个进程分别占用CPU的时间是5ms 然而 xff0c 阶级总是存在的 xff0c 毕
  • ARM处理器的异常模式

    1 ARM处理器有各种异常模式 xff0c 用于应对ARM出现的不同状态 出现异常时 xff0c 会随即进入相关的异常向量 xff0c 同时CPSR的寄存器也会设置成具体的模式 例 xff1a 当出现中断时 xff0c 不管是哪种中断 xf
  • 内核态和用户态相关的内存泄漏

    应用程序通过系统调用进入内核态代码 假如内核态代码存在内存泄漏 xff0c 此内存泄漏属于内核态还是用户态 xff1f 查看内核态和用户态的统计信息
  • 为什么在telnet登入界面下没有日志输出?

    1 每个进程的输入输出导向目标都可以在进程号下的fd软链接上查看 如 569号进程的输出目标是 dev console xff0c 即串口 其中0是标准输入 xff0c 1是标准输出 xff0c 2是标准错误输出 2 因此我们只需要查看te
  • 【无标题】

    1 将虚拟地址传入到内核态 xff0c 借助内核态中mm struct结构体的pgd页表基地址成员 xff0c 经过查页表的方式最终获取到物理地址 这种方法虽然很直观 xff0c 但是一会内核态 xff0c 一会用户态 xff0c 操作起来
  • C#串口=>发送和接收

    作用 xff1a 串口发送命令后 xff0c 等待下位机应答帧 代码 xff1a 一旦读取到数据就立即返回给上层 public string TXandRX byte buffer string data 发送 RS485专用 start