[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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich