[Armadillo:02344] PC104バスへのアクセス

Hiroki Nakamura email@hidden
2007年 11月 2日 (金) 16:52:44 JST


お世話になります。
nakamuraと申します。


PC104バスへの8Bitアクセスについて確認致します。
テストプログラムを作成して、PC104バスに
アクセスしましたが、正しく値が読み出せません。
PC104バスにアクセスする手順についてご教授願えないでしょうか?

<現在のアクセスした手順>
1.★に示すテストプログラムを作成、以下のコンパイルオプションにて、
 armadillo-9上でコンパイルを実行。
#gcc -o access_tool -march=armv4t test.c

2.作成された実行ファイルにて、以下を実行。
# ./access_tool 0xf2002000 r

結果が表示される。データは0xFEとなっています。(●部分)
mmap offset_adr = 0xF2002000
Map_base Address = 0x40016000
access offset_adr = 0x0
Virtual   Address = 0x40016000
*data = 0xFE
READ   Address = 0xF2002000   Data = 0xFE(●)

3.
http://lists.atmark-techno.com/pipermail/armadillo/2005-December/000764.htmlを
参考にhermitプロンプトからアクセスした場合は、
hermit:frob> peek8 0x12002000→物理アドレス
*0x12002000 == 0x5a 'Z'
0x5aが読み出されています。

PC104バスにアクセスするには、何かレジスタに設定するなどの手順が必要なので
しょうか?
もしくはアドレスの指定がおかしいのでしょうか?


各バージョンは以下に示す通りです。
gcc (GCC) 3.3.5 (Debian 1:3.3.5-8)
Linux armadillo9 2.6.12.3-a9-10 #1 Fri Sep 14 22:00:29 JST 2007 armv4tl
GNU/Linux

★テストプログラムtest.c↓↓↓↓↓↓↓↓↓

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

//#define DBG_REG_CHECK

#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n",
\
  __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)
#define READ  0
#define WRITE 1
#define OK    0
#define NG    1

#define START_ADR 0xF2002000
#define END_ADR  0xF2005000

typedef unsigned char uchar;
//typedef unsigned long ulong;


int r_rw_reg(uchar, ulong, uchar*);

int main(int argc, char **argv) {

    int fd;
    void *map_base, *virt_addr;
 unsigned char read_result, writeval;
 off_t target;
 int access_type = 'r';
 int ret;


 if(argc < 2) {
  fprintf(stderr, "\nUsage:\t%s { address } [ type [ data ] ]\n"
   "\taddress : memory address to act upon\n"
   "\ttype    : access operation type : [r]read, [w]write \n"
   "\tdata    : data to be written (1byte access) \n\n",
   argv[0]);
  exit(1);
 }
 target = strtoul(argv[1], 0, 0);   //アクセスアドレスの取得

 if(argc > 2)
  access_type = tolower(argv[2][0]);  //アクセスタイプの取得

 if((argc > 3) && (access_type == 'w')) { //WRITE
  writeval = strtoul(argv[3], 0, 0);   //第3引数 データの取得
  ret = r_rw_reg(WRITE, target, &writeval); //書き込み処理
  if(ret == OK) {   //Write
   ret = r_rw_reg(READ, target, &read_result); //読み込み処理
   if(ret == OK) {
    printf("WRITE   Address = 0x%X   Data = 0x%X\n", target, read_result);
   }
   else {
       printf("WRITE NG!\n");

   }
  }
  else {
      printf("WRITE NG!\n");

  }
 }
 else if((argc > 2) && (access_type == 'r')) {  //READ
  ret = r_rw_reg(READ, target, &read_result); //読み込み処理
  if(ret == OK) {
   printf("READ   Address = 0x%X   Data = 0x%X\n", target, read_result);
  }
  else {
      printf("READ NG! \n");

  }
 }
 else {
     printf("Access Err ! \n");

 }

    return 0;

}

int r_rw_reg(uchar kind, ulong mapaddr, uchar* data)
{

#ifdef DBG_REG_CHECK  //デバッグ用アドレス表示
 printf("DEBUG:  r_rw_reg  mapaddr = 0x%lx\n", mapaddr);  //アドレス表示
 if(kind == WRITE) {
  printf("DEBUG:  r_rw_reg  write data = 0x%x\n", (*data)); //書き込みデータ
 }
#else


 int fd;
 int ret;
 void* virt_addr;
 void* map_base;
 int offset_adr;

// if( (mapaddr < START_ADR) || (mapaddr >= END_ADR) ) { //アクセス範囲外?
//  printf("MEMORY ADDRESS ERR \n");
//  return NG;
// }

 /* メモリデバイス/dev/memをopenする */
 fd=open("/dev/mem",O_RDWR | O_SYNC);
 if(fd<0){
  printf("dev_openerr\n");
  return NG;
 }
 /* 4096byte単位でマッピング */
 offset_adr = mapaddr & ~MAP_MASK;
 printf("mmap offset_adr = 0x%X\n", offset_adr);
 map_base = mmap(0, MAP_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED,
fd, mapaddr & ~MAP_MASK);
 if(map_base == (void *) -1){
  printf("mmap return err\n");
  return NG;
 }

 printf("Map_base Address = %p \n", map_base);
 /* base + offsetで目的の番地にアクセス */
 offset_adr = mapaddr & MAP_MASK;
 printf("access offset_adr = 0x%X\n", offset_adr);
 virt_addr = map_base + (mapaddr & MAP_MASK);
 printf("Virtual   Address = %p \n", virt_addr);
 if(kind == READ){
  *data = *((unsigned char *)virt_addr);
 }
 else{
  *((unsigned char *)virt_addr) = *data;
 }

 printf("*data = 0x%X\n", (*data));

 /* H/Wと同期する */
 ret = msync(map_base, MAP_SIZE, MS_SYNC);
 if(ret == -1){
  printf("msync return err\n");
  return NG;
 }
 /* アンマップする */
 ret = munmap(map_base, MAP_SIZE);
 if(ret == -1){
  printf("munmap return err\n");
  return NG;
 }

    close(fd);
#endif
 return OK;
}

★テストプログラム↑↑↑↑↑↑↑↑↑

以上、
よろしくお願いします。




armadillo メーリングリストの案内