From 4347cd904848f380263f183700f3297701623355 Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Fri, 15 Sep 2023 01:18:13 +0200 Subject: [PATCH 01/10] Add PyInstaller support for client --- .github/workflows/build_client.yml | 23 +++++++++++--- software/.gitignore | 3 ++ software/pyinstaller.spec | 46 +++++++++++++++++++++++++++ software/script/chameleon_cli_unit.py | 9 +++++- software/src/mfkey.c | 1 + 5 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 software/pyinstaller.spec diff --git a/.github/workflows/build_client.yml b/.github/workflows/build_client.yml index aabd58ff..31b01082 100644 --- a/.github/workflows/build_client.yml +++ b/.github/workflows/build_client.yml @@ -19,32 +19,47 @@ jobs: pre_command: | ? . bundle_command: | - Compress-Archive -Path software\* -DestinationPath client-windows.zip + Compress-Archive -Path software\dist\* -DestinationPath client-windows.zip - name: linux os: ubuntu-latest pre_command: | true bundle_command: | - (cd software && zip -r "$OLDPWD/client-linux.zip" .) + (cd software/dist && zip -r "$OLDPWD/client-linux.zip" .) - name: macos os: macos-latest pre_command: | true bundle_command: | - (cd software && zip -r "$OLDPWD/client-macos.zip" .) + (cd software/dist && zip -r "$OLDPWD/client-macos.zip" .) runs-on: ${{ matrix.os }} steps: - name: Check out the repo uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-sha == null && github.sha || inputs.checkout-sha }} + - name: Install PyInstaller and client dependencies + run: | + pip3 install pyinstaller + pip3 install -r software/script/requirements.txt - name: Run OS specific setup run: ${{ matrix.pre_command }} + - name: Compile native code + run: | + cd software/src + mkdir out + cd out + cmake .. + cmake --build . --config Release + - name: Run PyInstaller + run: | + cd software + pyinstaller pyinstaller.spec - name: Upload built client uses: actions/upload-artifact@v3 with: name: client-${{ matrix.name }} - path: software/* + path: software/dist/* - name: Zip up client for release run: ${{ matrix.bundle_command }} - name: Upload release artifacts diff --git a/software/.gitignore b/software/.gitignore index 8b762595..8f80c9a5 100644 --- a/software/.gitignore +++ b/software/.gitignore @@ -6,3 +6,6 @@ script/__pycache__ src/out # Ignore the compiled scripts script/*.pyc +# Ignore pyinstaller folders +build/ +dist/ \ No newline at end of file diff --git a/software/pyinstaller.spec b/software/pyinstaller.spec new file mode 100644 index 00000000..865aaad9 --- /dev/null +++ b/software/pyinstaller.spec @@ -0,0 +1,46 @@ +# -*- mode: python ; coding: utf-8 -*- + + +block_cipher = None + + +a = Analysis( + ['script/chameleon_cli_main.py'], + pathex=[], + binaries=[ + ("bin/*", "bin/"), + ], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False, +) +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + [], + name='chameleon_cli_main', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index 5d5aad5c..5e2b0d37 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -10,6 +10,7 @@ import serial.tools.list_ports import threading import struct +from pathlib import Path from platform import uname import chameleon_com @@ -38,6 +39,12 @@ 0x38: "SmartMX with MIFARE Classic 4K", } +if getattr(sys, 'frozen', False): + # in pyinstaller + default_cwd = str(Path(sys._MEIPASS) / "bin") +else: + # from source + default_cwd = str(Path(__file__).parent.parent / "bin") class BaseCLIUnit: @@ -81,7 +88,7 @@ def on_exec(self, args: argparse.Namespace): raise NotImplementedError("Please implement this") @staticmethod - def sub_process(cmd, cwd=os.path.abspath("bin/")): + def sub_process(cmd, cwd=default_cwd): class ShadowProcess: def __init__(self): self.output = "" diff --git a/software/src/mfkey.c b/software/src/mfkey.c index 5c3c47e0..0e566fb6 100644 --- a/software/src/mfkey.c +++ b/software/src/mfkey.c @@ -13,6 +13,7 @@ #include "crapto1.h" // MIFARE +extern int compare_uint64(const void *a, const void *b); int inline compare_uint64(const void *a, const void *b) { if (*(uint64_t *)b == *(uint64_t *)a) return 0; if (*(uint64_t *)b < * (uint64_t *)a) return 1; From 55b4053acb75317f89c5e3ae64c7e93bdab13ccf Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Wed, 27 Sep 2023 13:53:20 +0200 Subject: [PATCH 02/10] Changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76153192..e85fc4bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add PyInstaller support for CLI client (@augustozanellato) ## [v2.0.0][2023-09-26] - Changed APP_FW_VER now deduced from git tag vx.y.z (@doegox) From 6915ee19a4a9d97e2593d39baca328f3faf10031 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 27 Sep 2023 23:09:59 +0200 Subject: [PATCH 03/10] New DELETE_SLOT_TAG_NICK --- CHANGELOG.md | 1 + docs/protocol.md | 4 ++++ firmware/application/src/app_cmd.c | 20 ++++++++++++++++++++ firmware/application/src/data_cmd.h | 1 + software/script/chameleon_cli_unit.py | 16 ++++++++++++++++ software/script/chameleon_cmd.py | 14 ++++++++++++++ 6 files changed, 56 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e85fc4bf..535f3ff4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Add PyInstaller support for CLI client (@augustozanellato) ## [v2.0.0][2023-09-26] + - Added `hw slot nick delete` and DELETE_SLOT_TAG_NICK (@doegox) - Changed APP_FW_VER now deduced from git tag vx.y.z (@doegox) - Changed initial button wakeup from 4 to 8 seconds (@aramova) - Added MIFARE Ultralight reading features (@FlUxIuS & @doegox) diff --git a/docs/protocol.md b/docs/protocol.md index fffc940e..8d333d9c 100644 --- a/docs/protocol.md +++ b/docs/protocol.md @@ -146,6 +146,10 @@ Notes: the returned string is the output of `git describe --abbrev=7 --dirty --a * Command: no data * Response: no data. Status is `STATUS_DEVICE_SUCCESS` or `STATUS_FLASH_WRITE_FAIL`. The device will reboot shortly after this command. * CLI: cf `hw factory_reset` +### 1021: DELETE_SLOT_TAG_NICK +* Command: 2 bytes. `slot_number|sense_type` with `slot_number` between 0 and 7 and `sense_type` according to `tag_sense_type_t` enum. +* Response: no data +* CLI: cf `hw slot nick delete` ### 1023: GET_ENABLED_SLOTS * Command: no data * Response: 16 bytes, 8*2 bool = `0x00` or `0x01`, 2 bytes for each slot from 0 to 7, as `enabled_hf|enabled_lf` diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index 5332c09c..23bd09db 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -792,6 +792,25 @@ static data_frame_tx_t *cmd_processor_get_slot_tag_nick(uint16_t cmd, uint16_t s return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, buffer[0], &buffer[1]); } +static data_frame_tx_t *cmd_processor_delete_slot_tag_nick(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { + if (length != 2) { + return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL); + } + uint8_t slot = data[0]; + uint8_t sense_type = data[1]; + fds_slot_record_map_t map_info; + + if (slot >= TAG_MAX_SLOT_NUM || (sense_type != TAG_SENSE_HF && sense_type != TAG_SENSE_LF)) { + return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL); + } + get_fds_map_by_slot_sense_type_for_nick(slot, sense_type, &map_info); + bool ret = fds_delete_sync(map_info.id, map_info.key); + if (!ret) { + return data_frame_make(cmd, STATUS_FLASH_WRITE_FAIL, 0, NULL); + } + return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 0, NULL); +} + static data_frame_tx_t *cmd_processor_mf1_get_emulator_config(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { uint8_t mf1_info[5] = {}; mf1_info[0] = nfc_tag_mf1_is_detection_enable(); @@ -965,6 +984,7 @@ static cmd_data_map_t m_data_cmd_map[] = { { DATA_CMD_GET_ACTIVE_SLOT, NULL, cmd_processor_get_active_slot, NULL }, { DATA_CMD_GET_SLOT_INFO, NULL, cmd_processor_get_slot_info, NULL }, { DATA_CMD_WIPE_FDS, NULL, cmd_processor_wipe_fds, NULL }, + { DATA_CMD_DELETE_SLOT_TAG_NICK, NULL, cmd_processor_delete_slot_tag_nick, NULL }, { DATA_CMD_GET_ENABLED_SLOTS, NULL, cmd_processor_get_enabled_slots, NULL }, { DATA_CMD_DELETE_SLOT_SENSE_TYPE, NULL, cmd_processor_delete_slot_sense_type, NULL }, { DATA_CMD_GET_BATTERY_INFO, NULL, cmd_processor_get_battery_info, NULL }, diff --git a/firmware/application/src/data_cmd.h b/firmware/application/src/data_cmd.h index 267e09c4..b0ad7511 100644 --- a/firmware/application/src/data_cmd.h +++ b/firmware/application/src/data_cmd.h @@ -28,6 +28,7 @@ #define DATA_CMD_GET_ACTIVE_SLOT (1018) #define DATA_CMD_GET_SLOT_INFO (1019) #define DATA_CMD_WIPE_FDS (1020) +#define DATA_CMD_DELETE_SLOT_TAG_NICK (1021) #define DATA_CMD_GET_ENABLED_SLOTS (1023) #define DATA_CMD_DELETE_SLOT_SENSE_TYPE (1024) diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index 5e2b0d37..203850a6 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -1392,6 +1392,22 @@ def on_exec(self, args: argparse.Namespace): print(f' - Get tag nick name for slot {slot_num}: {res.decode(encoding="utf8")}') +@hw_slot_nick.command('delete', 'Delete tag nick name for slot') +class HWSlotNickGet(SlotIndexRequireUnit, SenseTypeRequireUnit): + def args_parser(self) -> ArgumentParserNoExit or None: + parser = ArgumentParserNoExit() + self.add_slot_args(parser) + self.add_sense_type_args(parser) + return parser + + # hw slot nick delete -s 1 -st 1 + def on_exec(self, args: argparse.Namespace): + slot_num = args.slot + sense_type = args.sense_type + res = self.cmd.delete_slot_tag_nick(slot_num, sense_type) + print(f' - Delete tag nick name for slot {slot_num}: {res.decode(encoding="utf8")}') + + @hw_slot.command('update', 'Update config & data to device flash') class HWSlotUpdate(DeviceRequiredUnit): def args_parser(self) -> ArgumentParserNoExit or None: diff --git a/software/script/chameleon_cmd.py b/software/script/chameleon_cmd.py index 0e79eceb..2e5812e4 100644 --- a/software/script/chameleon_cmd.py +++ b/software/script/chameleon_cmd.py @@ -37,6 +37,8 @@ DATA_CMD_WIPE_FDS = 1020 +DATA_CMD_DELETE_SLOT_TAG_NICK = 1021 + DATA_CMD_GET_ENABLED_SLOTS = 1023 DATA_CMD_DELETE_SLOT_SENSE_TYPE = 1024 @@ -912,6 +914,18 @@ def get_slot_tag_nick(self, slot: SlotNumber, sense_type: TagSenseType): data = struct.pack('!BB', SlotNumber.to_fw(slot), sense_type) return self.device.send_cmd_sync(DATA_CMD_GET_SLOT_TAG_NICK, data) + @expect_response(chameleon_status.Device.STATUS_DEVICE_SUCCESS) + def delete_slot_tag_nick(self, slot: SlotNumber, sense_type: TagSenseType): + """ + Delete the nick name of the slot + :param slot: Card slot number + :param sense_type: field type + :return: + """ + # SlotNumber() will raise error for us if slot not in slot range + data = struct.pack('!BB', SlotNumber.to_fw(slot), sense_type) + return self.device.send_cmd_sync(DATA_CMD_DELETE_SLOT_TAG_NICK, data) + @expect_response(chameleon_status.Device.STATUS_DEVICE_SUCCESS) def mf1_get_emulator_config(self): """ From 4a94db10bf9edf876431c6091f678ba96797f678 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 27 Sep 2023 23:23:39 +0200 Subject: [PATCH 04/10] fix bug in default slot config --- firmware/application/src/rfid/nfctag/tag_emulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/src/rfid/nfctag/tag_emulation.c b/firmware/application/src/rfid/nfctag/tag_emulation.c index a7ebdabb..77cc0bd4 100644 --- a/firmware/application/src/rfid/nfctag/tag_emulation.c +++ b/firmware/application/src/rfid/nfctag/tag_emulation.c @@ -72,7 +72,7 @@ static tag_slot_config_t slotConfig ALIGN_U32 = { .slots = { { .enabled_hf = true, .enabled_lf = true, .tag_hf = TAG_TYPE_MIFARE_1024, .tag_lf = TAG_TYPE_EM410X, }, // 1 { .enabled_hf = true, .enabled_lf = false, .tag_hf = TAG_TYPE_MIFARE_1024, .tag_lf = TAG_TYPE_UNDEFINED, }, // 2 - { .enabled_hf = true, .enabled_lf = true, .tag_hf = TAG_TYPE_UNDEFINED, .tag_lf = TAG_TYPE_EM410X, }, // 3 + { .enabled_hf = false, .enabled_lf = true, .tag_hf = TAG_TYPE_UNDEFINED, .tag_lf = TAG_TYPE_EM410X, }, // 3 { .enabled_hf = false, .enabled_lf = false, .tag_hf = TAG_TYPE_UNDEFINED, .tag_lf = TAG_TYPE_UNDEFINED, }, // 4 { .enabled_hf = false, .enabled_lf = false, .tag_hf = TAG_TYPE_UNDEFINED, .tag_lf = TAG_TYPE_UNDEFINED, }, // 5 { .enabled_hf = false, .enabled_lf = false, .tag_hf = TAG_TYPE_UNDEFINED, .tag_lf = TAG_TYPE_UNDEFINED, }, // 6 From 5519715c10b0c446c5b8e5ba6776704af0dec312 Mon Sep 17 00:00:00 2001 From: DXL <64101226@qq.com> Date: Thu, 28 Sep 2023 16:43:50 +0800 Subject: [PATCH 05/10] Update README.md --- README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.md b/README.md index 49869948..71b62c9f 100644 --- a/README.md +++ b/README.md @@ -18,15 +18,6 @@ Read the [available documentation](docs/README.md). * [ChameleonUltraGUI](https://github.com/GameTec-live/ChameleonUltraGUI) -# Software Roadmap - -|No.|Functionality to achieve| Date | Achieved ? | Contributors | -|:--------------:|:--------------:|:--------:|:------------:|:------------:| -|1| :--------------:|:--------------:|:--------------:|:--------------:| -|2| :--------------:|:--------------:|:--------------:|:--------------:| -|3| :--------------:|:--------------:|:--------------:|:--------------:| - - # Videos *Beware some of the instructions might have changed since recording, check the current documentation when in doubt!* From 48bf8524657513c611f1fd2e894167f5de433005 Mon Sep 17 00:00:00 2001 From: DXL <64101226@qq.com> Date: Thu, 28 Sep 2023 17:27:43 +0800 Subject: [PATCH 06/10] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 71b62c9f..484cfcf0 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ Anywhere else: [Sneaktechnology](https://sneaktechnology.com) / [Aliexpress by R Read the [available documentation](docs/README.md). +# Public Roadmap with reference to [Here](https://github.com/RfidResearchGroup/ChameleonUltra/wiki/Public-Roadmap) + + + # Compatible applications * [ChameleonUltraGUI](https://github.com/GameTec-live/ChameleonUltraGUI) From 7efe23edb243dd698dd18082b597f62b99a8ce08 Mon Sep 17 00:00:00 2001 From: DXL <64101226@qq.com> Date: Thu, 28 Sep 2023 17:28:09 +0800 Subject: [PATCH 07/10] Update README.md --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 484cfcf0..0b794490 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,25 @@ Read the [available documentation](docs/README.md). # Public Roadmap with reference to [Here](https://github.com/RfidResearchGroup/ChameleonUltra/wiki/Public-Roadmap) - +Table for future functionality progress +--------------------------------- + +|No.|Functionality to achieve| Date | In Progress / Achieved ? | Contributors | RRG will reward | +|:--------------:|:--------------:|:--------:|:------------:|:------------:|:------------:| +|1| Adding DESfire Support|28/09/2023|:--------------:|:--------------:|:------------:| +|2| Adding Indala Emulation|28/09/2023|:--------------:|:--------------:|:------------:| +|3| Adding HID Prox 26 bit Emulation|28/09/2023|:--------------:|:--------------:|:------------:| +|4| Adding custom keys for t5577 read|28/09/2023|:------------:|:------------:|:------------:| +|5|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|6|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|7|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|8|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|9|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|10|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|11|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|12|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|13|:--------------:|:--------------:|:------------:|:------------:|:------------:| +|14|:--------------:|:--------------:|:------------:|:------------:|:------------:| # Compatible applications From 226efbc3d5dbe90ba4c188e8c5ceeece674129b5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Oct 2023 00:30:05 +0200 Subject: [PATCH 08/10] Fixed watchdog trigger during `hw factory_reset` --- CHANGELOG.md | 3 ++- firmware/application/src/utils/fds_util.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 535f3ff4..ca8b6db9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] - - Add PyInstaller support for CLI client (@augustozanellato) + - Fixed watchdog trigger during `hw factory_reset` (@doegox) + - Added PyInstaller support for CLI client (@augustozanellato) ## [v2.0.0][2023-09-26] - Added `hw slot nick delete` and DELETE_SLOT_TAG_NICK (@doegox) diff --git a/firmware/application/src/utils/fds_util.c b/firmware/application/src/utils/fds_util.c index 8de52c7e..23d28b84 100644 --- a/firmware/application/src/utils/fds_util.c +++ b/firmware/application/src/utils/fds_util.c @@ -1,5 +1,5 @@ #include "fds_util.h" - +#include "bsp_wdt.h" #define NRF_LOG_MODULE_NAME fds_sync #include "nrf_log.h" @@ -306,7 +306,9 @@ static bool fds_next_record_delete_sync() { bool fds_wipe(void) { NRF_LOG_INFO("Full fds wipe requested"); - while (fds_next_record_delete_sync()) {} + while (fds_next_record_delete_sync()) { + bsp_wdt_feed(); + } fds_gc_sync(); return true; } From 606ec02e30c5d771b44635388dd3359995b9c160 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Oct 2023 00:31:38 +0200 Subject: [PATCH 09/10] Added support for timestamped comments in CLI via `rem`, `;`, `%` or `#` --- CHANGELOG.md | 1 + software/script/chameleon_cli_main.py | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca8b6db9..9a992507 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added support for timestamped comments in CLI via `rem`, `;`, `%` or `#` (@doegox) - Fixed watchdog trigger during `hw factory_reset` (@doegox) - Added PyInstaller support for CLI client (@augustozanellato) diff --git a/software/script/chameleon_cli_main.py b/software/script/chameleon_cli_main.py index b58eb65b..6682ac8c 100755 --- a/software/script/chameleon_cli_main.py +++ b/software/script/chameleon_cli_main.py @@ -9,6 +9,7 @@ import os import pathlib import prompt_toolkit +from datetime import datetime from prompt_toolkit.formatted_text import ANSI from prompt_toolkit.history import FileHistory @@ -127,6 +128,18 @@ def startCLI(self): # parse cmd argv = cmd_str.split() root_cmd = argv[0] + # look for comments + if root_cmd == "rem" or root_cmd[0] in ";#%": + # precision: second + # iso_timestamp = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') + # precision: nanosecond (note that the comment will take some time too, ~75ns, check your system) + iso_timestamp = datetime.utcnow().isoformat() + 'Z' + if root_cmd[0] in ";#%": + comment = ' '.join([root_cmd[1:]]+argv[1:]).strip() + else: + comment = ' '.join(argv[1:]).strip() + print(f"{iso_timestamp} remark: {comment}") + continue if root_cmd not in chameleon_cli_unit.root_commands: # No matching command group print("".ljust(18, "-") + "".ljust(10) + "".ljust(30, "-")) From 42b715575cb72c06880f9a85eb8692bfbc64d71e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 1 Oct 2023 22:13:46 +0200 Subject: [PATCH 10/10] Changed CLI threads polling into blocking reads, to reduce CPU usage --- CHANGELOG.md | 1 + software/script/chameleon_com.py | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a992507..5a9ea336 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed CLI threads polling into blocking reads, to reduce CPU usage (@doegox) - Added support for timestamped comments in CLI via `rem`, `;`, `%` or `#` (@doegox) - Fixed watchdog trigger during `hw factory_reset` (@doegox) - Added PyInstaller support for CLI client (@augustozanellato) diff --git a/software/script/chameleon_com.py b/software/script/chameleon_com.py index eeee8d0b..726b61ea 100644 --- a/software/script/chameleon_com.py +++ b/software/script/chameleon_com.py @@ -5,6 +5,8 @@ import serial import chameleon_status +# each thread is waiting for its data for 100 ms before looping again +THREAD_BLOCKING_TIMEOUT = 0.1 class NotOpenException(Exception): """ @@ -82,7 +84,7 @@ def open(self, port): except Exception: # not all serial support dtr, e.g. virtual serial over BLE pass - self.serial_instance.timeout = 0 # do not block + self.serial_instance.timeout = THREAD_BLOCKING_TIMEOUT # clear variable self.send_data_queue.queue.clear() self.wait_response_map.clear() @@ -208,8 +210,6 @@ def thread_data_receive(self): data_buffer.clear() continue data_position += 1 - else: - time.sleep(0.001) def thread_data_transfer(self): """ @@ -218,10 +218,10 @@ def thread_data_transfer(self): """ while self.isOpen(): # get a task from queue(if exists) - if self.send_data_queue.empty(): - time.sleep(0.001) + try: + task = self.send_data_queue.get(block=True, timeout=THREAD_BLOCKING_TIMEOUT) + except queue.Empty: continue - task = self.send_data_queue.get() task_cmd = task['cmd'] task_timeout = task['timeout'] task_close = task['close'] @@ -262,7 +262,7 @@ def thread_check_timeout(self): else: # sync mode, set timeout flag self.wait_response_map[task_cmd]['is_timeout'] = True - time.sleep(0.001) + time.sleep(THREAD_BLOCKING_TIMEOUT) def make_data_frame_bytes(self, cmd: int, data: bytearray = None, status: int = 0) -> bytearray: """