[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 メーリングリストの案内