目前在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);
}
}