1

アドレスとデータを吐き出すフラッシュ メモリ ダンプ ファイルがあります。有効なタグを教えてくれるようにデータを解析したい '002F0900' 列は開始アドレスです。有効なタグの例は、"DC 08 00 06 00 00 07 26 01 25 05 09" です。"DC 08" = タグ番号、"00 06" = タグ データ長、"00 00" = タグ バージョン。タグ データはバージョンの後に始まります。この場合、「07 26 01 25 05 09」になり、次のタグは「DC 33」から始まります。

最初のタグをデータの長さまで印刷できますが、データが次の行に進むかどうかを考慮する必要があるため、データを印刷する方法がわからないため、何らかの方法でアドレスをスキップする必要があります. 各行には 58 列が含まれます。各アドレスは、次の 16 進数値が始まるまで、8 文字にコロンと 2 つのスペースを加えた長さです。

また、アドレス欄に「DC」がいつ表示されるかについても、最終的には検討する必要があります。私がどのようにやっているのか知っているので、誰かがアドバイスを与えることができれば、これはこれを行うための最良の方法ではありません. 私は最初にそれを機能させようとしています。

テキスト ファイルは、次のような数千行です。

002F0900:  09 FF DC 08 00 06 00 00 07 26 01 25 05 09 DC 33
002F0910:  00 07 00 00 1F A0 26 01 25 05 09 FF 9C 3E 00 08
002F0920:  00 01 07 DD 0A 0D 00 29 35 AD 9C 41 00 0A 00 01
002F0930:  07 DD 0A 0D 00 29 36 1C 1D 01 9C 40 00 02 00 01
002F0940:  01 00 9C 42 00 0A 00 01 07 DD 0A 0D 00 29 36 21
002F0950:  1D AD 9C 15 00 20 00 00 01 00 00 00 00 04 AD AE
002F0960:  C8 0B C0 8A 5B 52 01 00 00 00 00 00 FF 84 36 BA
002F0970:  4E 92 E4 16 28 86 75 C0 DC 10 00 05 00 00 00 00
002F0980:  00 00 01 FF DC 30 00 04 00 01 00 00 00 01 9C 41

出力例は次のとおりです。

Tag Number: DC 08
Address: 002E0000    
Data Length: 06
Tag Data: 07 26 01 25 05 09

ソースコード:

#include<stdio.h>
FILE *fp;

main()
{
    int i=0;
    char ch;
    char address[1024];
    char tag_number[5];
    char tag_length[4];
    int number_of_addresses = 0;
    long int length;

    fp = fopen(FILE_NAME,"rb");
    if(fp == NULL) {
        printf("error opening file");
    }
    else {
        printf("File opened\n");
        while(1){
            if((address[i]=fgetc(fp)) ==':')
                break;

            number_of_addresses++;
            i++;
        }

        printf("\nAddress:");
        for (i = 0; i < number_of_addresses;i++)
            printf("%c",address[i]);

        while((ch = fgetc(fp)) != 'D'){ //Search for valid tag
        }

        tag_number[0] = ch;
        if((ch = fgetc(fp)) == 'C')  //We have a valid TAG
        {
            tag_number[1] = ch;
            tag_number[2] = fgetc(fp);
            tag_number[3] = fgetc(fp);
            tag_number[4] = fgetc(fp);
        }

        printf("\nNumber:");
        for(i=0;i<5;i++)
            printf("%c",tag_number[i]);

        fgetc(fp);      //For space
        tag_length[0] = fgetc(fp);
        tag_length[1] = fgetc(fp);
        fgetc(fp);      //For space
        tag_length[2] = fgetc(fp);
        tag_length[3] = fgetc(fp);

        printf("\nLength:");

        for(i=0;i<4;i++)
            printf("%c",tag_length[i]);

        length = strtol(tag_length,&tag_length[4], 16);
        printf("\nThe decimal equilvant is: %ld",length);
        for (i = 0;i<165;i++)
            printf("\n%d:%c",i,fgetc(fp));
    }

    fclose(fp);
}

