SYD8801操作内部flash空间(【3K(ProfileData)空间操作方法】 【24K(FlashData)空间操作方法】)

    SYD8801是一款低功耗高性能蓝牙低功耗SOC,集成了高性能2.4GHz射频收发机、32位ARM Cortex-M0处理器、128kB Flash存储器、以及丰富的数字接口。SYD8801片上集成了Balun无需阻抗匹配网络、高效率DCDC降压转换器,适合用于可穿戴、物联网设备等。具体可咨询:http://www.sydtek.com/

提前说明

        SYD8811/SYD8810/SYD8801以及其他SYDTEK下的芯片,都支持内部空间的操作,因为在SYD8801的时候ProfileData空间(芯片默认给用户预留的空间,不用配置就存在),所以这里用3K来代表ProfileData,也不是所有芯片的ProfileData都是3k空间,比如SYD8821就是4K,各个芯片的API名字可能不完全一样,但是原理是一致的。和ProfileData一样,这里使用24K来代表FlashData,FlashData的空间大小是开发者可以配置的,在Studio的Setting中有如下功能,这里选择合适的大小后点击"Write"按钮即可配置自己需要的大小:

 

SYD8801的falsh空间安排(请看之前博客:http://blog.csdn.net/chengdong1314/article/details/54956664)如下:

    SYD8801的flash中有两个区域给用户存储数据使用,一个空间是3K,一个空间是24K.

3K空间操作方法

    在库的头文件(lib.h)中定义了如下函数:

    /* read&write flash */
    extern uint8_t ReadProfileData(uint16_t addr , uint16_t len, uint8_t *p_buf);   返回1代表成功 0代表失败
    extern uint8_t WriteProfileData(uint16_t addr , uint16_t len, uint8_t *p_buf);   返回1代表成功 0代表失败

   这两个函数可以操作用户3k空间,也就是上面那个图中最后的Profile Paratemers,操作这个空间不需要调用擦除函数,只需要读写就行。

   注意:WriteProfileData函数交由底层代码负责写操作,调用WriteProfileData函数的时候底层代码会先把数据放在缓冲区,只用调用了ble_sched_execute函数的时候真正的写flash操作才会起效,因为写flash的时间比较长,所以ble_schedK_execute函数一般在主函数的主循环调用,ble_sched_execute函数相关内容具体请看:http://blog.csdn.net/chengdong1314/article/details/76169279

   这里使用如下的测试代码:

    while(1)
    {        
        if(get_key()==1){
            err=ReadProfileData( currer_address,10,read_buff );
            dbg_printf("Read currer_address:%04x \r\n",currer_address);
            dbg_printf("[syd8801] err:%04x \r\n",err);
            dbg_hexdump("buff:\r\n",read_buff,10);
            GPO_CTRL->GPO_4=~GPO_CTRL->GPO_4;
            delay_ms(300);
        }else if(get_key()==2){
            err=WriteProfileData( currer_address,10,buff );
            dbg_printf("Write currer_address:%04x \r\n",currer_address);
            dbg_printf("[syd8801] err:%04x \r\n",err);
            dbg_hexdump("buff:\r\n",buff,10);
            GPO_CTRL->GPO_5=~GPO_CTRL->GPO_5;
            for(i=0;i<10;i++){
                buff[i]++;
            }
            delay_ms(300);
        }else if(get_key()==3){
            currer_address +=5;
            dbg_printf("currer_address:%04x \r\n",currer_address);
          GPO_CTRL->GPO_6=~GPO_CTRL->GPO_6;
            delay_ms(300);
        }else if(get_key()==4){
            currer_address -=5;
            dbg_printf("currer_address:%04x \r\n",currer_address);
            GPO_CTRL->GPO_7=~GPO_CTRL->GPO_7;
            delay_ms(300);
        }
        led_turn(LED0);
    }   

    当按下开发板的SW1的时候对currer_address地址进行读操作,然后调用dbg_hexdump("buff:\r\n",read_buff,10);把读到的信息答应出来,按下SW2进行写操作,然后调用dbg_hexdump("buff:\r\n",read_buff,10);把学信息答应出来,按下SW3读写地址自加5,按下SW4读写地址自减5.
     上面这套程序已经测试OK

     注意:这里的写函数都会进行整个扇区的擦除操作,不管写入的数据是多少字节!

   

     这里上传上本博客工程代码:http://download.csdn.net/detail/chengdong1314/9775236

    下面是带上蓝牙功能的工程:http://download.csdn.net/detail/chengdong1314/9885501

    

24K空间操作方法

    注意:对于SYD8811/8810,24K空间就是指FLASHDATA,这个空间是用户自己分配的,调用API传入的首地址是0(API接口内部已经自动做了偏移),关于flash分配的问题请看文章:https://blog.csdn.net/chengdong1314/article/details/118210536 ,请使用Studio工具在setting选择卡中的FLASH DATA进行空间分配!

    正常情况下从0x19000开始的24K空间用户都是可以使用的,在库的头文件(lib.h)中定义了如下函数:

    extern uint8_t ble_flash_erase(uint32_t address, uint8_t num);
    extern uint8_t ble_flash_read(uint32_t address, uint8_t len, uint8_t *p_buf);
    extern uint8_t ble_flash_write(uint32_t address, uint8_t len, uint8_t *p_buf);

    注意:这里的擦除函数ble_flash_erase很关键,使用的时候需谨慎,其中的num变量代表的是要删除多少个扇区,而不是要擦除那个扇区(相对address的偏移),因为擦除函数会参数flash上的内容,所以使用的时候要注意不要擦除不应该擦除的地址!

    这些算是flash标准擦除读写函数,这里可以使用下面的测试代码 
if(get_key()==1){
        /*
        uint8_t ble_flash_erase(uint32_t address, uint8_t );
        参数 address:要擦除扇区的首地址
             num:要擦除的扇区数
             注:一个扇区的大小是4096B
                 用户能够使用的是从0x00019000开始的24KB的空间,最后一个扇区留给协议栈使用
        
        uint8_t ble_flash_read(uint32_t address, uint8_t len, uint8_t *p_buf);
        参数 address:要读取flash的首地址
             len:要读取flash的长度,单位为byte
             p_buf:读取数据保存的位置
        
        uint8_t ble_flash_write(uint32_t address, uint8_t len, uint8_t *p_buf);
        参数 address:要写入的flash的首地址
             len:要写入flash的长度,单位为byte
             p_buf:写入数据保存的位置
        */

        //erase
        if(sector>=6) sector=0;
        dbg_printf("erase user flash addr:%x sector_num:%x start\r\n",USER_FLASH_BASE_ADDR+USER_FLASH_SECTOR_SIZE*sector,1);
        err=ble_flash_erase (USER_FLASH_BASE_ADDR, sector);
        if(err)  dbg_printf("erase user flash OK\r\n");
        else {dbg_printf("erase user flash error\r\n");  break;}
        
        //write
        dbg_printf("write user flash addr:%x size:%x start\r\n",USER_FLASH_BASE_ADDR+USER_FLASH_SECTOR_SIZE*sector+1024,sizeof(write_buff));
        err=ble_flash_write (USER_FLASH_BASE_ADDR+USER_FLASH_SECTOR_SIZE*sector+1024, sizeof(write_buff),write_buff);
        if(err)  dbg_printf("write user flash OK \r\n");
        else {dbg_printf("write user flash error \r\n");  break;}
        
        //read
        dbg_printf("read user flash addr:%x size:%x start\r\n",USER_FLASH_BASE_ADDR+USER_FLASH_SECTOR_SIZE*sector+1024,sizeof(read_buff));
        err=ble_flash_read (USER_FLASH_BASE_ADDR+USER_FLASH_SECTOR_SIZE*sector+1024, sizeof(read_buff),read_buff);
        if(err)  dbg_printf("read user flash OK\r\n");
        else {dbg_printf("read user flash error \r\n");  break;}
        
        //compare
        dbg_printf("compare read and write data size:%x start\r\n",sizeof(read_buff));
        for(i=0;i<200;i++){
         if(write_buff[i] != read_buff[i]) break;
        }
        if(i<200) dbg_printf("flash operation error \r\n");
        else dbg_printf("flash operation ok \r\n");
        
        //disaply
        dbg_hexdump("read_buff[0:50]:\r\n",read_buff,50);
        
        sector++;
        if(sector>=6)  sector=0;
        delay_ms(300);
    }else if(get_key()==2){
        if(sector>=6) continue;
        //read
        dbg_printf("read user flash addr:%x size:%x start\r\n",USER_FLASH_BASE_ADDR+USER_FLASH_SECTOR_SIZE*sector+1024,sizeof(read_buff));
        err=ble_flash_read (USER_FLASH_BASE_ADDR+USER_FLASH_SECTOR_SIZE*sector+1024, sizeof(read_buff),read_buff);
        if(err)  dbg_printf("read user flash OK");
        else {dbg_printf("read user flash error \r\n");  break;}
        
        //disaply
        dbg_hexdump("read_buff[0:50]:\r\n",read_buff,50);
        
        sector++;
        if(sector>=6)  sector=0;
        delay_ms(300);
    }
}   
      这里按下按键1则会进行擦除、写入、读取、比较工作,同时扇区数将会自加,也就是说按下6次按键就能够擦除所有的用户flash空间,按下按键按键2只会进行读取操作,同时扇区数将会自加。

      以上代码已经测试成功!

      注意:这里的写函数都会进行整个扇区的擦除操作,不管写入的数据是多少字节!

       这里上传上本博客使用的工程代码:

       http://download.csdn.net/detail/chengdong1314/9775295

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值