日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux创建线程读取双口数据,linux环境下读写一次双口ram尽然要十几个毫秒。(附驱动代码)...

發布時間:2025/4/16 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux创建线程读取双口数据,linux环境下读写一次双口ram尽然要十几个毫秒。(附驱动代码)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

linux環境下讀寫一次雙口ram盡然要十幾個毫秒。(附驅動代碼)

我用的雙口ram是IDT70V28,手冊上說的讀寫時間應該是幾個納秒,我寫了個linux驅動,然后做測試,發現讀寫一次的時間盡然是十幾個到幾十個毫秒!(通過點IO管腳,用示波器看),而且不能在多個線程訪問雙口ram(訪問不同的地址都不行!)。并且讀寫數據的時間基本和讀寫數據的長度沒有太多關系,只是和讀寫次數關系非常明顯。

搞了兩個星期,也沒有找到問題,請高人指點!謝謝幫忙

//以下為驅動程序全文

#include

#include

#include

#include?//必須

#include

#include

#undef?DPRINTK???????????????????????????????/*?undef?it,?just?in?case?*/

#ifdef?SDRAM_DEBUG

/*?This?one?if?debugging?is?on,?and?kernel?space?*/

#define?DPRINTK(fmt,?args...)?printk("can:?"fmt,?##?args)

#else

#define?DPRINTK(fmt,?args...)?/*?not?debugging:?nothing?*/

#endif

//定義雙口RAM字符設備結構

typedef?struct?_sdram_dev

{

struct?cdev?chrdev;

unsigned?short?*?data_addr;??????????????????//數據口

unsigned?int?data_max;

unsigned?int?user_idx;

}sdram_dev,*sdram_dev_t;

//全局變量,常量;

static?int?sdram_major=0;

static?struct?class*?sdram_class;

unsigned?int?SDRAM_offset=0;

#define?DSDRAM_NAME?????????????"double_sdram"

#define?DATA_EBI_BASE_ADDRESS???(0x20000000)

#define?ADDR_SDRAM_SIZE?????????(128*1024)

//SDRAM設備指針

static?sdram_dev_t?DSdram_dev;

//設備指針

static?struct?platform_device*?DSdram_devices?=?NULL;

//BANK配置

void?init_bank_board(void)

{

//bank?2?is?set?to?16-bit

__raw_writel(0x1000ffef,SMCBCR2);

DPRINTK("GPIO_AINTTYPE1=0x%xrn",__raw_readl(GPIO_AINTTYPE1));

DPRINTK("GPIO_AINTTYPE2=0x%xrn",__raw_readl(GPIO_AINTTYPE2));

}

//**********************************************************

//ioctl函數:

//**********************************************************

static?int?dsdram_ioctl(struct?inode?*inode,?struct?file?*file,unsigned?int?cmd,?unsigned?long?arg)

{

SDRAM_offset=arg;

//printk("Set?Offset?:0x%x?rn",SDRAM_offset);

return?0;

}

//write函數

static?ssize_t?dsdram_write(struct?file*?file,?const?char?*buffer,?size_t?length,loff_t*?loff)

{

unsigned?short?*data_addr?=?NULL;

if?(length?>?ADDR_SDRAM_SIZE)?{

printk("Reading?more?than?128K?bytes?data,?this?is?not?supported.n");

printk("Defaulting?to?128K?bytes?data.n");

length?=?ADDR_SDRAM_SIZE;

}

//length?=?length/2;

data_addr?=?(DSdram_dev->data_addr)+SDRAM_offset;

if(copy_from_user(data_addr,?(unsigned?short?*)buffer,?length))

return?-EFAULT;

SDRAM_offset=0;

return?(length);

}

//讀函數

ssize_t?dsdram_read(struct?file?*file,?char?*buffer,?size_t?length,?loff_t?*offset)

{

unsigned?short?*data_addr?=?NULL;

if?(length?>?ADDR_SDRAM_SIZE)?{

printk("Reading?more?than?128K?bytes?data,?this?is?not?supported.n");

printk("Defaulting?to?128K?bytes?data.n");

length?=?ADDR_SDRAM_SIZE;

}

//length?=?length/2;

data_addr?=?(DSdram_dev->data_addr)+SDRAM_offset;

if(copy_to_user((unsigned?short?*)buffer,?data_addr,?length))

return?-EFAULT;

SDRAM_offset=0;

return?(length);

}

//open?函數

static?int?dsdram_open(struct?inode?*inode,?struct?file?*file)

