CH582M 關(guān)于特征寫入回調(diào)函數(shù)的問題

尊敬的技術(shù)人員,您好,目前在開發(fā)過程中尚存在幾個(gè)小問題,煩請(qǐng)解答,謝謝。


目前連接的步驟為:掃描 - 建立連接 - 申請(qǐng)2M PHY - PHY申請(qǐng)回調(diào)中 - 請(qǐng)求最大MTU - MTU回調(diào)中發(fā)現(xiàn)服務(wù) - 發(fā)現(xiàn)服務(wù)回調(diào)中發(fā)現(xiàn)特征,訂閱其中一個(gè)notify特征,然后處理另一個(gè)可讀寫特征數(shù)據(jù)。共有兩個(gè)特征,一個(gè)長(zhǎng)度180字節(jié)可讀寫特征,一個(gè)2字節(jié)notify特征。MTU目前設(shè)置為247。


發(fā)送大量數(shù)據(jù)時(shí):寫入特征值(共180字節(jié)的結(jié)構(gòu)體序列化數(shù)據(jù)) - 設(shè)備端的寫入回調(diào)被調(diào)用 - 處理數(shù)據(jù) - 使用另一個(gè)notify特征通知手機(jī)。


現(xiàn)在存在的問題是:

  1. ?1.?我現(xiàn)在使用CH582M與安卓手機(jī)建立連接,發(fā)送大量數(shù)據(jù),在快速發(fā)送數(shù)據(jù)過程中手機(jī)會(huì)與設(shè)備斷開連接,設(shè)備顯示reason 13,為手機(jī)主動(dòng)斷開連接,上網(wǎng)搜尋后得知,建立連接后要先請(qǐng)求高優(yōu)先級(jí),但是實(shí)際測(cè)試中發(fā)現(xiàn)設(shè)置優(yōu)先級(jí)對(duì)這個(gè)情況沒有明顯改善 ( 讀寫操作的相關(guān)等待延遲已妥善設(shè)置 )。

  2. 2 在設(shè)備端特征被寫入的回調(diào)函數(shù)中,uint8_t* pValue 【有時(shí)候】無法直接使用結(jié)構(gòu)體指針反序列化,反序列化指針使用const進(jìn)行約束,在反序列化之前也會(huì)對(duì)實(shí)際的數(shù)據(jù)長(zhǎng)度 len 進(jìn)行檢查。 反序列化無法使用的表現(xiàn)為主循環(huán)停止執(zhí)行了,因?yàn)橐话阍跀嚅_連接后串口會(huì)打印出掃描信息,連接成功會(huì)也會(huì)打印read rssi信息。而在這種情況下,串口沒有任何數(shù)據(jù)輸出,此時(shí)使用調(diào)試器也無法正確連接。已確認(rèn)此處理代碼過程中不含有無限循環(huán)等阻止CPU執(zhí)行的情況,也沒有出現(xiàn)內(nèi)存越界的情況。( 目前只能 tmos_memcpy到另一個(gè)緩沖區(qū)中處理 )

  3. 3. 設(shè)備notify特征值的時(shí)候,調(diào)用的一個(gè)庫(kù)函數(shù)似乎使用了動(dòng)態(tài)內(nèi)存分配,因?yàn)槭穷A(yù)編譯的靜態(tài)庫(kù),所以不容易做出修改,可否有辦法改為靜態(tài)全局緩沖區(qū)分配?我嘗試過改為靜態(tài)分配,但是無法成功notify。

  4. 4. 在使用BLE的時(shí)候,編譯出來的固件體積較大,已開啟 -Os 優(yōu)化、移除未使用的輸入段、鏈接時(shí)全局優(yōu)化等選項(xiàng),但體積仍然較大,不知道是否能夠提供靜態(tài)庫(kù)的源代碼以供精簡(jiǎn)冗余信息?(無法提供源代碼的話請(qǐng)忽略此條) 因?yàn)樵谠S多官方C代碼中在處理不同情況的時(shí)候會(huì)使用很多條件與循環(huán),這部分代碼對(duì)于定制化的功能來說是冗余的。

  5. 5. 因MRS的代碼索引等功能較為不完善,所以目前我們使用vscode + eide插件進(jìn)行開發(fā),編譯器等組件直接使用MRS下的toolchain目錄,但是目前使用WCH-LINKE進(jìn)行調(diào)試的時(shí)候仍需使用MRS,因?yàn)樵趘scode中使用cortex-debug插件無法進(jìn)行調(diào)試,但是能在網(wǎng)絡(luò)上搜索到文章,可以對(duì)CH32V20X進(jìn)行調(diào)試,我按照相同的步驟選擇各個(gè)參數(shù)后,無法與目標(biāo)設(shè)備建立連接。因?yàn)樾掳娴牡腸ortex-debug插件要求GCC 9以上,所以目前使用0.43版本,不知道是否有相關(guān)配置文件提供?

  6. 6. 這里借用了官方的OTA升級(jí)工具對(duì)比吞吐量,發(fā)現(xiàn)官方的OTA升級(jí)工具吞吐量比目前我們的測(cè)試程序高出許多,但是在研究了官方提供的Android Studio工程源代碼之后發(fā)現(xiàn)與我們使用的方式是一樣的,我們目前的工程代碼(設(shè)備端)是從?Peripheral 例程修改而來的,請(qǐng)參考我上面提到的步驟,幫助分析一下是否有哪些地方存在問題?而且官方的OTA代碼在接收到數(shù)據(jù)時(shí)還對(duì) flash 進(jìn)行了編程,根據(jù)官方手冊(cè)的參數(shù),編程flash速度要慢得多,我們的處理代碼僅進(jìn)行了耗時(shí)很短的操作,且在執(zhí)行此測(cè)試時(shí),我們關(guān)閉了用戶自定義的中斷,僅保留必要的中斷。


