1. bread88lifa利发国际娱乐论坛/
  2. 嵌入式论坛/
    1. 电子论坛综合区
    2. 嵌入式论坛
    3. 电源技术论坛
    4. 硬件设计论坛
    5. 测试测量论坛
    6. 检测技术与质量
    7. EDA设计论坛
    8. 综合技术与应用
    9. 开源硬件
    10. IC设计论坛
    11. 消费电子论坛
    12. 无线通信论坛
    13. 个人版区
    14. 厂商专区
    15. 论坛服务区
    16. 高校联盟
    17. 供求信息发布
  3. 单片机/MCU论坛
    1. ARM技术论坛
    2. Android论坛
    3. Linux论坛
    4. MSP430技术论坛
    5. FPGA|CPLD|ASIC论坛
    6. STM32/STM8技术论坛
    7. NXP MCU 技术论坛
    8. PIC单片机论坛
    9. DSP论坛
    10. 瑞萨单片机论坛
    11. 嵌入式系统论坛
  4. / 原创,sam4s16c的片内flash读写
    关闭提示

[资料] 原创,sam4s16c的片内flash读写

[复制链接]
版主
发表于 2016-11-8 09:28:00   1282 查看 9 回复 只看该作者 倒序浏览
分享
本帖最后由 lee_st 于 2016-11-8 10:01 编辑

最近一直在玩sam4s16c,网上的所有论坛基本找不到atmel的资料,真心的不喜欢,但是工作需要,没办法。只能静下心来仔细研究Datasheet,别无他径。
内部flash的组织架构见下图

由图可知,flash是由很多的page组成,这个mcu的page size是512bits,而且,每个lock bit锁存8192bits,就是8k。
erase可以是全部,块,页等。
sam4s16c的片内flash大小的1m,0x100000.在片内的起始地址是0x400000,所有的读写都要从这个地址开始。不然会跑飞,我在调试时,试验了。很苦涩。
找了1天的原因,后来发现是我少写了个“0”,写成0x47000了,可能是自己不仔细,也可能是笔者经验不足,当然都是借口。
flash的写步骤是,
第一,先解锁
需要调用解锁函数flash_unlock()在xdk-asf-3.32.0\sam\services\flash_efc目录下的flash_efc.c文件里
里面很复杂,起初看的很晕。我是一遍又一遍的单步调试才搞明白的。
大家有兴趣可以研究一下,附上代码
uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end,
                uint32_t *pul_actual_start, uint32_t *pul_actual_end)
{
        Efc *p_efc;
        uint32_t ul_actual_start, ul_actual_end;
        uint16_t us_start_page, us_end_page;
        uint32_t ul_error;
        uint16_t us_num_pages_in_region =
                        IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;

        /* Compute actual unlock range and store it */
        compute_lock_range(ul_start, ul_end, &ul_actual_start, &ul_actual_end);
        if (pul_actual_start != NULL) {
                *pul_actual_start = ul_actual_start;
        }
        if (pul_actual_end != NULL) {
                *pul_actual_end = ul_actual_end;
        }

        /* Compute page numbers */
        translate_address(&p_efc, ul_actual_start, &us_start_page, 0);
        translate_address(0, ul_actual_end, &us_end_page, 0);

        /* Unlock all pages */
        while (us_start_page < us_end_page) {
                ul_error = efc_perform_command(p_efc, EFC_FCMD_CLB,
                                us_start_page);
                if (ul_error) {
                        return ul_error;
                }
                us_start_page += us_num_pages_in_region;
        }

        return FLASH_RC_OK;
}

第二步  解锁完成后要先擦除,可以选,全部,块或页。
调用库函数flash_erase_sector(),路径同上
这个函数看起来比较简单些,代码如下,有兴趣可以自己研究。
uint32_t flash_erase_sector(uint32_t ul_address)
{
        Efc *p_efc;
        uint16_t us_page;

        translate_address(&p_efc, ul_address, &us_page, NULL);

        if (EFC_RC_OK != efc_perform_command(p_efc, EFC_FCMD_ES, us_page)) {
                return FLASH_RC_ERROR;
        }

        return FLASH_RC_OK;
}

第三步,可以开始写数据。
调用flash_write()函数,路径同上
代码如下
uint32_t flash_write(uint32_t ul_address, const void *p_buffer,
                uint32_t ul_size, uint32_t ul_erase_flag)
{
        Efc *p_efc;
        uint32_t ul_fws_temp;
        uint16_t us_page;
        uint16_t us_offset;
        uint32_t writeSize;
        uint32_t ul_page_addr;
        uint16_t us_padding;
        uint32_t ul_error;
        uint32_t ul_idx;
        uint32_t *p_aligned_dest;
        uint8_t *puc_page_buffer = (uint8_t *) gs_ul_page_buffer;

        translate_address(&p_efc, ul_address, &us_page, &us_offset);

#if SAM3S || SAM3N || SAM3XA || SAM3U
        /* According to the errata, set the wait state value to 6. */
        ul_fws_temp = efc_get_wait_state(p_efc);
        efc_set_wait_state(p_efc, 6);
#else
        UNUSED(ul_fws_temp);
#endif

        /* Write all pages */
        while (ul_size > 0) {
                /* Copy data in temporary buffer to avoid alignment problems. */
                writeSize = Min((uint32_t) IFLASH_PAGE_SIZE - us_offset,
                                ul_size);
                compute_address(p_efc, us_page, 0, &ul_page_addr);
                us_padding = IFLASH_PAGE_SIZE - us_offset - writeSize;

                /* Pre-buffer data */
                memcpy(puc_page_buffer, (void *)ul_page_addr, us_offset);

                /* Buffer data */
                memcpy(puc_page_buffer + us_offset, p_buffer, writeSize);

                /* Post-buffer data */
                memcpy(puc_page_buffer + us_offset + writeSize,
                                (void *)(ul_page_addr + us_offset + writeSize),
                                us_padding);

                /* Write page.
                 * Writing 8-bit and 16-bit data is not allowed and may lead to
                 * unpredictable data corruption.
                 */
                p_aligned_dest = (uint32_t *) ul_page_addr;
                for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / sizeof(uint32_t));
                                ++ul_idx) {
                        *p_aligned_dest++ = gs_ul_page_buffer[ul_idx];
                }

                if (ul_erase_flag) {
                        ul_error = efc_perform_command(p_efc, EFC_FCMD_EWP,
                                        us_page);
                } else {
                        ul_error = efc_perform_command(p_efc, EFC_FCMD_WP,
                                        us_page);
                }

                if (ul_error) {
                        return ul_error;
                }

                /* Progression */
                p_buffer = (void *)((uint32_t) p_buffer + writeSize);
                ul_size -= writeSize;
                us_page++;
                us_offset = 0;
        }

#if SAM3S || SAM3N || SAM3XA || SAM3U
        /* According to the errata, restore the wait state value. */
        efc_set_wait_state(p_efc, ul_fws_temp);
#endif

        return FLASH_RC_OK;
}

这个函数嵌套很深,比较复杂,笔者也是单步调试,好多遍才搞懂。水平有限。
第四步,就是上锁
调用flash_lock()函数,路径同上
代码附上
uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end,
                uint32_t *pul_actual_start, uint32_t *pul_actual_end)
{
        Efc *p_efc;
        uint32_t ul_actual_start, ul_actual_end;
        uint16_t us_start_page, us_end_page;
        uint32_t ul_error;
        uint16_t us_num_pages_in_region =
                        IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;

        /* Compute actual lock range and store it */
        compute_lock_range(ul_start, ul_end, &ul_actual_start, &ul_actual_end);

        if (pul_actual_start != NULL) {
                *pul_actual_start = ul_actual_start;
        }

        if (pul_actual_end != NULL) {
                *pul_actual_end = ul_actual_end;
        }

        /* Compute page numbers */
        translate_address(&p_efc, ul_actual_start, &us_start_page, 0);
        translate_address(0, ul_actual_end, &us_end_page, 0);

        /* Lock all pages */
        while (us_start_page < us_end_page) {
                ul_error = efc_perform_command(p_efc, EFC_FCMD_SLB, us_start_page);

                if (ul_error) {
                        return ul_error;
                }
                us_start_page += us_num_pages_in_region;
        }

        return FLASH_RC_OK;
}

官方的库函数,都是很复杂,目前没有简单的寄存器版本,看的很累。有兴趣的自己研究。


片内flash的读,步骤是
解锁,读取,上锁,这个很简单,不在此处多说。
水平和经验有限,请大家多指点,谢谢!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册
x

评分

参与人数 2积分 +25 收起 理由
neomissing + 5
ElecFans处女座 + 20 原创技术先锋,加分鼓励!
查看全部评分
标签:flash
举报
版主
发表于 2016-11-8 10:08:14    楼主|
谢谢论坛的鼓励,我一定坚持多发原创
回复 点赞 举报
工程师
发表于 2016-11-8 13:07:35  
生活就像一盒巧克力,你不知道你的下一块口味是什么。
回复 点赞 举报
版主
发表于 2016-11-9 00:40:40    楼主|
是的,真理啊,,,,
回复 举报
实习生
发表于 2016-11-11 13:35:31  
atmel被收购了
回复 举报
版主
发表于 2016-11-12 15:48:40    楼主|
恩,高通,又一个巨无霸产生了
回复 点赞 举报
助理工程师
发表于 2016-11-13 10:53:41  
谢谢大家的分享。谢谢。
回复 举报
技术员
发表于 2016-11-13 11:06:05  
学习一下,希望可以互相交流3026827905
回复 点赞 举报
版主
发表于 2016-11-13 11:09:13    楼主|
可以啊,你是哪的?
回复 举报
版主
发表于 2016-11-15 00:23:56    楼主|
我的帖子被很多人推荐了,谢谢支持
回复 点赞 举报
高级模式
您需要登录后才可以回帖 登录 | 注册
关闭

站长推荐 上一条 /9 下一条

快速回复 返回顶部 返回列表
  1. time最新主题
  2. recommend推荐主题
  3. hot热门主题
  4. post 我的帖子
-

推荐专区

技术干货集中营

专家问答

方案交易

用户帮助┃咨询与建议┃版主议事

工程师杂谈

项目|工程师创意

招聘|求职}工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

MSP430技术论坛

FPGA|CPLD|ASIC论坛

STM32/STM8技术论坛

NXP MCU 技术论坛

PIC单片机论坛

DSP论坛

瑞萨单片机论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

工程资源中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

厂商专区

TI论坛

TI Deyisupport社区

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

电子展览展会专区

芯片求购|供应发布区

88lifa利发国际娱乐

百度360搜索搜狗搜索