【玩转.Net MF – 06】为Cortex-M3打造轻量级TinyGUI(上)

简介:
Microsoft .Net Micro Framework 官方UI库为WPF,针对320*240的LCD而言,至少额外需要150K以上RAM才能基本运行。而市面上常见Cortex-M3开发板的RAM大多为128K,少数开发板即使具备512k的RAM,运行官方自带的示例SimpleWPFApplication,也会出现内存溢出问题。此外由于Cortex-M3内核CPU主频大都在72M左右,官方图形库运行速度较慢。
一、参数指标
名称
 代码大小
 内存需求
 运行性能
 
WPF
 120k(含Microsoft.SPOT.TinyCore.pe)
 >150k
 运行基准测试程序,TinyGUI运行速度大概是WPF的3~5倍
 
TinyGUI
 <2k
 无需求
 
注:TinyGUI采用类似DirectDraw技术,直接操作显存,所以无内存需求,且运行速度快

二、位图显示技术比较
WPF支持标准BMP,JPG,GIF图片显示,从使用角度来看非常方便,但是由于嵌入式LCD大都为16bit显示(RGB565格式),无论是BMP还是JPG和GIF都需要进行颜色转换,此外后者还需要进行格式转换处理。以上操作,不仅导致运行速度慢,还需要一定的内存进行图形缓存。
TinyGUI的位图显示采用转换后的tinyBMP位图格式,其格式和LCD显存格式保持一致,由于图形转换工作通过程序(如下)预先完成,所以在嵌入式系统上直接向显存拷贝即可完成位图显示,所以运行速度极快。
 

(注:其实Net Micro Framework的字体就是采用类似技术,官方提供转换程序和tinyFont字体库)
核心代码其实很简单,就是把32位位图转换为指定RGB(或BGR)格式的16位位图。
InBlock.gif byte[] bytBuff =  new  byte[picBar.Height * picBar.Width * 2 + 12]; 
InBlock.gif 
InBlock.gif        BinaryWriter bw =  new BinaryWriter( new MemoryStream(bytBuff)); 
InBlock.gif 
InBlock.gif        bw.Write( new  byte[] { 84, 105, 110, 121, 66, 77, 80, 0 });  //TinyBMP\0;    
InBlock.gif 
InBlock.gif        bw.Write((UInt16)picBar.Width); 
InBlock.gif 
InBlock.gif        bw.Write((UInt16)picBar.Height); 
InBlock.gif 
InBlock.gif        Bitmap bmp =  new Bitmap(picBar.Image, picBar.Width, picBar.Height); 
InBlock.gif 
InBlock.gif         for ( int y = 0; y < bmp.Height; y++) 
InBlock.gif 
InBlock.gif        { 
InBlock.gif 
InBlock.gif                tspBar.Value = y; 
InBlock.gif 
InBlock.gif                 for ( int x = 0; x < bmp.Width; x++) 
InBlock.gif 
InBlock.gif                { 
InBlock.gif 
InBlock.gif                        bw.Write(Color_32_16(bmp.GetPixel(x, y))); 
InBlock.gif 
InBlock.gif                } 
InBlock.gif 
InBlock.gif        } 
InBlock.gif 
   三、TinyGUI图库接口
