zoukankan      html  css  js  c++  java
  • SD卡 驱动层测速

     init_timer(&timer1);
        timer1.function = test_time;
        timer1.data = 0;
        timer1.expires = jiffies + msecs_to_jiffies(1);
        add_timer(&timer1);
        sd_test(mmc);
        printk("count = %d 
    ",count);

    sd_test()函数写在probe函数中,但要等待sd初始化完毕才行,需要在上电时就插入SD卡,而不要等待系统起来之后。另外,如果mmc_rescan函数使用的工作队列实现的,那么它与probe就属于两个线程,会造成在执行sd_test时,sd卡还没初始化好,所以测试时不要用工作队列,直接调用就可以了。

    void test_time(void)
    {
        count++;
        mod_timer(&timer1,jiffies+msecs_to_jiffies(1));
    }
    

     计数方式,没1/HZ时间计数一次,HZ跟系统相关,我的是250HZ,精确度是0.004S,msecs_to_jiffies(x),x是指tick数,间断时间由tick数*精确度。系统的计数器是超时计数,使用mod_timer函数重启计数,并赋值新的值。

    void sd_test(struct mmc_host *mmc)
    {
    struct sepmmc_host *host = mmc_priv(mmc);
        reset_hardware(host);
            disable_any_int(host);
            clear_any_pending_int(host);
    
            sepmmc_start_command(host);
            init_completion(&host->cmd_complete_request);
            enable_command_done_int(host);
            wait_for_completion(&host->cmd_complete_request);
        printk("command transfer over
    ");
    
            init_completion(&host->data_complete_request);
            enable_data_transfer_over_int(host);
            wait_for_completion(&host->data_complete_request);
        printk("data transfer over
    ");
    //  dma_free_coherent(NULL, 0x2000, p ,bus_addr);
      //      if (!mrq->data->error && mrq->stop) {
      //        init_completion(&host->cmd_complete_request);
      //              enable_command_done_int(host);
      //              wait_for_completion(&host->cmd_complete_request);
      //      }
    
            host->mrq = NULL;
        if(host->cmd)
        kfree(host->cmd);
            host->cmd = NULL;
            host->data = NULL;
    
           // mmc_request_done(mmc, mrq);
    printk("------sd_test out------
    ");
    }
    
    void sepmmc_start_command(struct sepmmc_host *host)
    {
    struct mmc_command *cmd;
    unsigned int cmd_reg=0;
        dma_test(host->mmc);
        cmd = (struct mmc_command *)kmalloc(sizeof(struct mmc_command),GFP_KERNEL);
        printk("sepmmc_start_command into
    ");
        cmd->opcode = 18;
        cmd->arg = 0;
        cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
        cmd_reg |= cmd->opcode;
        if(cmd->flags & MMC_RSP_PRESENT)
        cmd_reg |= SDIO_CMD_RESP_EXPE(1);
        if(cmd->flags & MMC_RSP_136)
        cmd_reg |= SDIO_CMD_LONG_RESP(1);
        if(cmd->flags & MMC_RSP_CRC)
        cmd_reg |= SDIO_CMD_CHK_RESP_CRC(1);
    
        cmd_reg |= SDIO_CMD_HAVE_DAT_TRAN(1);
        cmd_reg |= SDIO_CMD_WAIT_DAT(1);
        cmd_reg |= SDIO_CMD_START;
        host->cmd = cmd;
        writel(0,SDIO1_CMDARG_V);
    //  writel(cmd_reg,SDIO1_CMD_V);
        writel(0x80002352,SDIO1_CMD_V);
        printk("sepmmc_start_command over
    ");
    }
    
    void dma_test(struct mmc_host *mmc)
    {
    struct sepmmc_host *host = mmc_priv(mmc);
    //struct sepmmc_dma_descriptor *descriptor_test[1];
    struct mmc_data *data;
    //dma_addr_t DESCRIPTOR_BASE_TEST[1];
    dma_addr_t bus_addr;
    int i = 0;
    char *p ;
        printk("------sd_test into------
    ");
    
        writel(512,SDIO1_BLKSIZ_V);   //block size 512
        writel(0x800000,SDIO1_BYTCNT_V);//8M
        data = (struct mmc_data*)kmalloc(sizeof(struct mmc_data),GFP_KERNEL);
        data->blksz = 512;
        data->blocks = 0x4000;
        data->flags = MMC_DATA_READ;
        data->stop = NULL;
        host->data = data;
    
        for(i = 0;i < 1024;i++)
            {
               descriptor_test[i]=dma_alloc_coherent(NULL, sizeof(struct sepmmc_dma_descriptor),&DESCRIPTOR_BASE_TEST[i], GFP_KERNEL);
           if(!descriptor_test[i])
                   printk("descriptor malloc err
    ");
        }
    //  p=dma_alloc_coherent(NULL,0x2000,&bus_addr,GFP_KERNEL);
    //  if(!p)
    //      printk("p malloc err
    ");
    //        descriptor_test[0]->des0 = 0x8000003c;
    //        descriptor_test[0]->des1 = 0x2000;
    //        descriptor_test[0]->des2 = bus_addr;
    //        descriptor_test[0]->des3 = 0;
    
        for(i=0;i<1024;i++)
        {
                if(i == 0)
                   descriptor_test[i]->des0 = 0x80000018;
                else if(i == 1023)
                   descriptor_test[i]->des0 = 0x80000034;
                else
                   descriptor_test[i]->des0 = 0x80000010;
            }
    
        p=dma_alloc_coherent(NULL,0x2000,&bus_addr,GFP_KERNEL);
        if(!p)
            printk("p malloc err
    ");
    
                for(i = 0;i<1024;i++)
                {
                       descriptor_test[i]->des1 = 0x2000;
                       descriptor_test[i]->des2 = bus_addr;
                }
    
                for(i = 0;i<1024;i++)
                {
                    if(i < 1023)
                    descriptor_test[i]->des3 = DESCRIPTOR_BASE_TEST[i+1];
                    else
                    descriptor_test[i]->des3 = 0;
                }
    
        writel(DESCRIPTOR_BASE_TEST[0],SDIO1_DBADDR_V);
            writel(0x82,SDIO1_BMOD_V);
        printk("dma init over
    ");
    }
    

     这边配置要注意,自己创建cmd 和 data函数,比如不需要stop命令,就使用data->stop = NULL;这些在中断处理函数中要用,主要的错误就出现在中断处理函数中。

    我使用的是内部DMA,与一般的外部DMA不一样,代码差距较大。

  • 相关阅读:
    Linux Time_wait网络状态 调优
    Linux 系统开启随机端口数量 调优
    Linux 跟踪连接netfilter 调优
    Linux 文件时间记录属性 调优
    Linux 默认线程栈大小 调优
    Linux 系统开启最大线程数 调优
    Linux 系统级开启文件句柄 调优
    Linux 进程级开启最大文件描述符 调优
    参数优化-偏差与方差
    决策树-回归
  • 原文地址:https://www.cnblogs.com/autum/p/cesu.html
Copyright © 2011-2022 走看看