norflash与mcu之间主要通过SPI接口进行通信。
norflash的初始化主要包括SPI接口的初始化、分区创建及初始化操作。
详细过程:
初始化norflash访问的SPI接口
根据名字创建分区,如果该名字分区已经存在,则不创建
如果创建分区时,空间不足,返回错误
创建新分区时,该分区与其他分区是否存在重叠
int _norflash_init(const char *name, struct norflash_dev_platform_data *pdata)
{
log_info("norflash_init ! %x %x", pdata->spi_cs_port, pdata->spi_read_width);
if (_norflash.spi_num == (int) - 1) {
_norflash.spi_num = pdata->spi_hw_num;
_norflash.spi_cs_io = pdata->spi_cs_port;
_norflash.spi_r_width = pdata->spi_read_width;
_norflash.flash_id = 0;
_norflash.flash_capacity = 0;
os_mutex_create(&_norflash.mutex);
_norflash.max_end_addr = 0;
_norflash.part_num = 0;
}
ASSERT(_norflash.spi_num == pdata->spi_hw_num);
ASSERT(_norflash.spi_cs_io == pdata->spi_cs_port);
ASSERT(_norflash.spi_r_width == pdata->spi_read_width);
struct norflash_partition *part;
part = norflash_find_part(name);
if (!part) {
part = norflash_new_part(name, pdata->start_addr, pdata->size);
ASSERT(part, "not enough norflash partition memory in array\n");
ASSERT(norflash_verify_part(part) == 0, "norflash partition %s overlaps\n", name);
log_info("norflash new partition %s\n", part->name);
} else {
ASSERT(0, "norflash partition name already exists\n");
}
return 0;
}
这里仅对指定name的分区进行了初始化操作。
norflash的打开操作首先判断是否被打开过,
没有被打开过,则需要进行SPI的初始化,
读取芯片的ID,通过芯片ID计算芯片的存储容量,
如果使能了缓存功能,则先从flash地址0处读4KB到缓存中,
将打开计数递增。
open函数主要是整个芯片的打开、初始化;init函数是分区的初始化。
int _norflash_open(void *arg)
{
int reg = 0;
os_mutex_pend(&_norflash.mutex, 0);
log_info("norflash open\n");
if (!_norflash.open_cnt) {
spi_cs_init();
spi_open(_norflash.spi_num);
_norflash.flash_id = _norflash_read_id();
log_info("norflash_read_id: 0x%x\n", _norflash.flash_id);
if ((_norflash.flash_id == 0) || (_norflash.flash_id == 0xffffff)) {
log_error("read norflash id error !\n");
reg = -ENODEV;
goto __exit;
}
_norflash.flash_capacity = 64 * _pow(2, (_norflash.flash_id & 0xff) - 0x10) * 1024;
log_info("norflash_capacity: 0x%x\n", _norflash.flash_capacity)