도와주세요!!
글 수 15,339
2003.09.04 11:04:58 (*.113.163.113)
6662
안녕하세요.
현재 ezboard 기반에 mpeg 코덱 칩을 붙여서 사용하고 있습니다.
해당 칩의 리눅스 드라이버를 제작하고 있는데, 레지스터를 쓰고 읽는데 약간
의 문제가 있어서 질문드립니다.
먼저 nCS4( 0x40000000 )의 base address를 가지고 있습니다. 커널상(
ezboard.c )에서 물리주소 0x40000000을 가상주소 0xf1000000으로 맵핑하였습
니다.
ezboard.c에서
static struct map_desc ezboard_io_desc[] __initdata = {
//.........
{ 0xf1000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 },
LAST_DESC
};
위 부분 추가 ...
첫번째는 드라이버의 틀을 만들고(init_module, ioctl, etc ) 레지스터 쓰고
읽는 테스트 루틴을 init_module안에 넣어봤습니다.
두번째로는 드라이버 없는 프로그램을 만들었는데, 직접 0xf1000000을 가지고
해당 레지스터에 쓰고 읽는 프로그램( 아래 main 참고 )입니다.
결론적으로 드라이버 없는 테스트 프로그램은 정확하게 레지스터에 접근 가능
한 것으로 보이나, 드라이버에서는 정상적으로 접근하지 못합니다.
최종적으로는
#define _my_arch_getw(x) (*((volatile unsigned int *)(x)))
#define _my_arch_putw(x,y) (*((volatile unsigned int *)(x)) = y)
2가지(드라이버/응용프로그램) 모두 위와 같은 함수로 접근을 합니다. 물론 테
스트 루틴 자체도 드라이버에서 구현한 것과 테스트 프로그램도 동일합니다.
드라이버에서 위의 루틴을 이용하여 해당 메모리를 읽고 쓰는 것과 테스트 프
로그램에서 읽고 쓰는 것이 차이가 있는지요?
/////////테스트 프로램///////////////////////////////////////////
static inline unsigned int HIUCTLCODE (unsigned int a, unsigned int b) {
return ( (unsigned int)(( a << 11 | b) & 0x1F9FF)<<1);
}
unsigned int READ_REGISTER_USHORT(unsigned long address)
{
return _my_arch_getw(address);
}
void WRITE_REGISTER_USHORT(unsigned long address,U16 value)
{
_my_arch_putw(address,value);
}
int main(void){
int i,j,k;
unsigned long vweb_base = 0xf1000000;
unsigned short lo,hi;
unsigned int HIUCMD;
unsigned long read_data;
printf("Vweb Test routine
");
HIUCMD = HIUCTLCODE(0x15,0x12);
lo=READ_REGISTER_USHORT(vweb_base+HIUCMD);
printf("
READ Decoder Sample reg : 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15,0x16);
lo=READ_REGISTER_USHORT(vweb_base+HIUCMD);
printf("
READ Decoder Sample reg : 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15,0x12);
lo=READ_REGISTER_USHORT(vweb_base+HIUCMD);
printf("
READ 0x12 Sample reg : 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15,0x16);
lo=READ_REGISTER_USHORT(vweb_base+HIUCMD);
printf("
READ 0x16 Sample reg : 0x%x
",lo);
return 0;
}
위와 같은 루틴이 드라이버의 init_module에서 테스트 되면 다른 결과를 나타
냅니다.
int __init init_module(void)
{
U32 HIUCMD;
unsigned int lo,hi;
int i=0,j=0;
int ret
if ((ret = register_chrdev(VWEB2010_DEVNUM, VWEB2010_DEVNAME,
&vw2010_fops)) < 0) {
printk("[E] error
", ret);
return -1;
}
MSC2 = 0xfffcfffc;
for(j=0;j<1000000;j++);
my_base = 0xf1000000;
HIUCMD = HIUCTLCODE(0x16, 0x12);
WRITE_REGISTER_USHORT((my_base + HIUCMD), 0x0009);
// set to 162 MHz
HIUCMD = HIUCTLCODE(0x16, 0x16);
printk("add: 0x%lx HIUCMD : 0x%x
",(my_base+HIUCMD),HIUCMD);
WRITE_REGISTER_USHORT((my_base + HIUCMD), 0xc000);
HIUCMD = HIUCTLCODE(0x15, 0x16);
lo=READ_REGISTER_USHORT((my_base + HIUCMD));
printk("reg 0x16 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15, 0x12);
lo=READ_REGISTER_USHORT((my_base + HIUCMD));
printk("reg 0x12 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15, 0x13);
lo=READ_REGISTER_USHORT((my_base + HIUCMD));
printk("reg 0x13 0x%x
",lo);
return 0;
}
차이가...뭘까요....그럼 수고하세요..
현재 ezboard 기반에 mpeg 코덱 칩을 붙여서 사용하고 있습니다.
해당 칩의 리눅스 드라이버를 제작하고 있는데, 레지스터를 쓰고 읽는데 약간
의 문제가 있어서 질문드립니다.
먼저 nCS4( 0x40000000 )의 base address를 가지고 있습니다. 커널상(
ezboard.c )에서 물리주소 0x40000000을 가상주소 0xf1000000으로 맵핑하였습
니다.
ezboard.c에서
static struct map_desc ezboard_io_desc[] __initdata = {
//.........
{ 0xf1000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 },
LAST_DESC
};
위 부분 추가 ...
첫번째는 드라이버의 틀을 만들고(init_module, ioctl, etc ) 레지스터 쓰고
읽는 테스트 루틴을 init_module안에 넣어봤습니다.
두번째로는 드라이버 없는 프로그램을 만들었는데, 직접 0xf1000000을 가지고
해당 레지스터에 쓰고 읽는 프로그램( 아래 main 참고 )입니다.
결론적으로 드라이버 없는 테스트 프로그램은 정확하게 레지스터에 접근 가능
한 것으로 보이나, 드라이버에서는 정상적으로 접근하지 못합니다.
최종적으로는
#define _my_arch_getw(x) (*((volatile unsigned int *)(x)))
#define _my_arch_putw(x,y) (*((volatile unsigned int *)(x)) = y)
2가지(드라이버/응용프로그램) 모두 위와 같은 함수로 접근을 합니다. 물론 테
스트 루틴 자체도 드라이버에서 구현한 것과 테스트 프로그램도 동일합니다.
드라이버에서 위의 루틴을 이용하여 해당 메모리를 읽고 쓰는 것과 테스트 프
로그램에서 읽고 쓰는 것이 차이가 있는지요?
/////////테스트 프로램///////////////////////////////////////////
static inline unsigned int HIUCTLCODE (unsigned int a, unsigned int b) {
return ( (unsigned int)(( a << 11 | b) & 0x1F9FF)<<1);
}
unsigned int READ_REGISTER_USHORT(unsigned long address)
{
return _my_arch_getw(address);
}
void WRITE_REGISTER_USHORT(unsigned long address,U16 value)
{
_my_arch_putw(address,value);
}
int main(void){
int i,j,k;
unsigned long vweb_base = 0xf1000000;
unsigned short lo,hi;
unsigned int HIUCMD;
unsigned long read_data;
printf("Vweb Test routine
");
HIUCMD = HIUCTLCODE(0x15,0x12);
lo=READ_REGISTER_USHORT(vweb_base+HIUCMD);
printf("
READ Decoder Sample reg : 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15,0x16);
lo=READ_REGISTER_USHORT(vweb_base+HIUCMD);
printf("
READ Decoder Sample reg : 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15,0x12);
lo=READ_REGISTER_USHORT(vweb_base+HIUCMD);
printf("
READ 0x12 Sample reg : 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15,0x16);
lo=READ_REGISTER_USHORT(vweb_base+HIUCMD);
printf("
READ 0x16 Sample reg : 0x%x
",lo);
return 0;
}
위와 같은 루틴이 드라이버의 init_module에서 테스트 되면 다른 결과를 나타
냅니다.
int __init init_module(void)
{
U32 HIUCMD;
unsigned int lo,hi;
int i=0,j=0;
int ret
if ((ret = register_chrdev(VWEB2010_DEVNUM, VWEB2010_DEVNAME,
&vw2010_fops)) < 0) {
printk("[E] error
", ret);
return -1;
}
MSC2 = 0xfffcfffc;
for(j=0;j<1000000;j++);
my_base = 0xf1000000;
HIUCMD = HIUCTLCODE(0x16, 0x12);
WRITE_REGISTER_USHORT((my_base + HIUCMD), 0x0009);
// set to 162 MHz
HIUCMD = HIUCTLCODE(0x16, 0x16);
printk("add: 0x%lx HIUCMD : 0x%x
",(my_base+HIUCMD),HIUCMD);
WRITE_REGISTER_USHORT((my_base + HIUCMD), 0xc000);
HIUCMD = HIUCTLCODE(0x15, 0x16);
lo=READ_REGISTER_USHORT((my_base + HIUCMD));
printk("reg 0x16 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15, 0x12);
lo=READ_REGISTER_USHORT((my_base + HIUCMD));
printk("reg 0x12 0x%x
",lo);
HIUCMD = HIUCTLCODE(0x15, 0x13);
lo=READ_REGISTER_USHORT((my_base + HIUCMD));
printk("reg 0x13 0x%x
",lo);
return 0;
}
차이가...뭘까요....그럼 수고하세요..