更新 @ooga: タグは勝手に書いてます。ロジックで無効なタグも考慮すれば、もう少し時間をかけて残りを把握できるはずです。ありがとう

4

1 に答える 1

2

これは、あなたが何を必要としているのか完全にはわからないので、あなたが始めるための単なるアイデアです. 基本的な考え方はread_byte、次の 2 桁の 16 進数値をバイトとして返し、そのアドレスも返すというものです。

#include <stdio.h>
#include <stdlib.h>

#define FILE_NAME "UA201_dump.txt"

void err(char *msg) {
  fprintf(stderr, "Error: %s\n", msg);
  exit(EXIT_FAILURE);
}

// read_byte
// Reads a single two-digit "byte" from the hex dump, also
// reads the address (if necessary).
// Returns the byte and current address through pointers.
// Returns 1 if it was able to read a byte, 0 otherwise.

int read_byte(FILE *fp, unsigned *byte, unsigned *addr_ret) {

  // Save current column and address between calls.
  static int column = 0;
  static unsigned addr;

  // If it's the beginning of a line...
  if (column == 0)
    // ... read the address.
    if (fscanf(fp, "%x:", &addr) != 1)
      // Return 0 if no address could be read.
      return 0;

  // Read the next two-digit hex value into *byte.
  if (fscanf(fp, "%x", byte) != 1)
    // Return 0 if no byte could be read.
    return 0;

  // Set return address to current address.
  *addr_ret = addr;
  // Increment current address for next time.
  ++addr;

  // Increment column, wrapping back to 0 when it reaches 16.
  column = (column + 1) % 16;

  // Return 1 on success.
  return 1;
}


int main() {
  unsigned byte, addr, afterdc, length, version, i;

  FILE *fp = fopen(FILE_NAME,"r");
  if (!fp) {
    fprintf(stderr, "Can't open %s\n", FILE_NAME);
    exit(EXIT_FAILURE);
  }

  while (read_byte(fp, &byte, &addr)) {
    if (byte == 0xDC) {

      // Read additional bytes like this:
      if (!read_byte(fp, &afterdc, &addr)) err("EOF 1");

      if (!read_byte(fp, &length, &addr)) err("EOF 2");
      if (!read_byte(fp, &byte, &addr)) err("EOF 3");
      length = (length << 8) | byte;

      if (!read_byte(fp, &version, &addr)) err("EOF 4");
      if (!read_byte(fp, &byte, &addr)) err("EOF 5");
      version = (version << 8) | byte;

      printf("DC: %02X, %u, %u\n  ", afterdc, length, version);
      for (i = 0; i < length; ++i) {
        if (!read_byte(fp, &byte, &addr)) err("EOF 6");
        printf("%02X ", byte);
      }
      putchar('\n');
    }
  }

  fclose(fp);
  return 0;
}

いくつかの説明:

が呼び出されるたびread_byteに、16 進ダンプから次の出力バイト (2 桁の 16 進値) を読み取ります。そのバイトとそのバイトのアドレスも返します。

各行には 16 個の 2 桁の 16 進数値があります。列番号 (0 ~ 15) は、呼び出し間で静的変数に保持されます。列は各バイトを読み取るたびにインクリメントされ、列が 16 に達するたびに 0 にリセットされます。

列番号が 0 のときはいつでも、出力されたアドレスを読み取り、呼び出し間でそれを静的変数に保持します。また、静的 addr 変数をインクリメントして、行の任意のバイトのアドレスを示すことができるようにします (列番号がゼロでない場合)。

例として、次のように使用できます。read_byeこれは、各バイト値とそのアドレスを別の行に出力します。

// after opening file as fp
while (read_byte(fp, &byte, &addr))
    printf("%08X- %02X\n", addr, byte);

(それが役立つというわけではありませんが、それをテストするには、質問で提供したスニペットを使用して実行できます。)

于 2014-06-18T16:43:55.557 に答える