您的位置: 凉山信息网 > 体育

S5PV210之Nandflash驅動編

发布时间:2019-11-08 22:42:42

S5PV210之Nand flash驱动编写

大家好,又到了天嵌【嵌入式分享】的时间,相对于前几期【嵌入式分享】做的主要是TQ335X开发板的技术分享,本期决定做同是cortex-a8系列的TQ210开发板的技术分享本期是关于TQ210开发板的Nand flash驱动编写,可能源码部分会比较多,本文由博主girlkoo编写,感谢他的分享 跟裸机程序一样,S5PV210(TQ210)的Nand flash模块跟S3C2440(TQ2440)的Nand flash模块非常相似,如果不引入ECC,驱动程序的编写也非常简单,我是使用的Linux-3.8.6(Linux-3.8.3也一样)内核,驱动的API函数有些变化,不过原理是相通的,稍微看一下内核源码并参考下其他平台的相关代码就可以自己写出Nand flash驱动了,下面是Nand flash驱动的源码,没有启用ECC,当然,你也可以改成软件ECC,但是我的觉得既然软件ECC不如HWECC快,我就采用硬件ECC吧#include #include #include #include #include #include #include #include struct s5p_nand_regs{ unsigned long nfconf; unsigned long nfcont; unsigned long nfcmmd; unsigned long nfaddr; unsigned long nfdata; unsigned long nfmeccd0; unsigned long nfmeccd1; unsigned long nfseccd; unsigned long nfsblk; unsigned long nfeblk; unsigned long nfstat; unsigned long nfeccerr0; unsigned long nfeccerr1; unsigned long nfmecc0; unsigned long nfmecc1; unsigned long nfsecc; unsigned long nfmlcbitpt;};struct s5p_nand_ecc{ unsigned long nfeccconf; unsigned long nfecccont; unsigned long nfeccstat; unsigned long nfeccsecstat; unsigned long nfeccprgecc0; unsigned long nfeccprgecc1; unsigned long nfeccprgecc2; unsigned long nfeccprgecc3; unsigned long nfeccprgecc4; unsigned long nfeccprgecc5; unsigned long nfeccprgecc6; unsigned long nfeccerl0; unsigned long nfeccerl1; unsigned long nfeccerl2; unsigned long nfeccerl3; unsigned long nfeccerl4; unsigned long nfeccerl5; unsigned long nfeccerl6; unsigned long nfeccerl7; unsigned long nfeccerp0; unsigned long nfeccerp1; unsigned long nfeccerp2; unsigned long nfeccerp3; unsigned long nfeccconecc0; unsigned long nfeccconecc1; unsigned long nfeccconecc2; unsigned long nfeccconecc3; unsigned long nfeccconecc4; unsigned long nfeccconecc5; unsigned long nfeccconecc6;};static struct nand_chip *nand_chip;static struct mtd_info *s5p_mtd_info;static struct s5p_nand_regs *s5p_nand_regs;static struct s5p_nand_ecc*s5p_nand_ecc;static struct clk *s5p_nand_clk;static struct mtd_partition s5p_nand_partions[] = { [0] = { .name = bootloader , .offset = 0, .size = SZ_1M, }, [1] = { .name = kernel , .offset = MTDPART_OFS_APPEND, .size = 5*SZ_1M, }, [2] = { .name = rootfs , .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL, },};static void s5p_nand_select_chip(struct mtd_info *mtd, int chipnr){ if(chipnr == -1){ s5p_nand_regs- nfcont |= (1 1); } else{ s5p_nand_regs- nfcont = ~(1 1); }}static void s5p_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl){ if (ctrl NAND_CLE){ s5p_nand_regs- nfcmmd = cmd; } else{ s5p_nand_regs- nfaddr = cmd; }}static int s5p_nand_ready(struct mtd_info *mtd){ return (s5p_nand_regs- nfstat 0x1);}static int s5p_nand_probe(struct platform_device *pdev){ int ret = 0; struct resource *mem; //硬件部分初始化 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err( pdev- dev, can't get I/O resource mem\n return -ENXIO; } s5p_nand_regs = (struct s5p_nand_regs *)ioremap(mem- start, resource_size(mem)); if (s5p_nand_regs == NULL) { dev_err( pdev- dev, ioremap failed\n ret = -EIO; goto err_exit; } s5p_nand_ecc = (struct s5p_nand_ecc *)ioremap(0xB0E20000, sizeof(struct s5p_nand_ecc)); if(s5p_nand_ecc == NULL){ dev_err( pdev- dev, ioremap failed\n ret = -EIO; goto err_iounmap; } s5p_nand_clk = clk_get( pdev- dev, nand if(s5p_nand_clk == NULL){ dev_dbg( pdev- dev, get clk failed\n ret = -ENODEV; goto err_iounmap; } clk_enable(s5p_nand_clk); s5p_nand_regs- nfconf = (3 12)|(5 8)|(3 4)|(1 1); s5p_nand_regs- nfcont |= 3; //分配驱动相关结构体 nand_chip = (struct nand_chip *)kzalloc(sizeof(struct nand_chip), GFP_KERNEL); if(nand_chip == NULL){ dev_err( pdev- dev, failed to allocate nand_chip structure\n ret = -ENOMEM; goto err_clk_put; } s5p_mtd_info = (struct mtd_info *)kzalloc(sizeof(struct mtd_info), GFP_KERNEL); if(s5p_mtd_info == NULL){ dev_err( pdev- dev, failed to allocate mtd_info structure\n ret = -ENOMEM; goto err_free_chip; } //设置驱动相关结构体 nand_chip- select_chip = s5p_nand_select_chip; nand_chip- cmd_ctrl = s5p_nand_cmd_ctrl; nand_chip- IO_ADDR_R = s5p_nand_regs- nfdata; nand_chip- IO_ADDR_W = s5p_nand_regs- nfdata; nand_chip- dev_ready = s5p_nand_ready; nand_chip- de = NAND_ECC_SOFT; s5p_mtd_info- priv = nand_chip; s5p_mtd_info- owner = THIS_MODULE; //扫描Nand flash 设备 if(nand_scan(s5p_mtd_info, 1)){ dev_dbg( pdev- dev, nand scan error\n goto err_free_info; } //添加分区信息 ret = mtd_device_parse_register(s5p_mtd_info, NULL, NULL, s5p_nand_partions, ARRAY_SIZE(s5p_nand_partions)); if(!ret) return 0;err_free_info: kfree(s5p_mtd_info);err_free_chip: kfree(nand_chip);err_clk_put: clk_disable(s5p_nand_clk); clk_put(s5p_nand_clk);err_iounmap: //if(s5p_nand_ecc == NULL) //iounmap(s5p_nand_ecc); if(s5p_nand_regs == NULL) iounmap(s5p_nand_regs);err_exit: return ret;}static int s5p_nand_remove(struct platform_device *pdev){ nand_release(s5p_mtd_info); kfree(s5p_mtd_info); kfree(nand_chip); clk_disable(s5p_nand_clk); clk_put(s5p_nand_clk); if(s5p_nand_regs == NULL) iounmap(s5p_nand_regs); return 0;}static struct platform_driver s5p_nand_drv = { .driver = { .owner = THIS_MODULE, .name = s5p-nand , }, .probe = s5p_nand_probe, .remove = s5p_nand_remove,};module_platform_driver(s5p_nand_drv);MODULE_LICENSE( GPL

上述源码为嵌入式爱好者分享,如有更新,请咨询相关客服与销售人员,以便更新与开发 操作所使用的硬件: TQ210V6开发板

肚子痛拉肚子快速止泻
什么咳嗽药不含麻黄
什么药治疗心律不齐效果好
猜你会喜欢的
猜你会喜欢的