SYD8801是一款低功耗高性能蓝牙低功耗SOC,集成了高性能2.4GHz射频收发机、32位ARM Cortex-M0处理器、128kB Flash存储器、以及丰富的数字接口。SYD8801片上集成了Balun无需阻抗匹配网络、高效率DCDC降压转换器,适合用于可穿戴、物联网设备等。具体可咨询:http://www.sydtek.com/
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_sched_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:x \r\n",currer_address); dbg_printf("[syd8801] err:x \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:x \r\n",currer_address); dbg_printf("[syd8801] err:x \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:x \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:x \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空间操作方法
正常情况下从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