norains的专栏

只专注于WINCE开发

用户操作
[即时聊天] [发私信] [加为好友]
norainsID:norains
130922次访问,排名642(-1)好友0人,关注者27
代码其实是一种乐趣
norains的文章
原创 186 篇
翻译 0 篇
转载 10 篇
评论 258 篇
norains的公告
联系方式请看置顶文章
最近评论
zhli6:如果我们想令该PIN作为GPIO并输出high,那么代码如下:
REG_HW_PINCTRL_MUXSEL0_SET(BF_PINCTRL_MUXSEL0_BANK0_PIN08(3));
REG_HW_PINCTRL_DOUT0_CLR(1 << 8);
REG_HW_PINCTRL_DOE0_SET(1 << 8);……
晴天:請問一下:
如果要寫成Watchdog timer 納在這這要如何實現呢?
hustpanda:电子书看不了呢?
bobo:“耍大牌”...... 你就该直接拉黑
bulrush:你好,首先先感谢一下。我看了你的音量控制,自己也去实现了一下,但是我个人感觉“AudioUpdateFromRegistry”没有依据注册表的设置来更新控制面板的音量。没有马上更新,我重启系统后才看到更新的结果。也就是说这种方法是可行,但是必须要重启,显然这不合理。上面的兄弟说:引用了这两个类后不起作用
如:
void CSoundDlg::OnSoft()
……
文章分类
收藏
    相册
    动漫
    文章图片
    程序交流
    xumercury的BLOG
    狗友们的博客
    清蒸石斑鱼
    美女如刀锋
    茁茁的BLOG
    魅力老姐的窝
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 S-Record格式分析代码收藏

    新一篇: 喘气 | 旧一篇: 另一半的标准

    //========================================================================
    //TITLE:
    //    S-Record格式分析代码
    //AUTHOR:
    //    norains
    //DATE:
    //    Wednesday  30-April-2008
    //Environment:
    //    NULL
    //========================================================================
        MOTOROLA S-Record的格式并不复杂,相关的描述可以参考我另一篇文章《S-Record格式详解》:http://blog.csdn.net/norains/archive/2008/04/25/2326306.aspx。本文主要是在代码层次对S-Record进行分析。

        和以往相同,为了方便使用,将S-Record的分析代码封装为一个CSrecParse类。
       
        以下为CSrecParse类代码:   


    //////////////////////////////////////////////////////////////////////    
    // SrecParse.h: interface for the CSrecParse class.
    //
    //////////////////////////////////////////////////////////////////////    
    #pragma once

    #include 
    <string>
    #include 
    <vector>


    #ifdef UNICODE
        typedef std::wstring TSTRING;
    #else
        typedef std::
    string TSTRING;
    #endif

    class CSrecParse
    {
    public:
        
    enum Type
        {
            S0 
    = 0,
            S1,
            S2,
            S3,
            S4,
            S5,
            S6,
            S7,
            S8,
            S9
        };


    public:
        
    //Interface
        bool SetFile(const TSTRING & strFile);
        
    bool GetNextData(CSrecParse::Type &type, DWORD &dwAddr,std::vector<BYTE> &vctData, bool &bChkSum);

    public:
        CSrecParse(
    void);
        
    ~CSrecParse(void);
        
    void Reset(void);

        
    protected:
        DWORD HexToDec(
    const char *pChar,int iLen = -1);

    private:
        std::
    string::size_type m_stPos;
        std::
    string m_strContent;

    };

     

    //////////////////////////////////////////////////////////////////////   
    // SrecParse.cpp
    //
    //////////////////////////////////////////////////////////////////////  
    #include "stdafx.h"
    #include "SrecParse.h"

    CSrecParse::CSrecParse(void):
    m_stPos(0)
    {
    }

    CSrecParse::~CSrecParse(void)
    {
    }


    //----------------------------------------------------------
    //Description:
    // Set the S-Record file to parse
    //
    //----------------------------------------------------------
    bool CSrecParse::SetFile(const TSTRING & strFile)
    {

     HANDLE hFile = CreateFile(&strFile[0],GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
     if(INVALID_HANDLE_VALUE == hFile)
     {
      return false;
     }

     DWORD dwFileSize = GetFileSize(hFile,NULL);
     if(m_strContent.capacity() < dwFileSize)
     {
      m_strContent.resize(dwFileSize);
     }
     
     DWORD dwFileRead = 0;
     ReadFile(hFile,&m_strContent[0],dwFileSize,&dwFileRead,NULL);
     CloseHandle(hFile);

     return true;
    }


    //----------------------------------------------------------
    //Description:
    // Get the next data. If you want to get the first data,you should call Reset() before calling the function.
    //
    //Parameter:
    // type : [out] The data type
    // dwAddr : [out] The address
    // vctData : [out] The buffer for store the data.
    // bChkSum : [out] The checksum is right or not.
    //
    //----------------------------------------------------------
    bool CSrecParse::GetNextData(CSrecParse::Type &type, DWORD &dwAddr,std::vector<BYTE> &vctData, bool &bChkSum)
    {
     m_stPos = m_strContent.find("S",m_stPos);  
     if(m_stPos != std::string.npos)
     { 
      std::string strCvrt(10,0);
      std::vector<BYTE> vctStore;
      DWORD dwSum = 0;

      //The type
      strCvrt[0] = m_strContent[m_stPos + 1];
      strCvrt[1] = '\0';
      type = static_cast<CSrecParse::Type>(atoi(&strCvrt[0]));
      if(type == S5)
      {
       //Doesn't support the S5 type in current
       return false;
      }

      

      //The length, include <address>,<data>,<checksum> field;
      strCvrt[0] = m_strContent[m_stPos + 2];
      strCvrt[1] = m_strContent[m_stPos + 3];
      strCvrt[2] = '\0';
      int iLength = static_cast<int>(HexToDec(&strCvrt[0])) * 2; //Plus 2 to convert to the string length.
      
      dwSum += static_cast<int>(HexToDec(&strCvrt[0]));

     

      if(type == S0)
      {
       //Address
       dwAddr = 0;

       //The data
       for(int i = 0; i < iLength - 6; i += 2)
       {
        strCvrt[0] = m_strContent[m_stPos + 8 + i];
        strCvrt[1] = m_strContent[m_stPos + 9 + i];
        strCvrt[2] = '\0';

        BYTE uData = static_cast<BYTE>(HexToDec(&strCvrt[0]));
        vctStore.push_back(uData);
        dwSum += uData;
       }
       vctData = vctStore;

       //The checksum
       strCvrt[0] = m_strContent[m_stPos + iLength + 2];
       strCvrt[1] = m_strContent[m_stPos + iLength + 3];
       strCvrt[2] = '\0';

       bChkSum = (static_cast<BYTE>(HexToDec(&strCvrt[0])) == ( 0xFF - (dwSum & 0xFF)));

       m_stPos ++;

       return true;
      }
      else
      {
       //S1,S2,S3,S7,S8,S9


       //The address
       int iLenAddr = 0;
       switch(type)
       {
        case S1:
        case S9:
         iLenAddr = 2 * 2;//Plus 2 to convert to the string length.
         break;
        case S2:
        case S8:
         iLenAddr = 3 * 2;//Plus 2 to convert to the string length.
         break;
        case S3:
        case S7:
         iLenAddr = 4 * 2;//Plus 2 to convert to the string length.
         break;
       }
       for(int i = 0; i < iLenAddr; i++)
       {
        strCvrt[i] = m_strContent[m_stPos + 4 + i];   
       }
       strCvrt[iLenAddr] = '\0';
       dwAddr = HexToDec(&strCvrt[0]);

       for(int i = 0; i < iLenAddr; i += 2)
       {
        dwSum += HexToDec(&strCvrt[i],2);
       }

     

       //The data  
       int iCount = iLength - iLenAddr - 2; //The length of 2 is checksum.
       std::string::size_type stPosBegin = m_stPos + 3 + iLenAddr + 1;
       for(int i = 0; i < iCount; i += 2)
       {
        strCvrt[0] = m_strContent[stPosBegin + i];
        strCvrt[1] = m_strContent[stPosBegin + i + 1];
        strCvrt[2] = '\0';
        
        BYTE uData = static_cast<BYTE>(HexToDec(&strCvrt[0]));
        vctStore.push_back(uData);
        dwSum += uData;
       }
       vctData = vctStore;

     

       //The checksum.
       strCvrt[0] = m_strContent[m_stPos + iLength + 2];
       strCvrt[1] = m_strContent[m_stPos + iLength + 3];
       strCvrt[2] = '\0';

       bChkSum = (static_cast<BYTE>(HexToDec(&strCvrt[0])) == ( 0xFF - (dwSum & 0xFF)));
      }
      

     }
     else
     {
      return false;
     }

     m_stPos ++;
     return true;
    }


    //----------------------------------------------------------
    //Description:
    // Reset the indext to call GetNextData() to get the first data.
    //
    //----------------------------------------------------------
    void CSrecParse::Reset(void)
    {
     m_stPos = 0;
    }


    //----------------------------------------------------------
    //Description:
    // Hex convert to decade.
    //
    //Parameter:
    // pChar : [in] The string to convert. If iLen is -1,it must be with the NULL terminate end.
    // iLen : [in] The length of the pChar buffer. The default value is -1;
    //
    //----------------------------------------------------------
    DWORD CSrecParse::HexToDec(const char *pChar,int iLen)
    {
     DWORD val = 0;  
     int iCount = 0;
     while(*pChar)  
     {  
      if(*pChar >= 'a' && *pChar <= 'f')  
      {
       val = val * 16 + *pChar - 'a' + 10;  
      }
      else if(*pChar >= 'A' && *pChar <= 'F')
      {
       val = val * 16 + *pChar - 'A' + 10;
      }
      else if(*pChar >= '0' && *pChar <= '9')  
      {
       val = val * 16 + *pChar - '0';  
      }
      else
      {
       break;  
      }
      pChar++;  

      if(iLen != -1)
      {
       iCount ++;
       if(iCount >= iLen)
       {
        return val;
       }
      }
     }  
     return   val;
    }


        该类的使用非常简单,现在以一个很基本的代码作为示例:

      CSrecParse parse;
      
      
    //设置需要分析的文件路径
        parse.SetFile(&strFile[0]); 

        
    //数据的类型  
        CSrecParse::Type type;
        
        
    //数据的地址
        DWORD dwAddr;
        
        
    //存储数据的缓存
        std::vector<BYTE> vctData;
        
        
    //ChkSum位是否正确
        bool bChkSum;

      
        std::vector
    <BYTE> vctStore;
        
        
    while(parse.GetNextData(type,dwAddr,vctData,bChkSum) == true)
        {
        
    if(type == CSrecParse::S5)
            {
                
    //S5格式暂时不支持
                break;
            }
            
    else
            {
              
    //...
              
    //根据分析回来的数据去做相应处理
            }
        }

    发表于 @ 2008年04月30日 18:25:00|评论(loading...)|编辑

    新一篇: 喘气 | 旧一篇: 另一半的标准

    评论:没有评论。

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © norains