NAND FLASH操作学习笔记

首先是几个C语言的学习点。

1.利用一个函数结构体,来保存某一类的函数首地址,一个很好的编程技巧,可以使程序可读性增加。做法是:

typedef struct {
    void (*nand_reset)(void);
    void (*wait_idle)(void);
    void (*nand_select_chip)(void);
    void (*nand_deselect_chip)(void);
    void (*write_cmd)(int cmd);
    void (*write_addr)(unsigned int addr);
    unsigned char (*read_data)(void);
}t_nand_chip;

t_nand_chip nand_chip;

nand_chip.nand_reset=2440_nand_reset;

这里的结构体成员全都是函数指针,函数指针,顾名思义就是保存函数首地址的指针,可以直接将一个函数名赋值给这个指针。当要调用这个函数时,可以直接像调用函数一样。

nand_chip.nand_reset();     注意:这里其实存在着编译器的优化,正确的写法应该是

nand_chip.(*nand_reset)();   nand_reset只是一个指针,它保存的内容才是函数的首地址,但是编译器在这里做了优化,可以使我们代码编写简单,而且好理解。

2.

typedef struct {
    S3C24X0_REG32   NFCONF;
    S3C24X0_REG32   NFCMD;
    S3C24X0_REG32   NFADDR;
    S3C24X0_REG32   NFDATA;
    S3C24X0_REG32   NFSTAT;
    S3C24X0_REG32   NFECC;
} S3C2410_NAND;

static S3C2410_NAND * s3c2410nand = (S3C2410_NAND *)0x4e000000;

这句话理解了半天,终于想明白了。

关键就在于并没有创建一个新的结构体,而是巧妙的利用了定义结构体的性质。s3c2410这个指针指向的结构体首地址就是0x4e000000,它是NAND寄存器的首地址。它巧妙的把原来已经存在的寄存器组当成了一个结构体,结构体内部的变量都是4字节递增,正好对应每个寄存器的地址。那么需要对这个某个寄存器赋值的时候。

volatile unsigned char *p = (volatile unsigned char *) &s3c2410nand->NFSTAT;

这里的p指针指向的是一个char型空间,所以后面要做强制类型转换。注意这里一定不能忘了取地址符&,它才表示这个寄存器的地址。

还有就是在对寄存器操作的时候,最好都用volatile修饰符,不然编译器可能会对其进行优化。程序中某些处函数没有使用,个人觉得最好也使用一下。

发布了13 篇原创文章 · 获赞 0 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章