|
编辑1:修改错别字
数据存在1G的flash中,每个subsector是4K字节,包含292条14字节的log数据,每个log数据头部是4字节的时间码(兼做识别用)
通讯过程如下:
上位机发送 rxlog -1
单片机应答 start:0,total:32768,表示从数据从subsector【0】开始,共用32768个subsector
while(total>0)
{
上位机发送 rxlog xxx(subsector);
单片机应答一个subsector的数据;
total--;
}
subsector数据包格式如下:
[1]: Head: 0xFA 0xF5 0xAA 0x55 [2]:n*14 bytes of Log data pack [3]: Tail: 0xFA 0xF5 0xCC 0x33 [4]:CRC32 of Head+Logs+Tail
log数据的时间码不会出现Head和Tail,如果接收中log数据的时间码是Tail,表示这个sebsector结束
每个subsector数据包,给1秒时间,超时没有完成,就重来
运行中出现crc err,看内存中数据是串口接收数据不完整,丢数据非常严重
程序如下:
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- //MessageBox.Show("Please confirm SW1 is all-off", "Notice!");
- // got all com ports
- btnOpen.Enabled = false;
- string[] portStr = SerialPort.GetPortNames();
- if (portStr.Length == 0)
- {
- MessageBox.Show("No COM port found!", "Error");
- return;
- }
- // com ports exist
- btnOpen.Enabled = true;
- foreach (string s in System.IO.Ports.SerialPort.GetPortNames())
- {
- cbSerial.Items.Add(s);
- }
- cbSerial.SelectedIndex = 0;
- }
- // comport
- private SerialPort rs232Port = new SerialPort();
-
- // got from "rxlog -1"
- private int startSub, totalSubs;
- // thread for rx
- private Thread getlogThread;
- private delegate void UpdateTextBox(string s);
- private UpdateTextBox updateTextBox;
- // rx flag
- private bool rxLogsInprocess = false;
- private bool rxPause = false;
- private int subInprocess;
- private uint currentDate = 0xFFFFFFFF;
- private subPack subpack = new subPack();
- private enum subStatus { ssHead, ssLog, ssTail, ssCrc32, ssOver };
- private subStatus revSt = subStatus.ssHead;
- private int revCnt = 0;
- private Queue<byte> rs232Buf = new Queue<byte>();
- private void info2textbox(string s)
- {
- textBox.AppendText(s + "\r\n");
- textBox.ScrollToCaret();
- }
- private void btnOpen_Click(object sender, EventArgs e)
- {
- if(rs232Port.IsOpen)
- {
- // if comport is receiving logs, stop it first
- rxPause = true;
- if (rxLogsInprocess)
- {
- while (rxLogsInprocess) ;
- }
- rs232Port.DataReceived -= byteReceived;
- btnGetLogs.Enabled = false;
- btnOpen.Text = "Open";
- rs232Port.Close();
- cbSerial.Enabled = true;
- return;
- }
- // clear flags
- rxLogsInprocess = false;
- rxPause = false;
- // init rs232port
- rs232Port.PortName = cbSerial.Text;
- rs232Port.BaudRate = 115200;
- rs232Port.Parity = Parity.None;
- rs232Port.StopBits = StopBits.One;
- rs232Port.DataBits = 8;
- rs232Port.Handshake = Handshake.None;
- rs232Port.RtsEnable = false;
- rs232Port.ReceivedBytesThreshold = 1;
- rs232Port.ReadBufferSize = subPack.SUBPACK_SIZE;
- rs232Port.NewLine = "\r\n";
- rs232Port.ReadTimeout = 1000;
- try
- {
- rs232Port.Open();
- }
- catch(Exception ex)
- {
- MessageBox.Show(ex.Message);
- return;
- }
- // clear buffer
- rs232Port.DiscardInBuffer();
- rs232Port.DiscardOutBuffer();
- btnOpen.Text = "Close";
- cbSerial.Enabled = false;
-
- textBox.Text = "Connecting...";
- // send command "rxlog -1\x0D" to get the log status from module :"Start:0, Total:32767\r\n"
- rs232Port.Write("rxlog -1\x0D");
- try
- {
- string rxLog = rs232Port.ReadLine();
- int s, t;
- s = rxLog.IndexOf("Start:");
- t = rxLog.IndexOf(", Total:");
- if (s != -1 && t != -1)
- {
- startSub = Int32.Parse(rxLog.Substring(s+6, t-(s+6)));
- totalSubs = Int32.Parse(rxLog.Substring(t+8));
- textBox.Text = "Start = " + startSub + ", Total = " + totalSubs+"\r\n";
- }
- else
- {
- throw new TimeoutException();
- }
- }
- catch (TimeoutException)
- {
- textBox.Text = "Connect failed!";
- return;
- }
- // connect successful, ready to get logs
- btnGetLogs.Enabled = true;
- subInprocess = startSub;
- }
- // 接收字节
- private volatile bool byteRecIsBus = false;
- void byteReceived(object sender, SerialDataReceivedEventArgs e)
- {
- while (byteRecIsBus == true) ; // avoid reentrant
- byteRecIsBus = true;
- while (rs232Port.BytesToRead > 0) // data to read
- {
- int n = rs232Port.BytesToRead;
- byte[] buf = new byte[n];
- rs232Port.Read(buf, 0, n); // read buffer
- for (int i = 0; i < n; i++)
- {
- rs232Buf.Enqueue(buf[i]); // to queue
- }
- }
- byteRecIsBus = false;
- }
- // 启动接收
- private void btnGetLogs_Click(object sender, EventArgs e)
- {
- rs232Port.DataReceived += byteReceived; // delegate
- btnGetLogs.Enabled = false; // disable the button
- getlogThread = new Thread(new ThreadStart(getLogAll)); // new thread to rx
- getlogThread.Start();
- updateTextBox = new UpdateTextBox(info2textbox);
- }
- // 接收线程
- private void getLogAll()
- {
- int timeoutCnt = 0;
- int crcErrCnt = 0;
- while (totalSubs > 0)
- {
- // to receive a new subsector, clear the buffer first
- rs232Buf.Clear();
- rs232Port.DiscardInBuffer();
- rs232Port.DiscardOutBuffer();
- // rxlog sub
- rs232Port.Write("rxlog " + subInprocess + "\x0D");
- // receive a sub
- // set timer
- setTimeout(1000);
- // waiting for data
- Thread.Sleep(300);
- try
- {
- // 1: head : 0xFAF5AA55
- byte[] headBuf = new byte[4] { 0, 0, 0, 0 };
- while ((headBuf[0] == 0xFA && headBuf[1] == 0xF5 && headBuf[2] == 0xAA && headBuf[3] == 0x55) == false)
- {
- headBuf[0] = headBuf[1];
- headBuf[1] = headBuf[2];
- headBuf[2] = headBuf[3];
- headBuf[3] = getByte();
- }
- for (int i = 0; i < subPack.HEAD_SIZE; i++)
- {
- subpack.head[i] = headBuf[i];
- }
- // 2&3: log and tail
- // The first 4 Bytes in a Log is timeStamp
- // If the timeStamp is 0xFAF5CC33 or LOG_CNT_MAX of Logs have been received, it means the Tail
- for (int i = 0; i < subPack.LOG_CNT_MAX + 1; i++)
- {
- // check first 4-byte
- int j;
- for (j = 0; j < 4; j++)
- {
- subpack.logsInSub[i].log14b[j] = getByte();
- }
- if ((subpack.logsInSub[i].getTimestamp() == 0xFAF5CC33) || (i == subPack.LOG_CNT_MAX))
- {// tail
- for (j = 0; j < 4; j++)
- {
- subpack.tail[j] = subpack.logsInSub[i].log14b[j];
- }
- subpack.logCnt = i; // how many Logs in this subsector
- // goto crc32
- break;
- }
- // receive other 10 bytes
- for (; j < log.LOG_SIZE; j++)
- {
- subpack.logsInSub[i].log14b[j] = getByte();
- }
- }
- // 4: crc32
- for (int i = 0; i < subPack.CRC32_SIZE; i++)
- {
- subpack.crc32[i] = getByte();
- }
- }
- catch (TimeoutException)
- {
- // timeout error, retry this subsector
- // update textbox
- if(++timeoutCnt==5)
- {
- //??????
- throw new TimeoutException("Timeout 5 times");
- }
- this.BeginInvoke(updateTextBox, "timeout\r\n");
- continue;
- }
- if (subpack.isCrc32Correct() == false)
- {
- // crc32 error, retry this subsector
- if (++crcErrCnt == 5)
- {
- //??????
- throw new TimeoutException("Crc error 5 times");
- }
- this.BeginInvoke(updateTextBox, "crc err\r\n");
- continue;
- }
- // got a sub
- // save to file
- for (int i = 0; i < subpack.logCnt; i++)
- {
- // check date
- uint date = subpack.logsInSub[i].getDate();
- if (currentDate != date)
- {// new date, new file
- currentDate = date;
- }
- else
- {// same date, same file
- }
- }
- // <- a sub is over
- timeoutCnt = 0;
- crcErrCnt = 0;
- this.BeginInvoke(updateTextBox, "Got subsector:" + subInprocess + "\r\n");
- totalSubs--;
- subInprocess++;
- if (subInprocess >= 32768)
- {
- subInprocess = 0;
- }
- }
- // over
- btnGetLogs.Enabled = false;
- // ?????
- }
- // 从队列中取出字节
- byte getByte()
- {
- while(rs232Buf.Count==0)
- {
- if (timeoutMsTick)
- {
- throw new TimeoutException();
- }
- }
- return rs232Buf.Dequeue();
- }
- private void btnBrowse_Click(object sender, EventArgs e)
- {
- System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
- dlg.Description = "Select the directory to save log files";
- if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
- {
- saveToDir.Text = dlg.SelectedPath.ToString();
- }
- }
- private void Form1_FormClosing(object sender, FormClosingEventArgs e)
- {
- if (rs232Port.IsOpen == true)
- {
- rs232Port.Close();
- // close file
- }
- }
-
- // 定时器 for timeout
- private volatile bool timeoutMsTick;
- private void timeoutMs_Tick(object sender, EventArgs e)
- {
- timeoutMsTick = true;
- timeoutMs.Stop();
- }
- private void setTimeout(int ms)
- {
- timeoutMs.Stop();
- timeoutMsTick = false;
- timeoutMs.Interval = ms>0?ms:1;
- timeoutMs.Start();
- }
-
- }
复制代码
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|