以上是信息描述,非常感謝。






1、建議使用默認(rèn)的1M速率,使用2M速率對(duì)速度的提升并不明顯,而且需要考慮主機(jī)兼容性問題;

2、數(shù)據(jù)快速發(fā)送的時(shí)候,需要考慮藍(lán)牙本身是否來得及處理。建議配置為最小連接間隔范圍6-8,MTU配置為247;

3、write/noti收發(fā)數(shù)據(jù)的時(shí)候,如果數(shù)據(jù)比較多而且需要串口輸出,則需要添加環(huán)形緩沖區(qū)功能,否則可能丟失數(shù)據(jù),直接參考ble_uart例程;

4、從機(jī)主動(dòng)使能noti參考:

CH573 CH582 CH579藍(lán)牙從機(jī)(peripheral)例程講解五(藍(lán)牙從機(jī)使能通知) - WCH藍(lán)牙應(yīng)用分享 - 博客園 (cnblogs.com)

從機(jī)noti發(fā)送失敗,檢查代碼返回值是否為0。如果非0則說明函數(shù)調(diào)用存在問題,例如handle不對(duì),如果時(shí)有成功且報(bào)錯(cuò)pending,則可以將協(xié)議棧分配的緩存增大;

5、MRS搜索:ctrl+f。MRS打開界面有helpManual。其他的配置參考:

MRS_開發(fā)編譯與設(shè)置相關(guān)問題匯總 - WCH_CH32 - 博客園 (cnblogs.com)

6、發(fā)送數(shù)據(jù)最大化:連接間隔配置為最?。ú榭催B接間隔協(xié)商),MTU配置為最大(前兩點(diǎn)是速度慢的最大原因),單連接多包,緩存加大。

藍(lán)牙BLE從機(jī)Peripheral講解一(廣播間隔和連接間隔) - SweetTea_lllpc - 博客園 (cnblogs.com)


@TECH_Lpc 謝謝回復(fù)。

