【玩转.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是如何开发的,敬请关注。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值