{

sdram_dev_t?hdev?=?NULL;

hdev?=?DSdram_dev;

if(++hdev->user_idx?==?1)

{

//申請內存區域,以檢測該地址空間是否被使用;

if?(!request_mem_region(DATA_EBI_BASE_ADDRESS,ADDR_SDRAM_SIZE,DSDRAM_NAME))

printk("Error?request?mem?address?for?0x20000000?!?rn");

hdev->data_addr?=?(unsigned?short*)ioremap(DATA_EBI_BASE_ADDRESS,ADDR_SDRAM_SIZE);

hdev->data_max??=?ADDR_SDRAM_SIZE;

}

DPRINTK("open?succeednr");

return?0;

}

//release函數

static?int??dsdram_release(struct?inode?*inode,?struct?file?*file)

{

sdram_dev_t?hdev=NULL;

hdev?=?DSdram_dev;

if(--hdev->user_idx?==?0)

{

//取消內存區域映射;

iounmap((unsigned?short?*)hdev->data_addr);

//釋放申請的內存區域;

release_mem_region(DATA_EBI_BASE_ADDRESS,ADDR_SDRAM_SIZE);

}

return?0;

}

//文件操作函數結構

struct?file_operations?dsdram_fops=

{

.owner??????=???THIS_MODULE,

.read???????=???dsdram_read,

.write??????=???dsdram_write,

.ioctl??????=?dsdram_ioctl,

.open???????=???dsdram_open,

.release????=???dsdram_release,

};

//系統探測函數

static?int?__devinit?dsdram_probe(struct?platform_device?*pdev)

{

int?ret;

dev_t?dev_id;

struct?class_device*?cls_sdram_dev;

sdram_dev_t?hdev;

printk("device?%s-%d?detected!n",?pdev->name,?pdev->id);

//config?gpio?and?bank

init_bank_board();

DSdram_dev?=?hdev?=?kmalloc(sizeof(sdram_dev),?GFP_KERNEL);

dev_id?=?MKDEV(sdram_major,?0);

pdev->dev.devt?=?dev_id;

cdev_init(&hdev->chrdev,?&dsdram_fops);

hdev->chrdev.owner?=?THIS_MODULE;

hdev->user_idx?=?0;

ret?=?cdev_add(&hdev->chrdev,?dev_id,?1);

if?(ret)

{

printk("fail?to?register?driver?for?"?DSDRAM_NAME?"%d!n",?pdev->id);

return?ret;

}

platform_set_drvdata(pdev,?hdev);

cls_sdram_dev?=?class_device_create(sdram_class,NULL,dev_id,&pdev->dev,

DSDRAM_NAME);

if?(IS_ERR(cls_sdram_dev))

return?PTR_ERR(cls_sdram_dev);

printk("driver?for?"DSDRAM_NAME"?registeredn");

return?ret;

}

static?int?__devexit?dsdram_remove(struct?platform_device?*pdev)

{

sdram_dev_t?hdev;

class_device_destroy(sdram_class,?pdev->dev.devt);

hdev?=?platform_get_drvdata(pdev);

if?(hdev)

{

cdev_del(&hdev->chrdev);

kfree(hdev);

}

platform_set_drvdata(pdev,?NULL);

pdev->dev.devt?=?0;

printk(DSDRAM_NAME?"removed!n");

return?0;

}

#ifdef?CONFIG_PM

static?int?dsdram_suspend(struct?platform_device?*pdev,?pm_message_t?state)

{

return?0;

}

static?int?dsdram_resume(struct?platform_device?*pdev)

{

return?0;

}

#else

#define?dsdram_suspend?NULL

#define?dsdram_resume?NULL

#endif

static?struct?platform_driver?dsdram_driver?=

{

.probe??????=?dsdram_probe,

.remove?????=?__devexit_p(dsdram_remove),

#ifdef?CONFIG_PM

.suspend????=?dsdram_suspend,

.resume?????=?dsdram_resume,

#endif

.driver?????=

{

.name???=?DSDRAM_NAME,

.owner??=?THIS_MODULE,

},

};

//*********************************************************

//初始化模塊函數;

//*********************************************************

static?int?__init?dousdram_init_module(void)

{

int?ret;

dev_t?dev?=?MKDEV(sdram_major,?0);

DSdram_devices?=?platform_device_alloc(DSDRAM_NAME,?0);

if?(!DSdram_devices)

return?-ENOMEM;

ret?=?platform_device_add(DSdram_devices);

if?(ret

您可能感興趣的文章:

總結

以上是生活随笔為你收集整理的Linux创建线程读取双口数据,linux环境下读写一次双口ram尽然要十几个毫秒。(附驱动代码)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。