請(qǐng)看下面帖子


@TECH_Lpc 謝謝回復(fù)。

關(guān)于第二點(diǎn),最小連接間隔已經(jīng)配置為6了,但是似乎吞吐量也沒那么大。

3. 我原文的意思是只是在串口輸出個(gè)標(biāo)志,不是把所有數(shù)據(jù)都輸出。這個(gè)問題已經(jīng)得到解決了,調(diào)試器的錯(cuò)誤解決了,用調(diào)試器調(diào)試了一下,發(fā)現(xiàn)寫入回調(diào)被調(diào)用的時(shí)候,直接轉(zhuǎn)指針會(huì)?

HardFault_Handler? ? ? ?/* Hard Fault Handler */

,查看了pValue的偏移量為MEM_BUF+4389,不知道為何沒有四字節(jié)對(duì)齊,我在查看了源代碼,但是調(diào)用的地方是 .a 靜態(tài)庫(kù)里的位置,無法查看具體原因,我可以確認(rèn)所有的寫操作都是4字節(jié)對(duì)齊的,不知道被調(diào)用這里為何偏移量沒有對(duì)齊。+4389>

4. 我不是使用兩個(gè)CH582M連接,而是使用手機(jī)連接CH582M,手機(jī)端可以正常訂閱Notify,只是設(shè)備端:


attHandleValueNoti_t?noti;

? ??if?(len?>?(peripheralMTU?-?3)) {

? ? ? ??PRINT("Too large noti\n");

? ? ? ??return;

? ? }

? ??noti.len?? ?=?len;

? ??noti.pValue?=?GATT_bm_alloc(peripheralConnList.connHandle,?ATT_HANDLE_VALUE_NOTI,?noti.len,?NULL,?0);

? ??if?(noti.pValue) {

? ? ? ??tmos_memcpy(noti.pValue,?pValue,?noti.len);

? ? ? ??if?(simpleProfile_Notify(peripheralConnList.connHandle,?&noti)?!=?SUCCESS) {

? ? ? ? ? ??GATT_bm_free((gattMsg_t?*)&noti,?ATT_HANDLE_VALUE_NOTI);

? ? ? ? }

? ? }


這里?GATT_bm_alloc?似乎是從藍(lán)牙協(xié)議棧分配了動(dòng)態(tài)的內(nèi)存,我不知道靜態(tài)庫(kù)的代碼怎么寫的,但是推測(cè)應(yīng)該是藍(lán)牙協(xié)議棧的預(yù)分配內(nèi)存按索引分配的,還是屬于靜態(tài)內(nèi)存,但是這個(gè)使用方法似乎不是很合適,有沒有辦法在這個(gè)位置直接使用外部靜態(tài)分配?我自己嘗試使用外部靜態(tài)分配,但是修改之后就無法正常Notify了。


5. Eclipse 以前經(jīng)常使用,各種操作都會(huì)用,只是對(duì)比vscode,很多代碼跳轉(zhuǎn)查詢都還是顯得效率低下?,F(xiàn)在編碼和編譯沒有問題。只是調(diào)試無法調(diào)試,我按照搜到的一片文章?https://www.cnblogs.com/wahahahehehe/p/16896184.html?進(jìn)行了配置,但是無法使用調(diào)試,配置文件如下:


{

? ??"version":?"0.2.0",

? ??"configurations": [

? ? ? ? {

? ? ? ? ? ??"cwd":?"${workspaceRoot}",

? ? ? ? ? ??"executable":?"./build/Debug/bootloader.elf",?//替換對(duì)應(yīng)的elf文件路徑

? ? ? ? ? ??"name":?"Debug with OpenOCD",

? ? ? ? ? ??"request":?"launch",

? ? ? ? ? ??"type":?"cortex-debug",

? ? ? ? ? ??"servertype":?"openocd",

? ? ? ? ? ??"searchDir": [],

? ? ? ? ? ??"runToEntryPoint":?"main",

? ? ? ? ? ??"showDevDebugOutput":?true,

? ? ? ? ? ??"device":?"CH582M",

? ? ? ? ? ??"svdFile":?"C:/MounRiver/MounRiver_Studio/template/wizard/WCH/RISC-V/CH58X/NoneOS/CH58Xxx.svd",?//MRS安裝目錄svd

? ? ? ? ? ??"toolchainPrefix":?"D:/MounRiver/MounRiver_Studio/toolchain/RISC-V Embedded GCC/bin/riscv-none-embed",?//MRS安裝目錄gdb, 不包含"-gdb.exe"

? ? ? ? ? ??"configFiles": [

? ? ? ? ? ? ? ??"C:/MounRiver/MounRiver_Studio/toolchain/OpenOCD/bin/wch-riscv.cfg"?//MRS安裝目錄cfg

? ? ? ? ? ? ]

? ? ? ? }

? ? ]

}



6. 如上所云,已經(jīng)配置為單連接多包,鏈接間隔也已經(jīng)配置為最小了,緩存也給的很大。


7. 另外想咨詢一下,有沒有精簡(jiǎn)版的 .a靜態(tài)庫(kù),因?yàn)槲夷壳伴_發(fā)的這個(gè)固件是一個(gè)平時(shí)不參與正常功能的固件,很多的東西是可以精簡(jiǎn)掉的。


我用官方一段源代碼舉例:

比如


SetSysClock(CLK_SOURCE_PLL_60MHz);

會(huì)調(diào)用如下官方代碼:


void?SetSysClock(SYS_CLKTypeDef?sc)

{

? ??uint32_t?i;

? ??sys_safe_access_enable();

? ??R8_PLL_CONFIG?&=?~(1?<<?5);?//

? ??sys_safe_access_disable();

? ??if(sc?&?0x20)

? ? {?// HSE div

? ? ? ??if(!(R8_HFCK_PWR_CTRL?&?RB_CLK_XT32M_PON))

? ? ? ? {

? ? ? ? ? ??sys_safe_access_enable();

? ? ? ? ? ??R8_HFCK_PWR_CTRL?|=?RB_CLK_XT32M_PON;?// HSE power on

? ? ? ? ? ??sys_safe_access_disable();

? ? ? ? ? ??for(i?=?0;?i?<?1200;?i++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ??__nop();

? ? ? ? ? ? ? ??__nop();

? ? ? ? ? ? }

? ? ? ? }


? ? ? ??sys_safe_access_enable();

? ? ? ??R16_CLK_SYS_CFG?=?(0?<<?6)?|?(sc?&?0x1f);

? ? ? ??__nop();

? ? ? ??__nop();

? ? ? ??__nop();

? ? ? ??__nop();

? ? ? ??sys_safe_access_disable();

? ? ? ??sys_safe_access_enable();

? ? ? ??SAFEOPERATE;

? ? ? ??R8_FLASH_CFG?=?0X51;

? ? ? ??sys_safe_access_disable();

? ? }


? ??else?if(sc?&?0x40)

? ? {?// PLL div

? ? ? ??if(!(R8_HFCK_PWR_CTRL?&?RB_CLK_PLL_PON))

? ? ? ? {

? ? ? ? ? ??sys_safe_access_enable();

? ? ? ? ? ??R8_HFCK_PWR_CTRL?|=?RB_CLK_PLL_PON;?// PLL power on

? ? ? ? ? ??sys_safe_access_disable();

? ? ? ? ? ??for(i?=?0;?i?<?2000;?i++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ??__nop();

? ? ? ? ? ? ? ??__nop();

? ? ? ? ? ? }

? ? ? ? }

? ? ? ??sys_safe_access_enable();

? ? ? ??R16_CLK_SYS_CFG?=?(1?<<?6)?|?(sc?&?0x1f);

? ? ? ??__nop();

? ? ? ??__nop();

? ? ? ??__nop();

? ? ? ??__nop();

? ? ? ??sys_safe_access_disable();

? ? ? ??if(sc?==?CLK_SOURCE_PLL_80MHz)

? ? ? ? {

? ? ? ? ? ??sys_safe_access_enable();

? ? ? ? ? ??R8_FLASH_CFG?=?0X02;

? ? ? ? ? ??sys_safe_access_disable();

? ? ? ? }

? ? ? ??else

? ? ? ? {

? ? ? ? ? ??sys_safe_access_enable();

? ? ? ? ? ??R8_FLASH_CFG?=?0X52;

? ? ? ? ? ??sys_safe_access_disable();

? ? ? ? }

? ? }

? ??else

? ? {

? ? ? ??sys_safe_access_enable();

? ? ? ??R16_CLK_SYS_CFG?|=?RB_CLK_SYS_MOD;

? ? ? ??sys_safe_access_disable();

? ? }

? ??//更改FLASH clk的驅(qū)動(dòng)能力

? ??sys_safe_access_enable();

? ??R8_PLL_CONFIG?|=?1?<<?7;

? ??sys_safe_access_disable();

}



