【玩转.Net MF – 01】Flash远程读写

简介: 目前在PC远程访问设备Flash,也就是部署TinyCLR和下载应用程序

目前在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_APPLICATION:

                usage = "Application";

                break;

            case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_BOOTSTRAP:

                usage = "Bootstrap";

                break;

            case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CODE:

                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_DEPLOYMENT:

                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_RESERVED:

                usage = "Reserved";

                break;

            case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_A:

                usage = "Storage";

                break;

            case _DBG.WireProtocol.Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_STORAGE_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驱动开发》,屏幕上显示的位图,就是通过该插件下载的。

相关文章
|
Windows
.Net Micro Framework研究—模拟器直接运行MF程序
既然VS2005能启动运行,我想我们也可以,唯一不同的是模拟器加载的参数不同而已
718 0
.Net Micro Framework研究—用MF编写俄罗斯方块
现在对MF充满了激情,所以从零做起(没有参考任何现成代码,只不过还是依照我早期的思路编写而成),花费我大半天的时间才编写完毕(在编写过程中,还发现MF对二维数组支持不大好,我后面会提到)
388 0
.Net Micro Framework研究—让MF支持鼠标
MF的标准模块仅支持按键,并不支持鼠标功能。但是对一些常见应用来说,如果没有鼠标(或触摸屏)用起来就太不习惯了
482 0
|
机器人
.Net Micro Framework研究—用MF控制机器人
机器人研究一直是我很早以前的梦想,没有想到在深入研究.Net Micro Framework同时能和机器人搭上了联系。
552 0
.Net Micro Framework研究—让MF支持英文输入法
目前字符串不仅无法转换为数字,并且没有字符插入功能,所以这个函数也必须自己来实现,此外输入焦点光标也需要自己绘制,好了,先不说难处了,先看看最终成果。
699 0
.Net Micro Framework研究—MF驱动继电器
年前张欣有一个比较好的想法,想用Digi的MF板驱动一个小型继电器,这样就可以用MF直接控制家中的小功率220V的电器了
583 0
|
安全
.Net MF V4.0开源前的代码整理
已经有好长一段时间没有更新博客了,一是去美国总部和台湾出差用了不少时间,二是做.Net MF代码整理又花了近一个月的时间。不过令人欣慰的是,目前.Net MF V4.0的相关代码整理已经告一段落,就等着下一步的开源了
660 0
|
Linux C++ C#
【.Net Micro Framework PortingKit – 15】移植总结兼MF未来发展
我坚信.Net Micro Framework在未来嵌入式发展中,一定会占有一席之地(更何况现在已经开源了,并且采用更为彻底的Apache 2.0 license)。希望更多的人参与其中,把.Net Micro Framework移植到更多嵌入式平台上去,使它成为真正名副其实的“框架”。
908 0
|
内存技术
【玩转.Net MF – 02】让PC成为MF的鼠标键盘
通过扩展我以前为.Net MF开发的WinForm库(参见我以前的文章《开源System.Windows.Forms库,让.Net Micro Framework界面开发和上位机一样简单》),增加一个输入代理层,就可以实现虚拟鼠标和键盘输入。
605 0
|
网络协议
【玩转.Net MF – 03】远程文件查看器
做过WinCE或Windows Mobile开发的人都知道,VS2008开发工具提供了些远程工具,诸如远程文件查看器、远程注册表编辑器、远程堆查看器和远程放大等等。受此启发,所以才有了MF的远程文件查看器。
623 0