作者 主題: 在ARM平台撰寫驅動程式遇到的問題  (閱讀 4724 次)

0 會員 與 1 訪客 正在閱讀本文。

acos

  • 可愛的小學生
  • *
  • 文章數: 6
  • 性別: 男
    • 檢視個人資料
    • Nothing is everything
在ARM平台撰寫驅動程式遇到的問題
« 於: 2008-11-29 15:52 »
最近在撰寫Linux的Driver要驅動版子上的一個硬體裝置(一個FPGA電路,功能是把bmp檔案的raw data做補數運算,得到負片輸出效果)
卻發生取不到值的問題
環境說明如下:ARM926-ejs平台,電路的位址為0x1CB20000(寫入區塊)、0x1CB24000(讀出區塊)

Driver的讀取函數如下:
代碼: [選擇]
ssize_t driver_read(struct file * filp, char __user *buff, size_t count, loff_t *f_pos) {
int i = count / 3 ;
int *ptr = NULL ;
char *buff_ptr = buff ;
ssize_t retval = count ;
unsigned int color = 0 ;
unsigned char rgb = 0xff ;

ptr = (int *)driver_addr_virt + (0x4000) ;
printk("Reading...%d", count) ;
while(i--) {
//color = ioread32(ptr++) ;
color = __raw_readl(ptr++) ;
rgb = color ;
copy_to_user(buff_ptr++, &rgb, 1) ;
rgb = (color>>8) ;
copy_to_user(buff_ptr++, &rgb, 1) ;
rgb = (color>>16) ;
copy_to_user(buff_ptr++, &rgb, 1) ;
}
printk("Done\n") ;
return retval ;
}

初始函數如下:
代碼: [選擇]
int __init MyDriver_init(void) {
int result ;

if(DRIVER_MAJOR) {
result = register_chrdev_region(driver_dev, DRIVER_NUMBER, DRIVER_NAME) ;
}
else {
result = alloc_chrdev_region(&driver_dev, DRIVER_MINOR, DRIVER_NUMBER, DRIVER_NAME) ;
DRIVER_MAJOR = MAJOR(driver_dev) ;
}
if( result<0 ) {
printk(KERN_ERR "Cannot get major %d!\n",DRIVER_MAJOR) ;
return result ;
}

driver_cdev = cdev_alloc() ;
if(driver_cdev != NULL) {
cdev_init(driver_cdev, &driver_fops) ;
driver_cdev->ops = &driver_fops ;
driver_cdev->owner = THIS_MODULE ;
if(cdev_add(driver_cdev, driver_dev, DRIVER_NUMBER))
printk(KERN_NOTICE "Someting wrong when adding MyDriver!\n") ;
else
printk("Success adding MyDriver!\n") ;
}
else {
printk(KERN_ERR "Register MyDriver error!\n") ;
return -1 ;
}

if(!request_mem_region(PHYS_ADDR, SIZE_OF_DEVICE*4, DRIVER_NAME))
{
printk(KERN_ERR "MyDriver: IO %X is not free.\n", PHYS_ADDR);
return -EBUSY;
}

driver_addr_virt = ioremap(PHYS_ADDR, SIZE_OF_DEVICE*4 );
if (!driver_addr_virt) {
printk (KERN_ERR "MyDriver: ioremap failed.\n");
iounmap(driver_addr_virt);
return -EINVAL;
}

return 0;
}

相關的定義常數與變數如下:
代碼: [選擇]
#define PHYS_ADDR 0x1CB20000
#define SIZE_OF_BUFFER (3 * 64 * 64)
#define SIZE_OF_DEVICE (0x4000*32)
#define DRIVER_NAME "MyDriver"

int DRIVER_MAJOR = 0 ;
int DRIVER_MINOR = 0 ;
int DRIVER_NUMBER = 1 ;

我曾試著把讀取函數裡的rgb變數填入固定值(0x00或0xff)後輸出
在AP讀取裝置時可以讀到正確的對應值
我層想過是否是color = __raw_readl(ptr++) ;這段敘述有錯誤
但試過color = ioread32(ptr++) ;一樣不行
因此想請教有經驗的板友指教錯誤的地方
謝謝