完全可以去掉非鎖相環(huán)部分,這部分代碼對(duì)于需要節(jié)省空間的項(xiàng)目來說是冗余的,這一個(gè)地方就可以節(jié)省316字節(jié), 一個(gè)地方可以節(jié)省幾十字節(jié)到幾百字節(jié)的話,很多地方加起來就可以節(jié)省很多空間了。因?yàn)槟壳熬幾g、匯編、鏈接的優(yōu)化全都給了:


? ??"global": {

? ? ? ??"output-debug-info":?"disable",

? ? ? ??"arch":?"rv32imac",

? ? ? ??"abi":?"ilp32",

? ? ? ??"code-model":?"medany",

? ? ? ??"misc-control":?"-msmall-data-limit=8 -mno-save-restore --specs=nosys.specs --specs=nano.specs"

? ? },

? ??"c/cpp-compiler": {

? ? ? ??"language-c":?"c99",

? ? ? ??"language-cpp":?"c++11",

? ? ? ??"optimization":?"level-size",

? ? ? ??"warnings":?"all-warnings",

? ? ? ??"C_FLAGS":?"-Wl,-Bstatic -ffunction-sections -fdata-sections -fmessage-length=0 -fsigned-char -flto"

? ? },

? ??"asm-compiler": {

? ? ? ??"ASM_FLAGS":?"-Wl,-Bstatic"

? ? },

? ??"linker": {

? ? ? ??"output-format":?"elf",

? ? ? ??"LD_FLAGS":?"-Wl,--cref -Wl,--gc-sections -nostartfiles",

? ? ? ??"LIB_FLAGS":?"-lISP583 -lCH58xBLE",

? ? ? ??"remove-unused-input-sections":?true,

? ? ? ??"$toolName":?"auto"

? ? }


8. 還有請(qǐng)問關(guān)于外掛 spi nor-flash 的映射有資料嗎?在內(nèi)部flash不夠使用的情況下是否可以直接執(zhí)行外掛flash中的代碼呢?


9. 關(guān)于PIC代碼似乎無法使用。我寫了一個(gè)工具固件,總大小為2020字節(jié),我將此固件用C語言數(shù)組的形式嵌入到另一個(gè)固件中,在運(yùn)行時(shí),將二進(jìn)制數(shù)據(jù)使用寫入到flash+6F000h中,然后跳轉(zhuǎn)運(yùn)行,固定起始地址是可以使用的,但是我在編譯時(shí)加入?yún)?shù) -fPIC 編譯成位置無關(guān)代碼卻不可以使用,請(qǐng)教一下這是為什么呢?另外我嘗試了幾種方式將PIC代碼放入RAM,直接在RAM中執(zhí)行:?


?(1) 使用__HIGH_CODE ,此方式無法實(shí)現(xiàn)正常執(zhí)行。