InBlock.gif namespace System.TinyGUI 
InBlock.gif 
InBlock.gif
InBlock.gif 
InBlock.gif         public  sealed  class Graphics 
InBlock.gif 
InBlock.gif        { 
InBlock.gif 
InBlock.gif                 public Graphics(); 
InBlock.gif 
InBlock.gif    
InBlock.gif 
InBlock.gif                 public  static  void Clear( uint color); 
InBlock.gif 
InBlock.gif                 public  static  void DrawEllipse( int x,  int y,  int width,  int height,  uint color); 
InBlock.gif 
InBlock.gif                 public  static  void DrawImage( int x,  int y,  byte[] bytData); 
InBlock.gif 
InBlock.gif                 public  static  void DrawImageEx( int x,  int y,  byte[] bytData,  uint MaskColor); 
InBlock.gif 
InBlock.gif                 public  static  void DrawLine( int x1,  int y1,  int x2,  int y2,  uint color); 
InBlock.gif 
InBlock.gif                 public  static  void DrawRectangle( int x,  int y,  int width,  int height,  uint color); 
InBlock.gif 
InBlock.gif                 public  static  void DrawString( int x,  int y,  string s,  uint color); 
InBlock.gif 
InBlock.gif                 public  static  void FillEllipse( int x,  int y,  int width,  int height,  uint color); 
InBlock.gif 
InBlock.gif                 public  static  void FillRectangle( int x,  int y,  int width,  int height,  uint color); 
InBlock.gif 
InBlock.gif                 public  static  uint GetPixel( int x,  int y); 
InBlock.gif 
InBlock.gif                 public  static  void Print( string str); 
InBlock.gif 
InBlock.gif                 public  static  void SetPixel( int x,  int y,  uint color); 
InBlock.gif 
InBlock.gif        } 
InBlock.gif 
InBlock.gif
InBlock.gif 
  四、TinyGUI测试程序
    运行效果图如下:

    

 

部分测试代码如下:
   
