中国自动化学会专家咨询工作委员会指定宣传媒体
免费注册 登录 广告服务 | 客服中心
您现在所在的是:

嵌入式系统

抖音 德嘉 泓格论坛 FLIR红外热像论坛
工控论坛首页 嵌入式系统 → 浏览主题: 【STM32 .Net MF开发板学习-26】借道调试口与开发板通信
发表新帖 回复该主题
回帖:1个,阅读:600 [上一页] [1] [下一页]
* 帖子主题:

【STM32 .Net MF开发板学习-26】借道调试口与开发板通信

分享到
884
yefanqiu
文章数:33
年度积分:50
历史总积分:884
注册时间:2004/8/19
发站内信
发表于:2011/1/9 23:24:10
#0楼
目前可以成为.net mf开发板调试口的信道有,串口、usb和网口,一般情况下,一旦具体设定哪个信道,在不更换固件的情况下,是无法动态改变的。
   所谓调试口,就是供windows平台上的vs2008/vs2010调试的信道,当然mfdeploy和我编写的工具yfaccessflash也是通过这个信道和开发板实现通信的。不过,这些通信过程,作为运行到开发板上的应用程序是无从知道的,这些基于开发板底层的通信,完全由tinyclr进行全权管理。
   我以前写了一篇关于这个信道的通信协议的介绍文章《
micro framework wireprotocol协议介绍
》,文章中介绍,wireprotocol协议是上位机mfdeploy或vs2008程序在诊断、部署、调试.net micro framework设备及相关应用程序时的通信协议。该协议与具体的硬件链路无关,目前支持的物理连接有串口、网口、usb等。该协议为点对点协议,协议中没有设备地址的概念,在同一时间同一物理通道仅能调试一台设备。协议格式分两部分,帧头和负荷(payload)(一帧命令可以不包含payload)。目前,通信命令一共71个,其中1个已经过时、6个已经被注销(v4.1版本又增加了几个命令)。
   有了以上知识,我们很自然地想到,借助这个通信协议,我们是否可以扩展一下,自定义我们所需要的通信命令,这样借助wireprotocol协议通道,我们就可以传输任意长度的数据了。
   不过,说起来容易,做起来难,这就像练武之人想打通任督二脉一样,打通的意义虽然重大,但是实现起来却环节众多。考虑到复杂性,所以我这里不打算详细介绍所有实现的细节,由点带面,简要说一下实现的过程,我们需要修改或创建的文件(或代码)如下:
   pc 平台:改造mfdeployengine.dll和microsoft.spot.debugger.dll文件,创建usbstream类。
   mf 平台:修改tinyclr_debugging.h和debugger.cpp文件,添加c_monitor_custom命令,此外再实现一个p/invoke接口,让运行在开发板上的用户程序可以访问该通道。
   p/invoke接口中的usbstream类的定义(.net micro framework代码)如下:
  public class usbstream
   {
       public usbstream();
       public int bytestoread { get; }
       public int bytestowrite { get; }
       public event usbstreamdatareceivedeventhandler datareceived;
       public void close();
       public void discardinbuffer();
       public void discardoutbuffer();
       public bool open();
       public int read(byte[] buffer, int offset, int count);
       public int write(byte[] buffer, int offset, int count);
   }
  和串口的定义类似,不过不用设置通信参数。
  运行在pc机上的usbstream类的定义(.net framework代码)如下:
   public class usbstream
   {
       public usbstream(yfdeploy deploy);
       public int bytestoread { get; }
       public int bytestowrite { get; }
       public void close();
       public void discardinbuffer();
       public void discardoutbuffer();
       public bool open();
       public int read(byte[] buffer, int offset, int count);
       public int write(byte[] buffer, int offset, int count);
   }
   二者代码几乎相同,不过后者构造函数中有参数,并且没有事件函数。
   我们做一个demo,来演示我们所实现的功能,很简单的做法,就是pc向开发板发送数据,开发板原样返回。
   pc机上的主要代码如下:
      private void btnsend_click(object sender, eventargs e)
       {
           if (txtoutput.text.length return;
           if (usb == null)
           {
               usb = new usbstream(deploy);
               if (!usb.open())
               {
                   txtoutput.backcolor = color.red;
                   usb = null;
                   return;
               }
               else
               {
                   txtoutput.backcolor = color.white;
               }
               trmread.enabled = true;
           }                                    
           byte[] indata = system.text.asciiencoding.utf8.getbytes(txtoutput.text);
           if (usb.write(indata, 0, indata.length)>0)
           {
               txtoutput.backcolor = color.white;
           }
           else
           {
               txtoutput.backcolor = color.red;
           }
       }
       private void trmread_tick(object sender, eventargs e)
       {
           if (usb != null)
           {
               if (usb.bytestoread > 0)
               {
                   byte[] bytdata = new byte[usb.bytestoread];
                   usb.read(bytdata, 0, bytdata.length);
                   txtinput.text += new string(system.text.asciiencoding.utf8.getchars(bytdata));
               }
           }
     }
    开发板上的代码如下:
      public static void main()
       {
           usbstream usb = new usbstream();
           if (usb.open())
           {
               debug.print(open ok);
               graphics.print(open ok\r\n);
           }
           usb.datareceived += new usbstreamdatareceivedeventhandler(usb_datareceived);
           while (true)
           {
               thread.sleep(100);
           }
           //usb.close();
       }
       static void usb_datareceived(object sender, eventargs e)
       {
           usbstream usb = (usbstream)sender;
           string strinfo = [ + usb.bytestoread.tostring()+];
           if (usb.bytestoread > 0)
           {
               byte[] bytdata=new byte[usb.bytestoread];
               usb.read(bytdata,0,bytdata.length);
               for (int i = 0; i
               {
                   strinfo += bytdata[i].tostring() + ;
               }
               usb.write(bytdata, 0, bytdata.length);
               graphics.print(new string(system.text.utf8encoding.utf8.getchars(bytdata)));
           }
           debug.print(strinfo);              
       }
      代码都非常简单,这里就不过多介绍了,我们看一下效果图。
     
      pc机上的程序,类似串口调试工具,可以发送和接收数据。
       
      开发板的lcd屏上显示从pc接收的数据。
     
       调试串口输出的调试信息,可以看到开发板接收的字节数据。
   以上功能的实现还是非常有意义的,特别是我们做一个产品的时候,我们可以很方便的通过pc配置我们产品的参数,并且可以和该产品进行通信。这样就不需要通过其它的通信口,来完成该功能了。并且难能可贵的是,实现了私有通信,但是并没有牺牲掉调试口。

本文源码:
http://www.sky-walker.com.cn/yefan/mfv40/sourcecode/yfaccess.rar
mf快速参考:
.net micro framework 快速入门
mf中文讨论组:
http://space.cnblogs.com/group/mfsoft/
【低价开发板】
http://item.taobao.com/item.htm?id=7117999726
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=132191&Name=yefanqiu
87
gkongman
文章数:-5
年度积分:-120
历史总积分:87
注册时间:2010/12/30
发站内信
发表于:2011/1/16 20:35:28
#1楼
此楼内容不符合板块规定,不予显示! 查看原帖内容>>
工控学堂推荐视频:

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

46.8003