程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 【玩轉.Net MF – 01】Flash遠程讀寫

【玩轉.Net MF – 01】Flash遠程讀寫

編輯:關於.NET

目前在PC遠程訪問設備Flash,也就是部署TinyCLR和下載應用程序。在以前寫 的《NandFlash驅動開發》文章,我們知道Flash被分為六個區,典型的結構如下 (以Sam9261_ek開發板為例):

const BlockRange g_K9F2G_8_BlockStatus[] =
{
     { BlockRange::BLOCKTYPE_BOOTSTRAP ,  0,  1 },
     { BlockRange::BLOCKTYPE_CONFIG    ,  2,  2 },
     { BlockRange::BLOCKTYPE_CODE      ,  3, 24 },
     { BlockRange::BLOCKTYPE_DEPLOYMENT, 25, 29 },
     { BlockRange::BLOCKTYPE_DEPLOYMENT, 30, 34 },
     { BlockRange::BLOCKTYPE_DEPLOYMENT, 35, 39 },
     { BlockRange::BLOCKTYPE_DEPLOYMENT, 40, 48 },
     { BlockRange::BLOCKTYPE_STORAGE_A , 49, 49 },
     { BlockRange::BLOCKTYPE_STORAGE_B , 50, 50 },    
     {BlockRange::BLOCKTYPE_FILESYSTEM, 51, FLASH_BLOCK_COUNT  - 1 }
};

我們能否直接讀寫該Flash上的所有區呢?

實現這個功能的好處是易見的,我們再也沒有必要為了下載一個應用程序而啟 動相對龐大的VS2008,再也不受必須打開MF工程才能下載的限制。在我們開發Ti DM355開發板就遇到類似問題,我們給異地開發板提供者演示相關程序功能時,必 須要求對方安裝VS2008,還必須發送我們的項目源碼,否則就無法在另外的開發 板上進行演示。

仔細研究了一下MFDeploy程序(這是典型的C#程序,在Vista和Windows7上可 直接運行,在WinXP及以前的系統上需要安裝.Net Framework運行時),發現可以 為其開發一個插件來實現我們所要求的功能。

MFDeploy程序可以通過三種方式來訪問.Net MF設備,串口、網口和USB,並且 可以把TinyCLR部署到設備上去(需要開發板運行TinyBooter),也可以清空應用 程序區,所以我們只要把這部分功能給擴展一下就可以了。

插件類必須繼承於MFPlugInMenuItem類,相關代碼如下:

public class PlugInHandle : MFPlugInMenuItem
      {
         public override string Name { get { return  "Read/Write Flash"; } }
         public override void OnAction(IMFDeployForm  form, MFDevice device)
         {
             if (form == null || device == null)  return;
             (new frmRWFlash(form, device)).ShowDialog ();
         }
}

其中由宿主傳遞過來的form和device非常重要,form就是針對MFDeploy主窗體 ,主要提供DumpToOutput函數,把消息顯示到信息區,而device則提供和設備通 信的相關函數,如Ping、Deploy、Erase、Execute等。

插件實現的第一步,要讀寫Flash區,首先要獲取Flash的內存映像表,通過如 下的代碼就可以獲取:

_DBG.WireProtocol.Commands.Monitor_FlashSectorMap.Reply reply  = engine.GetFlashSectorMap();
if (reply != null)
{
     for (int i = 0; i < reply.m_map.Length; i++)
     {
         _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.FlashSectorData fsd  = reply.m_map[i];
         string usage = "";
         switch (fsd.m_flags &  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK)
         {
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_APPLIC ATION:
                 usage = "Application";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_BOOTST RAP:
                 usage = "Bootstrap";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CODE:< BR>                  usage = "Code";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CONFIG :
                 usage = "Configuration";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_DEPLOY MENT:
                 usage = "Deployment";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_JITTER :
                 usage = "Jitter";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_FS:
                 usage = "File System";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_RESERV ED:
                 usage = "Reserved";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAG E_A:
                 usage = "Storage";
                 break;
             case  _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAG E_B:
                 usage = "Storage";
                 break;
             case 0xA0:
                 usage = "Custom";
                 break;
         }
         FlashMap.Add(FlashMaps, usage, fsd.m_address,  fsd.m_size);
   }
}

第二步就是讀寫Flash的扇區數據,可以通過如下代碼實現:

bool ret = engine.ReadMemory(addr, buflen, out  bytData);
bool ret = engine.WriteMemory(addr, FileIndex.GetBytes(), 0,  (int)FileIndex.HeadSize);

但是僅僅實現以上兩步還不行,因為TinyCLR代碼會限制一些Flash的讀寫范圍 ,所以我們還得需要修改TinyCLR的代碼。

在\CLR\Debugger目錄下的Debugger.cpp文件有一個函數CheckPermission,我 們修改一下它的代碼,讓它直接返回true就可以了,這樣我們就可以對Flash任何 區都可以讀寫了。

bool CLR_DBG_Debugger::CheckPermission( ByteAddress  address, int mode )
{
     NATIVE_PROFILE_CLR_DEBUGGER();
     bool   hasPermission = false;
     UINT32 regionIndex, rangeIndex;

     m_deploymentStorageDevice->FindRegionFromAddress(  address, regionIndex, rangeIndex );
     const BlockRange& range = m_deploymentStorageDevice ->GetDeviceInfo()->Regions[ regionIndex ].BlockRanges[  rangeIndex ];

     return true;
     /*
     switch(mode)
     {
         case AccessMemory_Check:
             hasPermission = true;
             break;
         case AccessMemory_Read:
             switch(range.RangeType)
             {
                 case BlockRange::BLOCKTYPE_CONFIG:  // fall through
                 case  BlockRange::BLOCKTYPE_DIRTYBIT: // fall through
                 case  BlockRange::BLOCKTYPE_DEPLOYMENT: // fall through
                 case  BlockRange::BLOCKTYPE_FILESYSTEM: // fall through
                 case  BlockRange::BLOCKTYPE_STORAGE_A: // fall through
                 case  BlockRange::BLOCKTYPE_STORAGE_B:

                     hasPermission = true;
                     break;
             }
             break;
         case AccessMemory_Write:
             if(range.IsDeployment())
             {
                 hasPermission = true;
             }
             break;
         case AccessMemory_Erase:
             switch(range.RangeType)
             {
                 case  BlockRange::BLOCKTYPE_DEPLOYMENT: // fall through
                 case  BlockRange::BLOCKTYPE_FILESYSTEM: // fall through
                 case  BlockRange::BLOCKTYPE_STORAGE_A: // fall through
                 case  BlockRange::BLOCKTYPE_STORAGE_B:
                     hasPermission = true;
                     break;
             }
             break;
         default:
             hasPermission = false;
             break;
     }

     return hasPermission;*/
}

編譯好插件,把它拷貝到MFDeploy.exe文件所在的子目錄PlugIn,啟動 MFDeploy.exe程序,在Plug-in菜單下就會有我們的插件菜單。

這樣就可以對Flash上的任何區都可以進行讀寫了。並且針對Deployment區, 不僅可以下載.Net Micro Framework應用程序,也可以單擊“Run”按鈕,運行當 前下載的程序(這樣就不用重啟TinyCLR了)。

針對File System區,我考慮實現一個類似VS2008遠程工具“遠程文件查看器 ”,這樣PC就會更方便和.Net MF設備進行交互了。如果大家看過我以前寫的 《LCD驅動開發》,屏幕上顯示的位圖,就是通過該插件下載的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved