亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 5080 | 回復(fù): 3
打印 上一主題 下一主題

linux環(huán)境下讀寫一次雙口ram盡然要十幾個(gè)毫秒。(附驅(qū)動(dòng)代碼) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2008-04-29 21:59 |只看該作者 |倒序?yàn)g覽
20可用積分
linux環(huán)境下讀寫一次雙口ram盡然要十幾個(gè)毫秒。(附驅(qū)動(dòng)代碼)
我用的雙口ram是IDT70V28,手冊(cè)上說(shuō)的讀寫時(shí)間應(yīng)該是幾個(gè)納秒,我寫了個(gè)linux驅(qū)動(dòng),然后做測(cè)試,發(fā)現(xiàn)讀寫一次的時(shí)間盡然是十幾個(gè)到幾
十個(gè)毫秒。ㄍㄟ^(guò)點(diǎn)IO管腳,用示波器看),而且不能在多個(gè)線程訪問(wèn)雙口ram(訪問(wèn)不同的地址都不行!)。并且讀寫數(shù)據(jù)的時(shí)間基本和讀寫
數(shù)據(jù)的長(zhǎng)度沒(méi)有太多關(guān)系,只是和讀寫次數(shù)關(guān)系非常明顯。
搞了兩個(gè)星期,也沒(méi)有找到問(wèn)題,請(qǐng)高人指點(diǎn)!謝謝幫忙
//以下為驅(qū)動(dòng)程序全文
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <asm/arch/hardware.h>    //必須
#include <asm/io.h>
#include <asm/irq.h>  
#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字符設(shè)備結(jié)構(gòu)
typedef struct _sdram_dev
{
    struct cdev chrdev;
    unsigned short * data_addr;                  //數(shù)據(jù)口
    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設(shè)備指針
static sdram_dev_t DSdram_dev;
//設(shè)備指針
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%x\r\n",__raw_readl(GPIO_AINTTYPE1));
    DPRINTK("GPIO_AINTTYPE2=0x%x\r\n",__raw_readl(GPIO_AINTTYPE2));
      
}
//**********************************************************
//ioctl函數(shù):
//**********************************************************
static int dsdram_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)
{
  
SDRAM_offset=arg;
//printk("Set Offset :0x%x \r\n",SDRAM_offset);

return 0;
}
//write函數(shù)
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);
              
}

//讀函數(shù)
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 函數(shù)
static int dsdram_open(struct inode *inode, struct file *file)
{
    sdram_dev_t hdev = NULL;
    hdev = DSdram_dev;
    if(++hdev->user_idx == 1)
    {
   
     //申請(qǐng)內(nèi)存區(qū)域,以檢測(cè)該地址空間是否被使用;
        if (!request_mem_region(DATA_EBI_BASE_ADDRESS,ADDR_SDRAM_SIZE,DSDRAM_NAME))
            printk("Error request mem address for 0x20000000 ! \r\n");   
   
     hdev->data_addr = (unsigned short*)ioremap(DATA_EBI_BASE_ADDRESS,ADDR_SDRAM_SIZE);
     hdev->data_max  = ADDR_SDRAM_SIZE;  
    }
    DPRINTK("open succeed\n\r");
return 0;
}
//release函數(shù)
static int  dsdram_release(struct inode *inode, struct file *file)
{
    sdram_dev_t hdev=NULL;
    hdev = DSdram_dev;
    if(--hdev->user_idx == 0)
    {
        //取消內(nèi)存區(qū)域映射;
        iounmap((unsigned short *)hdev->data_addr);

        //釋放申請(qǐng)的內(nèi)存區(qū)域;
        release_mem_region(DATA_EBI_BASE_ADDRESS,ADDR_SDRAM_SIZE);      
    }
   
return 0;
}
//文件操作函數(shù)結(jié)構(gòu)
struct file_operations dsdram_fops=
{
.owner      =   THIS_MODULE,
.read       =   dsdram_read,
.write      =   dsdram_write,
.ioctl     =  dsdram_ioctl,
.open       =   dsdram_open,
.release    =   dsdram_release,
};
//系統(tǒng)探測(cè)函數(shù)
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" registered\n");
    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,  
    },
};

//*********************************************************
//初始化模塊函數(shù);
//*********************************************************
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 < 0) {
        platform_device_put(DSdram_devices);
        return ret;
    }
  
    /* Figure out our device number. */
    if (sdram_major)
        ret = register_chrdev_region(dev, 1, DSDRAM_NAME);
    else
    {
        ret = alloc_chrdev_region(&dev, 0, 1, DSDRAM_NAME);
        if (ret)
        {
            printk(KERN_WARNING "DSDRAM_MODULE_NAME: unable to get major %d\n", sdram_major);
            return ret;
  }
        sdram_major = MAJOR(dev);
    }
    //create class
    sdram_class = class_create(THIS_MODULE, DSDRAM_NAME);
    if (IS_ERR(sdram_class))
        return PTR_ERR(sdram_class);
    ret = platform_driver_register(&dsdram_driver);
    return ret;
}

//*********************************************************
//清除模塊函數(shù);
//*********************************************************
static void __exit dousdram_cleanup_module(void)
{
    platform_driver_unregister(&dsdram_driver);
    class_destroy(sdram_class);
    unregister_chrdev_region(MKDEV(sdram_major, 0), 1);
   
    platform_device_unregister(DSdram_devices);
    DPRINTK("unregister driver " DSDRAM_NAME "\n");
   
}
module_init(dousdram_init_module);
module_exit(dousdram_cleanup_module);
MODULE_LICENSE("GPL");

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2008-04-29 23:18 |只看該作者
可以在驅(qū)動(dòng)層實(shí)現(xiàn)mmap函數(shù),在應(yīng)用層獲得地址后直接對(duì)ram讀寫。

或者在內(nèi)核里面做一個(gè)緩沖區(qū),不要在讀寫時(shí)直接調(diào)用copy_XXX_user,拷貝到緩沖區(qū)后,調(diào)用io操作。

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2008-05-30 21:00 |只看該作者
70v28不是64K嗎?
用readw和writew試試,不用copy_from_user和copy_to_user

論壇徽章:
24
15-16賽季CBA聯(lián)賽之北京
日期:2018-08-17 18:43:33技術(shù)圖書徽章
日期:2018-08-22 12:53:57技術(shù)圖書徽章
日期:2018-08-22 12:54:20技術(shù)圖書徽章
日期:2018-08-22 12:54:3015-16賽季CBA聯(lián)賽之福建
日期:2018-10-19 16:58:1619周年集字徽章-慶
日期:2019-08-27 13:28:5619周年集字徽章-19
日期:2019-08-27 13:31:2619周年集字徽章-19
日期:2019-08-27 13:31:2615-16賽季CBA聯(lián)賽之同曦
日期:2019-09-05 12:03:2819周年集字徽章-周
日期:2019-09-06 18:54:5415-16賽季CBA聯(lián)賽之上海
日期:2018-07-25 11:55:2615-16賽季CBA聯(lián)賽之青島
日期:2018-07-10 14:13:18
4 [報(bào)告]
發(fā)表于 2008-06-05 16:26 |只看該作者
原帖由 zclever 于 2008-5-30 21:00 發(fā)表
70v28不是64K嗎?
用readw和writew試試,不用copy_from_user和copy_to_user

不是很明白, 為什么不能用 copy_xxx_user()這個(gè)函數(shù)的影響在哪里呢?
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP