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

📅 2026/7/13 1:01:03
SYD8801操作内部flash空间(【3K(ProfileData)空间操作方法】 【24K(FlashData)空间操作方法】)
提前说明SYD8811/SYD8810/SYD8801以及其他SYDTEK下的芯片,都支持内部空间的操作,因为在SYD8801的时候ProfileData空间(芯片默认给用户预留的空间,不用配置就存在),所以这里用3K来代表ProfileData,也不是所有芯片的ProfileData都是3k空间,比如SYD8821就是4K,各个芯片的API名字可能不完全一样,但是原理是一致的。和ProfileData一样这里使用24K来代表FlashDataFlashData的空间大小是开发者可以配置的在Studio的Setting中有如下功能,这里选择合适的大小后点击Write按钮即可配置自己需要的大小:SYD8801的falsh空间安排请看之前博客http://blog.csdn.net/chengdong1314/article/details/54956664如下SYD8801的flash中有两个区域给用户存储数据使用一个空间是3K一个空间是24K.3K空间操作方法在库的头文件lib.h中定义了如下函数/* readwrite 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函数每次最大只能够写入128个字节,ReadProfileData函数没有长度限制注意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){errReadProfileData( 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){errWriteProfileData( 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(i0;i10;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/988550124K空间操作方法注意对于SYD8811/881024K空间就是指FLASHDATA,这个空间是用户自己分配的调用API传入的首地址是0API接口内部已经自动做了偏移关于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的长度单位为bytep_buf:读取数据保存的位置uint8_t ble_flash_write(uint32_t address, uint8_t len, uint8_t *p_buf);参数 address要写入的flash的首地址len:要写入flash的长度单位为bytep_buf:写入数据保存的位置*///eraseif(sector6) sector0;dbg_printf(erase user flash addr:%x sector_num:%x start\r\n,USER_FLASH_BASE_ADDRUSER_FLASH_SECTOR_SIZE*sector,1);errble_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;}//writedbg_printf(write user flash addr:%x size:%x start\r\n,USER_FLASH_BASE_ADDRUSER_FLASH_SECTOR_SIZE*sector1024,sizeof(write_buff));errble_flash_write (USER_FLASH_BASE_ADDRUSER_FLASH_SECTOR_SIZE*sector1024, 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;}//readdbg_printf(read user flash addr:%x size:%x start\r\n,USER_FLASH_BASE_ADDRUSER_FLASH_SECTOR_SIZE*sector1024,sizeof(read_buff));errble_flash_read (USER_FLASH_BASE_ADDRUSER_FLASH_SECTOR_SIZE*sector1024, 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;}//comparedbg_printf(compare read and write data size:%x start\r\n,sizeof(read_buff));for(i0;i200;i){if(write_buff[i] ! read_buff[i]) break;}if(i200) dbg_printf(flash operation error \r\n);else dbg_printf(flash operation ok \r\n);//disaplydbg_hexdump(read_buff[0:50]:\r\n,read_buff,50);sector;if(sector6) sector0;delay_ms(300);}else if(get_key()2){if(sector6) continue;//readdbg_printf(read user flash addr:%x size:%x start\r\n,USER_FLASH_BASE_ADDRUSER_FLASH_SECTOR_SIZE*sector1024,sizeof(read_buff));errble_flash_read (USER_FLASH_BASE_ADDRUSER_FLASH_SECTOR_SIZE*sector1024, sizeof(read_buff),read_buff);if(err) dbg_printf(read user flash OK);else {dbg_printf(read user flash error \r\n); break;}//disaplydbg_hexdump(read_buff[0:50]:\r\n,read_buff,50);sector;if(sector6) sector0;delay_ms(300);}}这里按下按键1则会进行擦除、写入、读取、比较工作同时扇区数将会自加也就是说按下6次按键就能够擦除所有的用户flash空间按下按键按键2只会进行读取操作同时扇区数将会自加。以上代码已经测试成功注意这里的写函数都会进行整个扇区的擦除操作不管写入的数据是多少字节这里上传上本博客使用的工程代码http://download.csdn.net/detail/chengdong1314/9775295Flashdata传入的数组不能够来自代码区今天遇到一个问题,只要调用WriteFlashData函数就会死机:phaseNum wave_data_len[index] / 8; dbg_printf(w1 addr:%x len:%x buff:%x\r\n,FLASH_INTERNAL_WAVEDATA_ADDR 1024 * index,sizeof(phaseNum),(uint32_t)phaseNum); dbg_printf(w2 addr:%x len:%x buff:%x\r\n,FLASH_INTERNAL_WAVEDATA_ADDR 1024 * index sizeof(phaseNum),wave_data_len[index],(uint32_t)wave_data_arr[index]); WriteFlashData(FLASH_INTERNAL_WAVEDATA_ADDR 1024 * index, sizeof(phaseNum), (uint8_t *)phaseNum); WriteFlashData(FLASH_INTERNAL_WAVEDATA_ADDR 1024 * index sizeof(phaseNum), wave_data_len[index], (uint8_t *)wave_data_arr[index]);log如下:Syd8811_UART w1 addr:1000 len:4 buff:200042D4 w2 addr:1004 len:60 buff:10006412 w1 addr:1400 len:4 buff:200042D4 w2 addr:1404 len:60 buff:10006472 w1 addr:1800 len:4 buff:200042D4 w2 addr:1804 len:60 buff:100064D2 w1 addr:1C00 len:4 buff:200042D4 w2 addr:1C04 len:60 buff:10006532可以看到buff的地址是0X1xxxxxxx,这个是代码区的地址,看代码是数组前面加了const 变量来修饰并且直接传入这个变量:const uint8_t wave_data_mode1[] 这个是不允许的,flashdata写入的指针不能够来自代码区,所以这里可以加一个缓冲问题就能够解决:for (index 0; index MAX_MODE; index) { phaseNum wave_data_len[index] / 8; dbg_printf(w1 addr:%x len:%x buff:%x\r\n,FLASH_INTERNAL_WAVEDATA_ADDR 1024 * index,sizeof(phaseNum),(uint32_t)phaseNum); dbg_printf(w2 addr:%x len:%x buff:%x\r\n,FLASH_INTERNAL_WAVEDATA_ADDR 1024 * index sizeof(phaseNum),wave_data_len[index],(uint32_t)wave_data_arr[index]); WriteFlashData(FLASH_INTERNAL_WAVEDATA_ADDR 1024 * index, sizeof(phaseNum), (uint8_t *)phaseNum); WriteFlashData(FLASH_INTERNAL_WAVEDATA_ADDR 1024 * index sizeof(phaseNum), wave_data_len[index], (uint8_t *)wave_data_arr[index]); }log如下并且不会死机了:Syd8811_UART w1 addr:1000 len:4 buff:200042D4 w2 addr:1004 len:60 buff:1000643E w1 addr:1400 len:4 buff:200042D4 w2 addr:1404 len:60 buff:1000649E w1 addr:1800 len:4 buff:200042D4 w2 addr:1804 len:60 buff:100064FE w1 addr:1C00 len:4 buff:200042D4 w2 addr:1C04 len:60 buff:1000655E