[FL-1816] Fix ble radio stack is alive check (#707)
* bt: fix bt_is_alive return, add bt_is_active * bt: fix bt_is_alive return * Cli: show heap usage in ps. * FuriHal: strict sequence for flash operations * Scripts: add stress test * Core: proper heap calculation. Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
b4ffc1f81b
commit
f05153ed5c
@ -67,17 +67,17 @@ int32_t bt_srv() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update statusbar
|
// Update statusbar
|
||||||
view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_alive());
|
view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_active());
|
||||||
|
|
||||||
BtMessage message;
|
BtMessage message;
|
||||||
while(1) {
|
while(1) {
|
||||||
furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK);
|
furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK);
|
||||||
if(message.type == BtMessageTypeUpdateStatusbar) {
|
if(message.type == BtMessageTypeUpdateStatusbar) {
|
||||||
// Update statusbar
|
// Update statusbar
|
||||||
view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_alive());
|
view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_active());
|
||||||
} else if(message.type == BtMessageTypeUpdateBatteryLevel) {
|
} else if(message.type == BtMessageTypeUpdateBatteryLevel) {
|
||||||
// Update battery level
|
// Update battery level
|
||||||
if(furi_hal_bt_is_alive()) {
|
if(furi_hal_bt_is_active()) {
|
||||||
battery_svc_update_level(message.data.battery_level);
|
battery_svc_update_level(message.data.battery_level);
|
||||||
}
|
}
|
||||||
} else if(message.type == BtMessageTypePinCodeShow) {
|
} else if(message.type == BtMessageTypePinCodeShow) {
|
||||||
|
@ -385,17 +385,19 @@ void cli_command_ps(Cli* cli, string_t args, void* context) {
|
|||||||
const uint8_t threads_num_max = 32;
|
const uint8_t threads_num_max = 32;
|
||||||
osThreadId_t threads_id[threads_num_max];
|
osThreadId_t threads_id[threads_num_max];
|
||||||
uint8_t thread_num = osThreadEnumerate(threads_id, threads_num_max);
|
uint8_t thread_num = osThreadEnumerate(threads_id, threads_num_max);
|
||||||
printf("%d threads in total:\r\n", thread_num);
|
printf(
|
||||||
printf("%-20s %-14s %-14s %s\r\n", "Name", "Stack start", "Stack alloc", "Stack watermark");
|
"%-20s %-14s %-8s %-8s %s\r\n", "Name", "Stack start", "Heap", "Stack", "Stack min free");
|
||||||
for(uint8_t i = 0; i < thread_num; i++) {
|
for(uint8_t i = 0; i < thread_num; i++) {
|
||||||
TaskControlBlock* tcb = (TaskControlBlock*)threads_id[i];
|
TaskControlBlock* tcb = (TaskControlBlock*)threads_id[i];
|
||||||
printf(
|
printf(
|
||||||
"%-20s 0x%-12lx %-14ld %ld\r\n",
|
"%-20s 0x%-12lx %-8d %-8ld %-8ld\r\n",
|
||||||
osThreadGetName(threads_id[i]),
|
osThreadGetName(threads_id[i]),
|
||||||
(uint32_t)tcb->pxStack,
|
(uint32_t)tcb->pxStack,
|
||||||
(uint32_t)(tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(uint32_t),
|
memmgr_heap_get_thread_memory(threads_id[i]),
|
||||||
osThreadGetStackSpace(threads_id[i]) * sizeof(uint32_t));
|
(uint32_t)(tcb->pxEndOfStack - tcb->pxStack + 1) * sizeof(StackType_t),
|
||||||
|
osThreadGetStackSpace(threads_id[i]));
|
||||||
}
|
}
|
||||||
|
printf("\r\nTotal: %d", thread_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_free(Cli* cli, string_t args, void* context) {
|
void cli_command_free(Cli* cli, string_t args, void* context) {
|
||||||
|
@ -155,19 +155,21 @@ void memmgr_heap_disable_thread_trace(osThreadId_t thread_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t memmgr_heap_get_thread_memory(osThreadId_t thread_id) {
|
size_t memmgr_heap_get_thread_memory(osThreadId_t thread_id) {
|
||||||
size_t leftovers = 0;
|
size_t leftovers = MEMMGR_HEAP_UNKNOWN;
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
{
|
{
|
||||||
memmgr_heap_thread_trace_depth++;
|
memmgr_heap_thread_trace_depth++;
|
||||||
MemmgrHeapAllocDict_t* alloc_dict =
|
MemmgrHeapAllocDict_t* alloc_dict =
|
||||||
MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id);
|
MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id);
|
||||||
furi_check(alloc_dict);
|
if(alloc_dict) {
|
||||||
MemmgrHeapAllocDict_it_t alloc_dict_it;
|
leftovers = 0;
|
||||||
for(MemmgrHeapAllocDict_it(alloc_dict_it, *alloc_dict);
|
MemmgrHeapAllocDict_it_t alloc_dict_it;
|
||||||
!MemmgrHeapAllocDict_end_p(alloc_dict_it);
|
for(MemmgrHeapAllocDict_it(alloc_dict_it, *alloc_dict);
|
||||||
MemmgrHeapAllocDict_next(alloc_dict_it)) {
|
!MemmgrHeapAllocDict_end_p(alloc_dict_it);
|
||||||
MemmgrHeapAllocDict_itref_t* data = MemmgrHeapAllocDict_ref(alloc_dict_it);
|
MemmgrHeapAllocDict_next(alloc_dict_it)) {
|
||||||
leftovers += data->value;
|
MemmgrHeapAllocDict_itref_t* data = MemmgrHeapAllocDict_ref(alloc_dict_it);
|
||||||
|
leftovers += data->value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memmgr_heap_thread_trace_depth--;
|
memmgr_heap_thread_trace_depth--;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MEMMGR_HEAP_UNKNOWN 0xFFFFFFFF
|
||||||
|
|
||||||
/** Memmgr heap enable thread allocation tracking
|
/** Memmgr heap enable thread allocation tracking
|
||||||
* @param thread_id - thread id to track
|
* @param thread_id - thread id to track
|
||||||
*/
|
*/
|
||||||
|
@ -24,7 +24,7 @@ void furi_hal_bt_start_advertising() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_stop_advertising() {
|
void furi_hal_bt_stop_advertising() {
|
||||||
if(furi_hal_bt_is_alive()) {
|
if(furi_hal_bt_is_active()) {
|
||||||
gap_stop_advertising();
|
gap_stop_advertising();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,6 +52,11 @@ void furi_hal_bt_dump_state(string_t buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_is_alive() {
|
bool furi_hal_bt_is_alive() {
|
||||||
|
BleGlueStatus status = APPE_Status();
|
||||||
|
return (status == BleGlueStatusBroken) || (status == BleGlueStatusStarted);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool furi_hal_bt_is_active() {
|
||||||
return gap_get_state() > GapStateIdle;
|
return gap_get_state() > GapStateIdle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +72,7 @@ bool furi_hal_bt_wait_startup() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_lock_flash() {
|
bool furi_hal_bt_lock_flash(bool erase_flag) {
|
||||||
if (!furi_hal_bt_wait_startup()) {
|
if (!furi_hal_bt_wait_startup()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -75,18 +80,25 @@ bool furi_hal_bt_lock_flash() {
|
|||||||
while (HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) {
|
while (HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) {
|
||||||
osDelay(1);
|
osDelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
|
|
||||||
HAL_FLASH_Unlock();
|
HAL_FLASH_Unlock();
|
||||||
|
|
||||||
while(LL_FLASH_IsOperationSuspended()) {};
|
if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
|
||||||
|
|
||||||
|
while(LL_FLASH_IsActiveFlag_OperationSuspended()) {};
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_unlock_flash() {
|
void furi_hal_bt_unlock_flash(bool erase_flag) {
|
||||||
SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
|
__enable_irq();
|
||||||
|
|
||||||
|
if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
|
||||||
|
|
||||||
HAL_FLASH_Lock();
|
HAL_FLASH_Lock();
|
||||||
|
|
||||||
HAL_HSEM_Release(CFG_HW_FLASH_SEMID, HSEM_CPU1_COREID);
|
HAL_HSEM_Release(CFG_HW_FLASH_SEMID, HSEM_CPU1_COREID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ size_t furi_hal_flash_get_free_page_count() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_flash_erase(uint8_t page, uint8_t count) {
|
bool furi_hal_flash_erase(uint8_t page, uint8_t count) {
|
||||||
if (!furi_hal_bt_lock_flash()) {
|
if (!furi_hal_bt_lock_flash(true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
FLASH_EraseInitTypeDef erase;
|
FLASH_EraseInitTypeDef erase;
|
||||||
@ -66,24 +66,24 @@ bool furi_hal_flash_erase(uint8_t page, uint8_t count) {
|
|||||||
erase.NbPages = count;
|
erase.NbPages = count;
|
||||||
uint32_t error;
|
uint32_t error;
|
||||||
HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error);
|
HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error);
|
||||||
furi_hal_bt_unlock_flash();
|
furi_hal_bt_unlock_flash(true);
|
||||||
return status == HAL_OK;
|
return status == HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_flash_write_dword(size_t address, uint64_t data) {
|
bool furi_hal_flash_write_dword(size_t address, uint64_t data) {
|
||||||
if (!furi_hal_bt_lock_flash()) {
|
if (!furi_hal_bt_lock_flash(false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data);
|
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data);
|
||||||
furi_hal_bt_unlock_flash();
|
furi_hal_bt_unlock_flash(false);
|
||||||
return status == HAL_OK;
|
return status == HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_flash_write_dword_from(size_t address, size_t source_address) {
|
bool furi_hal_flash_write_dword_from(size_t address, size_t source_address) {
|
||||||
if (!furi_hal_bt_lock_flash()) {
|
if (!furi_hal_bt_lock_flash(false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address);
|
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address);
|
||||||
furi_hal_bt_unlock_flash();
|
furi_hal_bt_unlock_flash(false);
|
||||||
return status == HAL_OK;
|
return status == HAL_OK;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ void furi_hal_bt_start_advertising() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_stop_advertising() {
|
void furi_hal_bt_stop_advertising() {
|
||||||
if(furi_hal_bt_is_alive()) {
|
if(furi_hal_bt_is_active()) {
|
||||||
gap_stop_advertising();
|
gap_stop_advertising();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,6 +52,11 @@ void furi_hal_bt_dump_state(string_t buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_is_alive() {
|
bool furi_hal_bt_is_alive() {
|
||||||
|
BleGlueStatus status = APPE_Status();
|
||||||
|
return (status == BleGlueStatusBroken) || (status == BleGlueStatusStarted);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool furi_hal_bt_is_active() {
|
||||||
return gap_get_state() > GapStateIdle;
|
return gap_get_state() > GapStateIdle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +72,7 @@ bool furi_hal_bt_wait_startup() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_bt_lock_flash() {
|
bool furi_hal_bt_lock_flash(bool erase_flag) {
|
||||||
if (!furi_hal_bt_wait_startup()) {
|
if (!furi_hal_bt_wait_startup()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -75,18 +80,25 @@ bool furi_hal_bt_lock_flash() {
|
|||||||
while (HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) {
|
while (HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) {
|
||||||
osDelay(1);
|
osDelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
|
|
||||||
HAL_FLASH_Unlock();
|
HAL_FLASH_Unlock();
|
||||||
|
|
||||||
while(LL_FLASH_IsOperationSuspended()) {};
|
if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
|
||||||
|
|
||||||
|
while(LL_FLASH_IsActiveFlag_OperationSuspended()) {};
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_bt_unlock_flash() {
|
void furi_hal_bt_unlock_flash(bool erase_flag) {
|
||||||
SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
|
__enable_irq();
|
||||||
|
|
||||||
|
if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
|
||||||
|
|
||||||
HAL_FLASH_Lock();
|
HAL_FLASH_Lock();
|
||||||
|
|
||||||
HAL_HSEM_Release(CFG_HW_FLASH_SEMID, HSEM_CPU1_COREID);
|
HAL_HSEM_Release(CFG_HW_FLASH_SEMID, HSEM_CPU1_COREID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ size_t furi_hal_flash_get_free_page_count() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_flash_erase(uint8_t page, uint8_t count) {
|
bool furi_hal_flash_erase(uint8_t page, uint8_t count) {
|
||||||
if (!furi_hal_bt_lock_flash()) {
|
if (!furi_hal_bt_lock_flash(true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
FLASH_EraseInitTypeDef erase;
|
FLASH_EraseInitTypeDef erase;
|
||||||
@ -66,24 +66,24 @@ bool furi_hal_flash_erase(uint8_t page, uint8_t count) {
|
|||||||
erase.NbPages = count;
|
erase.NbPages = count;
|
||||||
uint32_t error;
|
uint32_t error;
|
||||||
HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error);
|
HAL_StatusTypeDef status = HAL_FLASHEx_Erase(&erase, &error);
|
||||||
furi_hal_bt_unlock_flash();
|
furi_hal_bt_unlock_flash(true);
|
||||||
return status == HAL_OK;
|
return status == HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_flash_write_dword(size_t address, uint64_t data) {
|
bool furi_hal_flash_write_dword(size_t address, uint64_t data) {
|
||||||
if (!furi_hal_bt_lock_flash()) {
|
if (!furi_hal_bt_lock_flash(false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data);
|
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data);
|
||||||
furi_hal_bt_unlock_flash();
|
furi_hal_bt_unlock_flash(false);
|
||||||
return status == HAL_OK;
|
return status == HAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_flash_write_dword_from(size_t address, size_t source_address) {
|
bool furi_hal_flash_write_dword_from(size_t address, size_t source_address) {
|
||||||
if (!furi_hal_bt_lock_flash()) {
|
if (!furi_hal_bt_lock_flash(false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address);
|
HAL_StatusTypeDef status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, address, source_address);
|
||||||
furi_hal_bt_unlock_flash();
|
furi_hal_bt_unlock_flash(false);
|
||||||
return status == HAL_OK;
|
return status == HAL_OK;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,9 @@ void furi_hal_bt_start_advertising();
|
|||||||
/** Stop advertising */
|
/** Stop advertising */
|
||||||
void furi_hal_bt_stop_advertising();
|
void furi_hal_bt_stop_advertising();
|
||||||
|
|
||||||
|
/** Returns true if BLE is advertising */
|
||||||
|
bool furi_hal_bt_is_active();
|
||||||
|
|
||||||
/** Get BT/BLE system component state */
|
/** Get BT/BLE system component state */
|
||||||
void furi_hal_bt_dump_state(string_t buffer);
|
void furi_hal_bt_dump_state(string_t buffer);
|
||||||
|
|
||||||
@ -32,10 +35,10 @@ bool furi_hal_bt_wait_startup();
|
|||||||
* Lock shared access to flash controller
|
* Lock shared access to flash controller
|
||||||
* @return true if lock was successful, false if not
|
* @return true if lock was successful, false if not
|
||||||
*/
|
*/
|
||||||
bool furi_hal_bt_lock_flash();
|
bool furi_hal_bt_lock_flash(bool erase_flag);
|
||||||
|
|
||||||
/** Unlock shared access to flash controller */
|
/** Unlock shared access to flash controller */
|
||||||
void furi_hal_bt_unlock_flash();
|
void furi_hal_bt_unlock_flash(bool erase_flag);
|
||||||
|
|
||||||
/** Start ble tone tx at given channel and power */
|
/** Start ble tone tx at given channel and power */
|
||||||
void furi_hal_bt_start_tone_tx(uint8_t channel, uint8_t power);
|
void furi_hal_bt_start_tone_tx(uint8_t channel, uint8_t power);
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from flipper.storage import FlipperStorage
|
from flipper.storage import FlipperStorage
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import binascii
|
import binascii
|
||||||
import posixpath
|
import posixpath
|
||||||
|
import filecmp
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
class Main:
|
class Main:
|
||||||
@ -56,6 +59,16 @@ class Main:
|
|||||||
self.parser_list.add_argument("flipper_path", help="Flipper path", default="/")
|
self.parser_list.add_argument("flipper_path", help="Flipper path", default="/")
|
||||||
self.parser_list.set_defaults(func=self.list)
|
self.parser_list.set_defaults(func=self.list)
|
||||||
|
|
||||||
|
self.parser_stress = self.subparsers.add_parser("stress", help="Stress test")
|
||||||
|
self.parser.add_argument(
|
||||||
|
"-c", "--count", type=int, default=10, help="Iteration count"
|
||||||
|
)
|
||||||
|
self.parser_stress.add_argument("flipper_path", help="Flipper path")
|
||||||
|
self.parser_stress.add_argument(
|
||||||
|
"file_size", type=int, help="Test file size in bytes"
|
||||||
|
)
|
||||||
|
self.parser_stress.set_defaults(func=self.stress)
|
||||||
|
|
||||||
# logging
|
# logging
|
||||||
self.logger = logging.getLogger()
|
self.logger = logging.getLogger()
|
||||||
|
|
||||||
@ -262,6 +275,41 @@ class Main:
|
|||||||
storage.list_tree(self.args.flipper_path)
|
storage.list_tree(self.args.flipper_path)
|
||||||
storage.stop()
|
storage.stop()
|
||||||
|
|
||||||
|
def stress(self):
|
||||||
|
self.logger.error("This test is wearing out flash memory.")
|
||||||
|
self.logger.error("Never use it with internal storage(/int)")
|
||||||
|
|
||||||
|
if self.args.flipper_path.startswith(
|
||||||
|
"/int"
|
||||||
|
) or self.args.flipper_path.startswith("/any"):
|
||||||
|
self.logger.error("Stop at this point or device warranty will be void")
|
||||||
|
say = input("Anything to say? ").strip().lower()
|
||||||
|
if say != "void":
|
||||||
|
return
|
||||||
|
say = input("Why, Mr. Anderson? ").strip().lower()
|
||||||
|
if say != "because":
|
||||||
|
return
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
|
send_file_name = os.path.join(tmpdirname, "send")
|
||||||
|
receive_file_name = os.path.join(tmpdirname, "receive")
|
||||||
|
open(send_file_name, "w").write("A" * self.args.file_size)
|
||||||
|
storage = FlipperStorage(self.args.port)
|
||||||
|
storage.start()
|
||||||
|
if storage.exist_file(self.args.flipper_path):
|
||||||
|
self.logger.error("File exists, remove it first")
|
||||||
|
return
|
||||||
|
while self.args.count > 0:
|
||||||
|
storage.send_file(send_file_name, self.args.flipper_path)
|
||||||
|
storage.receive_file(self.args.flipper_path, receive_file_name)
|
||||||
|
if not filecmp.cmp(receive_file_name, send_file_name):
|
||||||
|
self.logger.error("Files mismatch")
|
||||||
|
break
|
||||||
|
storage.remove(self.args.flipper_path)
|
||||||
|
os.unlink(receive_file_name)
|
||||||
|
self.args.count -= 1
|
||||||
|
storage.stop()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
Main()()
|
Main()()
|
||||||
|
Loading…
Reference in New Issue
Block a user