?(2) 使用直接執(zhí)行,直接將存儲(chǔ)工具固件的數(shù)組首地址強(qiáng)制轉(zhuǎn)換為函數(shù)指針,然后跳轉(zhuǎn)執(zhí)行,此方法也無法執(zhí)行(此方法應(yīng)該屬于flash執(zhí)行)。

?(3) 新建4字節(jié)對(duì)齊緩沖區(qū),將數(shù)據(jù)tmos_memcpy一份到緩沖區(qū),再嘗試執(zhí)行,也無法執(zhí)行。


以上嘗試方式所使用的工具固件均是使用 -fPIC 參數(shù)編譯的位置無關(guān)代碼。關(guān)于以上問題,還請(qǐng)賜教,非常感謝。


更新帖子,空白字符會(huì)被顯示成 ? ,所以重新發(fā)一遍


忘了說了,mstatus 寄存器已經(jīng)修改了,固件是有權(quán)限控制CPU跳轉(zhuǎn)的,但是PIC代碼沒有成功執(zhí)行



1、速度問題:BLE傳輸?shù)乃俣龋鹤钚¢g隔7.5ms,MTU最大247,嘗試將單連接多包開啟,這樣速度可以達(dá)到30+KB/s,注意需要在近距離的條件下,否則可能出現(xiàn)丟包的情況。直接參考speedtest例程查看測(cè)試的速度。

如果有BLE轉(zhuǎn)串口/USB等的功能,則速度會(huì)下降,可以參考BLE_UART例程,MTU開啟最大進(jìn)行測(cè)試。

2、noti發(fā)送失敗問題:在數(shù)據(jù)收發(fā)的時(shí)候需要進(jìn)行內(nèi)存分配,也就是從協(xié)議棧里面開辟一段堆用于數(shù)據(jù)的發(fā)送。noti會(huì)用到此功能。如果noti發(fā)送失敗,查看返回值,最明顯的現(xiàn)象是pending,這需要將協(xié)議棧緩存進(jìn)一步擴(kuò)大,或者直接在出現(xiàn)pending后重復(fù)調(diào)用發(fā)送即可。出現(xiàn)pending是可能的情況。

如果是其他的報(bào)錯(cuò),檢查代碼是否參數(shù)傳遞錯(cuò)誤,如handle。

如果是直接進(jìn)入hardfault,打印PC指針查看報(bào)錯(cuò),如執(zhí)行noti四字節(jié)對(duì)齊問題。則查看自行分配的緩存四字節(jié)對(duì)齊:__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];

3、使用其他編譯器:我們真誠(chéng)的邀請(qǐng)用戶對(duì)芯片做客制化的開發(fā)。但同時(shí)需要注意官方提供的開發(fā)工具只有MRS,如使用MRS出現(xiàn)問題可以留下反饋。針對(duì)使用vscode問題,后續(xù)如果提供類似開發(fā)工具會(huì)第一時(shí)間提供或者在該工程師博客留言獲取解決辦法。

4、CH582的精簡(jiǎn)庫(kù)只有從機(jī)功能,可以參考固定庫(kù):image.png

如果需要其他的精簡(jiǎn)庫(kù),發(fā)送郵件至郵箱:lpc@wch.cn,描述具體項(xiàng)目和應(yīng)用,我們進(jìn)行評(píng)估。

針對(duì)提到的代碼冗余,EVT代碼是為了適用所有開發(fā)者。

5、外掛FLASH可以參考V208的外掛FLASH。外掛FLASH可以用于存儲(chǔ)信息,但是無法用于運(yùn)行代碼。

CH32V20xEVT.ZIP - 南京沁恒微電子股份有限公司 (wch.cn)

6、單片機(jī)沒有動(dòng)態(tài)鏈接,無法使用fPIC。



@TECH_Lpc?好的,我和同事整理一下資料然后發(fā)郵件過去。




只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频