InBlock.gif static  void DrawGraphics() 
InBlock.gif 
InBlock.gif        { 
InBlock.gif 
InBlock.gif                x = rnd.Next(239); 
InBlock.gif 
InBlock.gif                width = rnd.Next(240 - x); 
InBlock.gif 
InBlock.gif                y = rnd.Next(319); 
InBlock.gif 
InBlock.gif                height = rnd.Next(320 - y); 
InBlock.gif 
InBlock.gif                c = rnd.Next(colors.Length - 1); 
InBlock.gif 
InBlock.gif                 switch (index++ % 3) 
InBlock.gif 
InBlock.gif                { 
InBlock.gif 
InBlock.gif                         case 0: 
InBlock.gif 
InBlock.gif                                 if (rnd.Next(10) > 5) 
InBlock.gif 
InBlock.gif                                        Graphics.DrawRectangle(x, y, width, height, colors[c]); 
InBlock.gif 
InBlock.gif                                 else 
InBlock.gif 
InBlock.gif                                        Graphics.FillRectangle(x, y, width, height, colors[c]); 
InBlock.gif 
InBlock.gif                                 break
InBlock.gif 
InBlock.gif                         case 1: 
InBlock.gif 
InBlock.gif                                 if (rnd.Next(10) > 5) 
InBlock.gif 
InBlock.gif                                        Graphics.DrawEllipse(x, y, width, height, colors[c]); 
InBlock.gif 
InBlock.gif                                 else 
InBlock.gif 
InBlock.gif                                        Graphics.FillEllipse(x, y, width, height, colors[c]); 
InBlock.gif 
InBlock.gif                                 break
InBlock.gif 
InBlock.gif                         case 2: 
InBlock.gif 
InBlock.gif                                Graphics.DrawLine(x, y, rnd.Next(239), rnd.Next(319), colors[c]); 
InBlock.gif 
InBlock.gif                                 break
InBlock.gif 
InBlock.gif                } 
InBlock.gif 
InBlock.gif    
InBlock.gif 
InBlock.gif                Graphics.FillRectangle(0, 300, 240, 20, Color.White); 
InBlock.gif 
InBlock.gif# if        STM3210E_EVAL 
InBlock.gif 
InBlock.gif                Graphics.DrawString(2, 303,  "Key - Back", Color.Black); 
InBlock.gif 
InBlock.gif# else 
InBlock.gif 
InBlock.gif                Graphics.DrawString(2, 303,  "Select - Back", Color.Black); 
InBlock.gif 
InBlock.gif#endif 
InBlock.gif 
InBlock.gif        } 
InBlock.gif 
InBlock.gif    
InBlock.gif 
InBlock.gif         static  void DrawPicture() 
InBlock.gif 
InBlock.gif        { 
InBlock.gif 
InBlock.gif                 if (++picIndex > 12) picIndex = 0;    
InBlock.gif 
InBlock.gif                AccessFlash.Read(( uint)(0x002A0000 + picIndex * 0xEA6C), 0xEA6C, picData); 
InBlock.gif 
InBlock.gif                 if(StateIndex!= SystemState.Main)    Graphics.DrawImage(20, 70, picData); 
InBlock.gif 
InBlock.gif
InBlock.gif 
其中图片从Flash中进行读取,图片的下载方法可以参考我以前的博客文章《Flash远程读写》,为了在C#代码中读取Flash上的内容,我重新封装了一个AccessFlash类,可以直接读写Flash任意区域的数据,这部分内容我在后续文章中再进行介绍。
这篇文章仅仅介绍了TinyGUI应用层面的内容,下篇文章《为Cortex-M3打造轻量级TinyGUI(下)》将介绍TinyGUI是如何开发的,敬请关注。








本文转自yefanqiu51CTO博客,原文链接:http://blog.51cto.com/yfsoft/321203 ,如需转载请自行联系原作者
相关文章
|
物联网 Linux 开发工具
.NET Core 跨平台串口通讯,wind ows/Linux 串口通讯,flyfire.CustomSerialPort的使用三
.NET Core 跨平台串口通讯,wind ows/Linux 串口通讯,flyfire.CustomSerialPort的使用三
467 0
.NET Core 跨平台串口通讯,wind ows/Linux 串口通讯,flyfire.CustomSerialPort的使用三
|
C# 内存技术
【玩转.Net MF – 06】为Cortex-M3打造轻量级TinyGUI(上)
Microsoft .Net Micro Framework 官方UI库为WPF,针对320*240的LCD而言,至少额外需要150K以上RAM才能基本运行。
683 0
|
Windows
在Corex-M3开发板上移植.Net Micro Framework系列文章
.NET Micro Framework 将 .NET 的可靠性和效率与 Visual Studio&reg; 的高生产率结合起来,以针对价格较低、资源受限的小型设备开发应用程序,可帮助人们使用熟悉的 Visual Studio 工具来构建托管的嵌入式应用程序。
620 0
.Net Micro Framework研究—Digi开发板初探
写的比较基础全面,由于我们北航的研发团队先研究了Digi的开发板,所以直到今天Digi开发板才到我的手上,我的《Micro Framework研究》系列文章以后也会陆续推出
707 0
.Net Micro Framework研究—MF驱动继电器
年前张欣有一个比较好的想法,想用Digi的MF板驱动一个小型继电器,这样就可以用MF直接控制家中的小功率220V的电器了
567 0
【.Net Micro Framework PortingKit – 13】LCD驱动开发
LCD的驱动开发还是比较繁琐一些的,因为LCD的驱动代码分散在三个目录中(题外话,我觉得针对.Net Micro Framework来说,最难的驱动是网卡驱动(特别是wifi驱动)、其次是USB驱动,和它们相比,LCD驱动就是小菜了)
741 0
|
内存技术 Windows 开发工具
.NET Micro Framework开发板用户简明手册(v2.0)
本手册基于.NET Micro Framework 4.1,采用VS2010进行用户程序开发。
869 0
|
Windows 内存技术 C++
.Net Micro Framework开发板用户简明手册
  作为.NET家族的一员,.Net Micro Framework是微软专门针对超轻量级平台设计的软件架构。与.Net Framework和.Net Compact Framework不同的地方是,.Net Micro Framework具有自启动的特性,并且在HAL层,微软将操作系统的必要特性引
678 0
|
开发工具 Windows 内存技术
.NET Micro Framework开发板用户简明手册(v3.0)
本手册基于.NET Micro Framework 4.2,采用VS2010进行用户程序开发, .NET Micro Framework 4.2最大的改进就是支持VB.net 编程和远程升级功能。
662 0
.Net Micro Framework研究—让MF支持鼠标
MF的标准模块仅支持按键,并不支持鼠标功能。但是对一些常见应用来说,如果没有鼠标(或触摸屏)用起来就太不习惯了
460 0