新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > S5PV210(TQ210)學習筆記——Nand flash驅動編寫

        S5PV210(TQ210)學習筆記——Nand flash驅動編寫

        作者: 時間:2016-11-28 來源:網絡 收藏
        跟裸機程序一樣,S5PV210Nand flash模塊跟S3C2440的Nand flash模塊非常相似,如果不引入ECC,驅動程序的編寫也非常簡單,具體的分析及編寫過程強烈推薦觀看韋東山老師的視頻教程,我是使用的Linux-3.8.6(Linux-3.8.3也一樣)內核,驅動的API函數有些變化,不過原理是相通的,稍微看一下內核源碼并參考下其他平臺的相關代碼就可以自己寫出Nand flash驅動了,下面是Nand flash驅動的源碼,沒有啟用ECC,當然,你也可以改成軟件ECC,但是我的覺得既然軟件ECC不如HWECC快,我就采用硬件ECC吧,我會在下篇文章中加入HWECC。
        1. #include
        2. #include
        3. #include
        4. #include
        5. #include
        6. #include
        7. #include
        8. #include
        9. structs5p_nand_regs{
        10. unsignedlongnfconf;
        11. unsignedlongnfcont;
        12. unsignedlongnfcmmd;
        13. unsignedlongnfaddr;
        14. unsignedlongnfdata;
        15. unsignedlongnfmeccd0;
        16. unsignedlongnfmeccd1;
        17. unsignedlongnfseccd;
        18. unsignedlongnfsblk;
        19. unsignedlongnfeblk;
        20. unsignedlongnfstat;
        21. unsignedlongnfeccerr0;
        22. unsignedlongnfeccerr1;
        23. unsignedlongnfmecc0;
        24. unsignedlongnfmecc1;
        25. unsignedlongnfsecc;
        26. unsignedlongnfmlcbitpt;
        27. };
        28. structs5p_nand_ecc{
        29. unsignedlongnfeccconf;
        30. unsignedlongnfecccont;
        31. unsignedlongnfeccstat;
        32. unsignedlongnfeccsecstat;
        33. unsignedlongnfeccprgecc0;
        34. unsignedlongnfeccprgecc1;
        35. unsignedlongnfeccprgecc2;
        36. unsignedlongnfeccprgecc3;
        37. unsignedlongnfeccprgecc4;
        38. unsignedlongnfeccprgecc5;
        39. unsignedlongnfeccprgecc6;
        40. unsignedlongnfeccerl0;
        41. unsignedlongnfeccerl1;
        42. unsignedlongnfeccerl2;
        43. unsignedlongnfeccerl3;
        44. unsignedlongnfeccerl4;
        45. unsignedlongnfeccerl5;
        46. unsignedlongnfeccerl6;
        47. unsignedlongnfeccerl7;
        48. unsignedlongnfeccerp0;
        49. unsignedlongnfeccerp1;
        50. unsignedlongnfeccerp2;
        51. unsignedlongnfeccerp3;
        52. unsignedlongnfeccconecc0;
        53. unsignedlongnfeccconecc1;
        54. unsignedlongnfeccconecc2;
        55. unsignedlongnfeccconecc3;
        56. unsignedlongnfeccconecc4;
        57. unsignedlongnfeccconecc5;
        58. unsignedlongnfeccconecc6;
        59. };
        60. staticstructnand_chip*nand_chip;
        61. staticstructmtd_info*s5p_mtd_info;
        62. staticstructs5p_nand_regs*s5p_nand_regs;
        63. staticstructs5p_nand_ecc*s5p_nand_ecc;
        64. staticstructclk*s5p_nand_clk;
        65. staticstructmtd_partitions5p_nand_partions[]={
        66. [0]={
        67. .name="bootloader",
        68. .offset=0,
        69. .size=SZ_1M,
        70. },
        71. [1]={
        72. .name="kernel",
        73. .offset=MTDPART_OFS_APPEND,
        74. .size=5*SZ_1M,
        75. },
        76. [2]={
        77. .name="rootfs",
        78. .offset=MTDPART_OFS_APPEND,
        79. .size=MTDPART_SIZ_FULL,
        80. },
        81. };
        82. staticvoids5p_nand_select_chip(structmtd_info*mtd,intchipnr){
        83. if(chipnr==-1){
        84. s5p_nand_regs->nfcont|=(1<<1);
        85. }
        86. else{
        87. s5p_nand_regs->nfcont&=~(1<<1);
        88. }
        89. }
        90. staticvoids5p_nand_cmd_ctrl(structmtd_info*mtd,intcmd,unsignedintctrl)
        91. {
        92. if(ctrl&NAND_CLE){
        93. s5p_nand_regs->nfcmmd=cmd;
        94. }
        95. else{
        96. s5p_nand_regs->nfaddr=cmd;
        97. }
        98. }
        99. staticints5p_nand_ready(structmtd_info*mtd){
        100. return(s5p_nand_regs->nfstat&0x1);
        101. }
        102. staticints5p_nand_probe(structplatform_device*pdev){
        103. intret=0;
        104. structresource*mem;
        105. //硬件部分初始化
        106. mem=platform_get_resource(pdev,IORESOURCE_MEM,0);
        107. if(!mem){
        108. dev_err(&pdev->dev,"cantgetI/Oresourcemem");
        109. return-ENXIO;
        110. }
        111. s5p_nand_regs=(structs5p_nand_regs*)ioremap(mem->start,resource_size(mem));
        112. if(s5p_nand_regs==NULL){
        113. dev_err(&pdev->dev,"ioremapfailed");
        114. ret=-EIO;
        115. gotoerr_exit;
        116. }
        117. s5p_nand_ecc=(structs5p_nand_ecc*)ioremap(0xB0E20000,sizeof(structs5p_nand_ecc));
        118. if(s5p_nand_ecc==NULL){
        119. dev_err(&pdev->dev,"ioremapfailed");
        120. ret=-EIO;
        121. gotoerr_iounmap;
        122. }
        123. s5p_nand_clk=clk_get(&pdev->dev,"nand");
        124. if(s5p_nand_clk==NULL){
        125. dev_dbg(&pdev->dev,"getclkfailed");
        126. ret=-ENODEV;
        127. gotoerr_iounmap;
        128. }
        129. clk_enable(s5p_nand_clk);
        130. s5p_nand_regs->nfconf=(3<<12)|(5<<8)|(3<<4)|(1<<1);
        131. s5p_nand_regs->nfcont|=3;
        132. //分配驅動相關結構體
        133. nand_chip=(structnand_chip*)kzalloc(sizeof(structnand_chip),GFP_KERNEL);
        134. if(nand_chip==NULL){
        135. dev_err(&pdev->dev,"failedtoallocatenand_chipstructure");
        136. ret=-ENOMEM;
        137. gotoerr_clk_put;
        138. }
        139. s5p_mtd_info=(structmtd_info*)kzalloc(sizeof(structmtd_info),GFP_KERNEL);
        140. if(s5p_mtd_info==NULL){
        141. dev_err(&pdev->dev,"failedtoallocatemtd_infostructure");
        142. ret=-ENOMEM;
        143. gotoerr_free_chip;
        144. }
        145. //設置驅動相關結構體
        146. nand_chip->select_chip=s5p_nand_select_chip;
        147. nand_chip->cmd_ctrl=s5p_nand_cmd_ctrl;
        148. nand_chip->IO_ADDR_R=&s5p_nand_regs->nfdata;
        149. nand_chip->IO_ADDR_W=&s5p_nand_regs->nfdata;
        150. nand_chip->dev_ready=s5p_nand_ready;
        151. nand_chip->ecc.mode=NAND_ECC_SOFT;
        152. s5p_mtd_info->priv=nand_chip;
        153. s5p_mtd_info->owner=THIS_MODULE;
        154. //掃描Nandflash設備
        155. if(nand_scan(s5p_mtd_info,1)){
        156. dev_dbg(&pdev->dev,"nandscanerror");
        157. gotoerr_free_info;
        158. }
        159. //添加分區信息
        160. ret=mtd_device_parse_register(s5p_mtd_info,NULL,NULL,s5p_nand_partions,ARRAY_SIZE(s5p_nand_partions));
        161. if(!ret)
        162. return0;
        163. err_free_info:
        164. kfree(s5p_mtd_info);
        165. err_free_chip:
        166. kfree(nand_chip);
        167. err_clk_put:
        168. clk_disable(s5p_nand_clk);
        169. clk_put(s5p_nand_clk);
        170. err_iounmap:
        171. //if(s5p_nand_ecc==NULL)
        172. //iounmap(s5p_nand_ecc);
        173. if(s5p_nand_regs==NULL)
        174. iounmap(s5p_nand_regs);
        175. err_exit:
        176. returnret;
        177. }
        178. staticints5p_nand_remove(structplatform_device*pdev){
        179. nand_release(s5p_mtd_info);
        180. kfree(s5p_mtd_info);
        181. kfree(nand_chip);
        182. clk_disable(s5p_nand_clk);
        183. clk_put(s5p_nand_clk);
        184. if(s5p_nand_regs==NULL)
        185. iounmap(s5p_nand_regs);
        186. return0;
        187. }
        188. staticstructplatform_drivers5p_nand_drv={
        189. .driver={
        190. .owner=THIS_MODULE,
        191. .name="s5p-nand",
        192. },
        193. .probe=s5p_nand_probe,
        194. .remove=s5p_nand_remove,
        195. };
        196. module_platform_driver(s5p_nand_drv);
        197. MODULE_LICENSE("GPL");

        源碼都在上面,具體的原理還是參考視頻或者其他資料,這里就不多說了,如果有任何問題,歡迎留言討論。

        本文引用地址:http://www.104case.com/article/201611/322812.htm


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 新郑市| 合江县| 鹿泉市| 铅山县| 西林县| 山阴县| 图片| 信丰县| 天津市| 抚顺市| 临沭县| 恩平市| 海南省| 望城县| 新兴县| 工布江达县| 莱州市| 高陵县| 井冈山市| 广德县| 娄烦县| 青铜峡市| 大竹县| 南汇区| 乌鲁木齐市| 阿勒泰市| 高雄县| 吴川市| 古交市| 义马市| 东城区| 朝阳县| 确山县| 雷波县| 富阳市| 义马市| 乐安县| 井冈山市| 广德县| 安义县| 界首市|