Układy Beken są znane już od dłuższego czasu, ale z tego, co mi wiadomo, nie istnieje żaden emulator Beken. Mamy nasz OBK Simulator , ale jest to w zasadzie port oprogramowania układowego OBK na systemy Windows/Linux, a nie prawdziwy emulator, który próbuje naśladować układ Beken poprzez wykonywanie jego instrukcji na poziomie sprzętowym. Jednak, jak niedawno pokazałem na przykładzie ALI M3801 , stworzenie podstawowego przepływu sterowania za pomocą biblioteki Capstone w języku Python jest stosunkowo proste. W tym wątku przedstawię podstawowy zarys mojego symulatora Beken – jest to wciąż wczesna wersja proof of concept, ale już teraz daje naprawdę obiecujące wyniki!
Podstawową ideą jest tutaj wykorzystanie istniejących bibliotek Pythona do wykonania najtrudniejszych zadań. Zdecydowałem się na Capstone do deasemblacji kodu ARM/Thumb oraz Unicorn Engine (opartego na QEMU) do właściwej emulacji procesora. Działa to w większości od razu po uruchomieniu, ponieważ układy Beken, takie jak BK7231, są po prostu standardowymi architekturami ARM9 (ARM968E-S). Jedyną naprawdę skomplikowaną częścią jest symulacja rejestrów sprzętowych specyficznych dla Beken, aby oprogramowanie układowe nie utknęło w pętli nieskończonej podczas próby komunikacji z pasmem podstawowym Wi-Fi lub zegarami sprzętowymi.
Jak dotąd stworzyłem jedynie bardzo podstawowy szkic, próbując „złapać” razem tylko kilka podstawowych operacji, aby log debugowania był wyświetlany poprawnie. Oto kilka przykładowych logów wygenerowanych przez aktualną wersję narzędzia (w momencie pisania tego tekstu):
Pierwszy test – BK7231T_QIO_Woox_R5111_2023-14-10-23-46-06:
Running simulator (UART Only) for: W:\GIT\BekenSimulator\references\FlashDumps\IoT\BK7231T\BK7231T_QIO_Woox_R5111_2023-14-10-23-46-06.bin
prvHeapInit-start addr:0x4203d0, size:130096
[01-01 18:12:15 TUYA Info][mqc_app.c:175] mqc app init ...
[01-01 18:12:15 TUYA Info][sf_mqc_cb.c:42] register mqc app callback
[01-01 18:12:15 TUYA Debug][mqc_app.c:118] mq_pro:5 mqc_handler_cnt:1
[01-01 18:12:15 TUYA Debug][mqc_app.c:118] mq_pro:31 mqc_handler_cnt:2
[01-01 18:12:15 TUYA Err][uf_flash_file_app.c:411] uf_get_size err,filepath:log_seq_stat,ret:4
[01-01 18:12:15 TUYA Err][uf_flash_file_app.c:266] uf_open log_seq_stat err 4
[01-01 18:12:15 TUYA Err][log_seq.c:701] log stats open fail.
[01-01 18:12:15 TUYA Debug][svc_online_log.c:288] svc online log init success
[01-01 18:12:15 TUYA Err][tuya_ws_db.c:314] kvs_read fails gw_bi -1
[01-01 18:12:15 TUYA Err][ws_db_gw.c:111] gw base read fails -935
[01-01 18:12:15 TUYA Debug][tuya_bt_sdk.c:89] ty bt cmmod register finish 1
[01-01 18:12:15 TUYA Debug][tuya_ble_api.c:301] ble sdk inited
!!!!!!!!!!tuya_bt_port_init
No TLV header found in flash
No TLV header found in flash
[01-01 18:12:15 TUYA Debug][tuya_ble_api.c:337] ble sdk re_inited
[01-01 18:12:15 TUYA Notice][tuya_bt_sdk.c:130] ty bt sdk init success finish
[01-01 18:12:15 TUYA Notice][light_system.c:2196] go to pre device!
[01-01 18:12:15 TUYA Err][uf_flash_file_app.c:266] uf_open oem_cfg err 4
[01-01 18:12:15 TUYA Err][soc_flash.c:196] uf file can't open and read data!
[01-01 18:12:15 TUYA Err][user_flash.c:154] oem cfg data read error!
[01-01 18:12:15 TUYA Err][device_config_load.c:444] oem data ERROR
[01-01 18:12:15 TUYA Notice][light_init.c:38] oem cfg load error!
[01-01 18:12:15 TUYA Err][light_init.c:241] Light hardware init error!
[01-01 18:12:15 TUYA Notice][light_system.c:2199] Fast boot error!
[01-01 18:12:15 TUYA Notice][simple_flash.c:432] key_addr: 0x1ee000 block_sz 4096
[01-01 18:12:15 TUYA Err][simple_flash.c:452] key data is not matched magic(0x3a2d3e45),crc32(0xe2d8782c)
[01-01 18:12:15 TUYA Notice][simple_flash.c:486] init key:
0xcb 0x4e 0x3e 0xa4 0x0 0x30 0x9d 0xab 0x65 0x6d 0x8d 0xbf 0xe4 0xb9 0x3f 0x35
[01-01 18:12:15 TUYA Err][simple_flash.c:691] user area read != write! 6
[01-01 18:12:15 TUYA Err][tuya_ws_db.c:442] db init fails -1
[01-01 18:12:15 TUYA Err][tuya_iot_com_api.c:311] db init fails -1
[01-01 18:12:15 TUYA Notice][tuya_main.c:311] **********[oem_bk7231s_light_ty] [2.9.6] compiled at Oct 29 2020 14:38:00**********
No TLV header found in flash
No TLV header found in flash
[bk]tx_txdesc_flush
[rx_iq]rx_amp_err_rd: 0xffffffe8
[rx_iq]rx_phase_err_rd: 0xffffffcb
[rx_iq]rx_ty2_rd: 0x001
*********** finally result **********
gtx_dcorMod : 0x8
gtx_dcorPA : 0xa
gtx_pre_gain : 0xe
gtx_i_dc_comp : 0x241
gtx_q_dc_comp : 0x241
gtx_i_gain_comp : 0x3ff
gtx_q_gain_comp : 0x3ff
gtx_ifilter_corner over: 0x3d
gtx_qfilter_corner over: 0x3d
gtx_phase_comp : 0x2ff
gtx_phase_ty2 : 0x221
gbias_after_cal : 0x2
gav_tssi : 0x2
g_rx_dc_gain_tab 0 over: 0x1ff01ff
g_rx_dc_gain_tab 1 over: 0x1ff01ff
g_rx_dc_gain_tab 2 over: 0x1ff01ff
g_rx_dc_gain_tab 3 over: 0x1ff01ff
g_rx_dc_gain_tab 4 over: 0x1ff01ff
g_rx_dc_gain_tab 5 over: 0x1ff01ff
g_rx_dc_gain_tab 6 over: 0x1ff01ff
g_rx_dc_gain_tab 7 over: 0x1ff01ff
grx_amp_err_wr : 0x20c
grx_phase_err_wr : 0x3e6
**************************************
NO TXID found in flash, use def temp:280
temp in flash is:280
NO TXID found in flash, use lpf i&q:61, 61
NO TXID found in flash, use def xtal:25
xtal in flash is:25
-----pwr_gain:12, g_idx:12, shift_b:0, shift_g:0
-----[pwr_gain]12
Initializing TCP/IP stack
Drugi test – OOBK 1.18.300:
Running simulator (UART Only) for: W:\GIT\BekenSimulator\firmwares\OpenBK7231T_QIO_1.18.300.bin
prvHeapInit-start addr:0x41f390, size:134256
OpenBK7231T, version 1.18.300
Entering initLog()...
Commands registered!
initLog() done!
Info:MAIN:Main_Init_Before_Delay
Main_Init_Before_Delay
Warn:CFG:CFG_InitAndLoad: Config crc or ident mismatch. Default config will be loaded.
No TLV header found in flash
No TLV header found in flash
Info:CFG:CFG_SetDefaultLEDCorrectionTable: setting defaults
Info:NTP:CLOCK driver initialized.
Error:CMD:lfs is absent
Info:GEN:PIN_SetupPins pins have been set up.
Info:MAIN:Main_Init_Before_Delay done
Main_Init_Before_Delay done
Info:MAIN:Main_Init_Delay
Main_Init_Delay
No TLV header found in flash
No TLV header found in flash
[bk]tx_txdesc_flush
[rx_iq]rx_amp_err_rd: 0xffffffe8
[rx_iq]rx_phase_err_rd: 0xffffffcb
[rx_iq]rx_ty2_rd: 0x001
*********** finally result **********
gtx_dcorMod : 0x8
gtx_dcorPA : 0xa
gtx_pre_gain : 0xe
gtx_i_dc_comp : 0x241
gtx_q_dc_comp : 0x241
gtx_i_gain_comp : 0x3ff
gtx_q_gain_comp : 0x3ff
gtx_ifilter_corner over: 0x3d
gtx_qfilter_corner over: 0x3d
gtx_phase_comp : 0x2ff
gtx_phase_ty2 : 0x221
gbias_after_cal : 0x2
gav_tssi : 0x2
g_rx_dc_gain_tab 0 over: 0x1ff01ff
g_rx_dc_gain_tab 1 over: 0x1ff01ff
g_rx_dc_gain_tab 2 over: 0x1ff01ff
g_rx_dc_gain_tab 3 over: 0x1ff01ff
g_rx_dc_gain_tab 4 over: 0x1ff01ff
g_rx_dc_gain_tab 5 over: 0x1ff01ff
g_rx_dc_gain_tab 6 over: 0x1ff01ff
g_rx_dc_gain_tab 7 over: 0x1ff01ff
grx_amp_err_wr : 0x20c
grx_phase_err_wr : 0x3e6
**************************************
NO TXID found in flash, use def temp:280
temp in flash is:280
NO TXID found in flash, use lpf i&q:61, 61
NO TXID found in flash, use def xtal:25
xtal in flash is:25
-----pwr_gain:12, g_idx:12, shift_b:0, shift_g:0
-----[pwr_gain]12
Initializing TCP/IP stack
Info:MAIN:Main_Init_Delay done
Main_Init_Delay done
Info:MAIN:Main_Init_After_Delay
Info:MAIN:Using SSID []
Info:MAIN:Using Pass []
Error:HTTP:Created HTTP SV thread with (stack=2048)
Info:MQTT:MQTT_RegisterCallback called for bT obk8C000000/ subT obk8C000000/+/set
Info:MQTT:MQTT_RegisterCallback called for bT bekens_t/ subT bekens_t/+/set
Info:MQTT:MQTT_RegisterCallback called for bT cmnd/obk8C000000/ subT cmnd/obk8C000000/+
Info:MQTT:MQTT_RegisterCallback called for bT cmnd/bekens_t/ subT cmnd/bekens_t/+
Info:MQTT:MQTT_RegisterCallback called for bT obk8C000000/ subT obk8C000000/+/get
Info:MQTT:MQTT_RegisterCallback called for bT homeassistant/ subT homeassistant/+
Info:CMD:CMD_StartScript: started @startup at the beginning
Error:CMD:LFS_ReadFile: lfs is absent
Info:CMD:CMD_StartScript: failed to get file autoexec.bat
Info:MAIN:Main_Init_After_Delay done
REKLAMA
Test z bootloaderem – jednym z Woox:
Running simulator (UART Only) for: W:\GIT\BekenSimulator\references\FlashDumps\IoT\BK7231T\BK7231T_QIO_Woox_R5111_2023-14-10-23-46-06.bin
V:BK7231S_1.0.5
CPSR:400001D3
R0:00000000
R1:00000000
R2:00000000
R3:00000000
R4:00000000
R13:00000000
R14(LR):00000000
ST:00000000
J 0x10000
prvHeapInit-start addr:0x4203d0, size:130096
[01-01 18:12:15 TUYA Info][mqc_app.c:175] mqc app init ...
[01-01 18:12:15 TUYA Info][sf_mqc_cb.c:42] register mqc app callback
[01-01 18:12:15 TUYA Debug][mqc_app.c:118] mq_pro:5 mqc_handler_cnt:1
[01-01 18:12:15 TUYA Debug][mqc_app.c:118] mq_pro:31 mqc_handler_cnt:2
[01-01 18:12:15 TUYA Err][uf_flash_file_app.c:411] uf_get_size err,filepath:log_seq_stat,ret:4
[01-01 18:12:15 TUYA Err][uf_flash_file_app.c:266] uf_open log_se
Poszedłem też o krok dalej i postanowiłem przetestować kilka operacji matematycznych. Liczby całkowite i zmiennoprzecinkowe. Dodałem następujący fragment kodu do funkcji Main_Init_Before_Delay:
Kod: C / C++
Działa bez zarzutu i wyświetla oczekiwany wynik:
Running simulator (UART Only) for: W:\GIT\BekenSimulator\firmwares\OpenBK7231T_QIO_1.18.300_mathDemo.bin
prvHeapInit-start addr:0x41f390, size:134256
OpenBK7231T, version 2178_merge_f1fd73da79fc
Entering initLog()...
Commands registered!
initLog() done!
Info:MAIN:Main_Init_Before_Delay
Main_Init_Before_Delay
Info:MAIN:integer test
Info:MAIN:a = 123
Info:MAIN:float test
Info:MAIN:x = 3.140000
Info:MAIN:y = 1.860000
Info:MAIN:x + y = 5.000000
Warn:CFG:CFG_InitAndLoad: Config crc or ident mismatch. Default config will be loaded.
co dowodzi, że emulator poprawnie wykonuje procedury soft-float (libgcc) skompilowane w oprogramowaniu układowym, co oznacza, że podstawowa emulacja instrukcji ARM przebiega bezbłędnie!
Podsumowując, podstawowa emulacja serii BK7231 jest całkowicie wykonalna i otwiera naprawdę obiecujące możliwości na przyszłość. Potencjalnie moglibyśmy przeprowadzać automatyczne testy dla OpenBeken, debugować awarie bez konieczności korzystania ze sprzętu, a nawet po prostu dowiedzieć się więcej o tym, jak SDK Tuya współdziała z pasmem podstawowym. Wciąż pozostaje mnóstwo pracy nad symulacją rejestrów sprzętowych, urządzeń peryferyjnych oraz zainicjowaniem Wi-Fi, ale udało nam się już przejść przez bootloader i dotrzeć do głównej logiki aplikacji. Kolejnym celem będzie prawdopodobnie przejście przez etap Info:MAIN:Main_Init_After_Delay i dotarcie do pętli OpenBeken uruchamianej „co sekundę”, ponieważ wydaje się, że program jeszcze do niej nie dociera… wymaga to dalszej analizy.
Jeśli ktoś ma ochotę się tym pobawić, zapraszam do zapoznania się z kodem na GitHubie. Zachęcam do wniesienia własnego wkładu lub po prostu uruchomienia kodu, aby zobaczyć, jak działa ta magia.
Repozytorium:
https://github.com/openshwprojects/BekenEmulator
Fajne? Ranking DIY Pomogłem? Kup mi kawę.