# Refactoring: source code docstrings
This commit is contained in:
parent
0f54c35be6
commit
31e3237b06
21 changed files with 12 additions and 64 deletions
|
|
@ -15,8 +15,6 @@
|
||||||
| Загрузчик (⏳ запланирован) | `firmware/bootloader/` | A/B обновление через uSD. Обновляется только через USB ROM + blhost / SWD |
|
| Загрузчик (⏳ запланирован) | `firmware/bootloader/` | A/B обновление через uSD. Обновляется только через USB ROM + blhost / SWD |
|
||||||
| Production прошивка (⏳ запланирован) | `firmware/tft_app/` | Приложение с реализацией логики лифтового индикатора. Обновляется загрузчиком |
|
| Production прошивка (⏳ запланирован) | `firmware/tft_app/` | Приложение с реализацией логики лифтового индикатора. Обновляется загрузчиком |
|
||||||
|
|
||||||
`bootloader`/`tft_app` пока не реализованы.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Инструменты (`tools/`)
|
## Инструменты (`tools/`)
|
||||||
|
|
|
||||||
|
|
@ -161,18 +161,15 @@ static uint32_t poll_rx_mailboxes(void)
|
||||||
|
|
||||||
uint8_t mb_idx = RX_MB_FIRST + i;
|
uint8_t mb_idx = RX_MB_FIRST + i;
|
||||||
|
|
||||||
/* Проверяем флаг готовности MB. */
|
|
||||||
uint64_t mb_flag = (uint64_t) 1U << mb_idx;
|
uint64_t mb_flag = (uint64_t) 1U << mb_idx;
|
||||||
if (FLEXCAN_GetMbStatusFlags(BSP_CAN_BASE, mb_flag) == 0U)
|
if (FLEXCAN_GetMbStatusFlags(BSP_CAN_BASE, mb_flag) == 0U)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Читаем фрейм из MB. */
|
|
||||||
flexcan_frame_t sdk_frame;
|
flexcan_frame_t sdk_frame;
|
||||||
status_t sdk_status = FLEXCAN_ReadRxMb(BSP_CAN_BASE, mb_idx, &sdk_frame);
|
status_t sdk_status = FLEXCAN_ReadRxMb(BSP_CAN_BASE, mb_idx, &sdk_frame);
|
||||||
|
|
||||||
/* Очищаем флаг. */
|
|
||||||
FLEXCAN_ClearMbStatusFlags(BSP_CAN_BASE, mb_flag);
|
FLEXCAN_ClearMbStatusFlags(BSP_CAN_BASE, mb_flag);
|
||||||
|
|
||||||
if ((sdk_status == kStatus_Success) || (sdk_status == kStatus_FLEXCAN_RxOverflow))
|
if ((sdk_status == kStatus_Success) || (sdk_status == kStatus_FLEXCAN_RxOverflow))
|
||||||
|
|
@ -180,7 +177,6 @@ static uint32_t poll_rx_mailboxes(void)
|
||||||
bsp_can_frame_t bsp_frame;
|
bsp_can_frame_t bsp_frame;
|
||||||
frame_from_sdk(&sdk_frame, &bsp_frame);
|
frame_from_sdk(&sdk_frame, &bsp_frame);
|
||||||
|
|
||||||
/* Сериализуем фрейм побайтово в ring buffer. */
|
|
||||||
ring_buffer_write(&g_s_rx_ring, (const uint8_t *) &bsp_frame, sizeof(bsp_frame));
|
ring_buffer_write(&g_s_rx_ring, (const uint8_t *) &bsp_frame, sizeof(bsp_frame));
|
||||||
received++;
|
received++;
|
||||||
}
|
}
|
||||||
|
|
@ -222,16 +218,13 @@ bsp_status_t bsp_can_init(const bsp_can_config_t *p_config)
|
||||||
return BSP_ERR_PARAM;
|
return BSP_ERR_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Если уже инициализирован — сначала деинициализируем. */
|
|
||||||
if (g_s_initialized)
|
if (g_s_initialized)
|
||||||
{
|
{
|
||||||
bsp_can_deinit();
|
bsp_can_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Инициализация ring buffer. */
|
|
||||||
ring_buffer_init(&g_s_rx_ring, g_s_rx_ring_storage, RX_RING_SIZE);
|
ring_buffer_init(&g_s_rx_ring, g_s_rx_ring_storage, RX_RING_SIZE);
|
||||||
|
|
||||||
/* Конфигурация FlexCAN. */
|
|
||||||
flexcan_config_t flexcan_cfg;
|
flexcan_config_t flexcan_cfg;
|
||||||
FLEXCAN_GetDefaultConfig(&flexcan_cfg);
|
FLEXCAN_GetDefaultConfig(&flexcan_cfg);
|
||||||
|
|
||||||
|
|
@ -306,7 +299,6 @@ bsp_status_t bsp_can_set_filter(uint8_t index, uint32_t can_id, uint32_t mask, b
|
||||||
|
|
||||||
uint8_t mb_idx = RX_MB_FIRST + index;
|
uint8_t mb_idx = RX_MB_FIRST + index;
|
||||||
|
|
||||||
/* Конфигурация RX MB. */
|
|
||||||
flexcan_rx_mb_config_t rx_mb_cfg;
|
flexcan_rx_mb_config_t rx_mb_cfg;
|
||||||
rx_mb_cfg.type = kFLEXCAN_FrameTypeData;
|
rx_mb_cfg.type = kFLEXCAN_FrameTypeData;
|
||||||
|
|
||||||
|
|
@ -422,14 +414,12 @@ bsp_status_t bsp_can_send(const bsp_can_frame_t *p_frame, uint32_t timeout_ms)
|
||||||
flexcan_frame_t sdk_frame;
|
flexcan_frame_t sdk_frame;
|
||||||
frame_to_sdk(p_frame, &sdk_frame);
|
frame_to_sdk(p_frame, &sdk_frame);
|
||||||
|
|
||||||
/* Записать фрейм в TX MB. */
|
|
||||||
status_t wr_status = FLEXCAN_WriteTxMb(BSP_CAN_BASE, TX_MB_IDX, &sdk_frame);
|
status_t wr_status = FLEXCAN_WriteTxMb(BSP_CAN_BASE, TX_MB_IDX, &sdk_frame);
|
||||||
if (wr_status != kStatus_Success)
|
if (wr_status != kStatus_Success)
|
||||||
{
|
{
|
||||||
return BSP_ERR_BUSY;
|
return BSP_ERR_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ждать завершения передачи с таймаутом. */
|
|
||||||
uint64_t tx_flag = (uint64_t) 1U << TX_MB_IDX;
|
uint64_t tx_flag = (uint64_t) 1U << TX_MB_IDX;
|
||||||
uint32_t start_ms = bsp_tick_get_ms();
|
uint32_t start_ms = bsp_tick_get_ms();
|
||||||
|
|
||||||
|
|
@ -442,7 +432,6 @@ bsp_status_t bsp_can_send(const bsp_can_frame_t *p_frame, uint32_t timeout_ms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Очистить флаг завершения. */
|
|
||||||
FLEXCAN_ClearMbStatusFlags(BSP_CAN_BASE, tx_flag);
|
FLEXCAN_ClearMbStatusFlags(BSP_CAN_BASE, tx_flag);
|
||||||
|
|
||||||
return BSP_OK;
|
return BSP_OK;
|
||||||
|
|
@ -471,16 +460,13 @@ bsp_status_t bsp_can_receive(bsp_can_frame_t *p_frame, uint32_t timeout_ms)
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* Опросить все активные MB, сложить в ring buffer. */
|
|
||||||
poll_rx_mailboxes();
|
poll_rx_mailboxes();
|
||||||
|
|
||||||
/* Попробовать извлечь фрейм. */
|
|
||||||
if (try_dequeue_frame(p_frame))
|
if (try_dequeue_frame(p_frame))
|
||||||
{
|
{
|
||||||
return BSP_OK;
|
return BSP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Проверить таймаут. */
|
|
||||||
uint32_t elapsed = bsp_tick_get_ms() - start_ms;
|
uint32_t elapsed = bsp_tick_get_ms() - start_ms;
|
||||||
if (elapsed >= timeout_ms)
|
if (elapsed >= timeout_ms)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -110,11 +110,6 @@ static void mqs_edma_callback(I2S_Type *p_base, sai_edma_handle_t *p_handle, sta
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
* Публичный API
|
* Публичный API
|
||||||
* ----------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------- */
|
||||||
/*
|
|
||||||
* AUDIO PLL setting: Frequency = Fref * (DIV_SELECT + NUM / DENOM)
|
|
||||||
* = 24 * (32 + 768/1000)
|
|
||||||
* = 786.432 MHz
|
|
||||||
*/
|
|
||||||
|
|
||||||
bsp_status_t bsp_mqs_init(void)
|
bsp_status_t bsp_mqs_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
* Пин LOW (тока нет) → BSP_OPTO_STATE_INACTIVE
|
* Пин LOW (тока нет) → BSP_OPTO_STATE_INACTIVE
|
||||||
*
|
*
|
||||||
* Режимы каналов (bsp_opto_ch_mode_t):
|
* Режимы каналов (bsp_opto_ch_mode_t):
|
||||||
* ы
|
|
||||||
* BSP_OPTO_MODE_LEVEL — IN1, IN2
|
* BSP_OPTO_MODE_LEVEL — IN1, IN2
|
||||||
* Детектирование уровня с программным дебаунсом.
|
* Детектирование уровня с программным дебаунсом.
|
||||||
* ISR переключает направление прерывания (RISING↔FALLING) после каждого фронта,
|
* ISR переключает направление прерывания (RISING↔FALLING) после каждого фронта,
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* Константы */
|
/* Константы */
|
||||||
/* -------------------------------------------------s------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/** Передать в timeout_ms чтобы ждать данные бесконечно. */
|
/** Передать в timeout_ms чтобы ждать данные бесконечно. */
|
||||||
#define BSP_UART_HOST_WAIT_FOREVER (UINT32_MAX)
|
#define BSP_UART_HOST_WAIT_FOREVER (UINT32_MAX)
|
||||||
|
|
|
||||||
|
|
@ -84,17 +84,14 @@ bsp_status_t bsp_uart_host_init(uint32_t baud_rate)
|
||||||
return BSP_ERR_INIT;
|
return BSP_ERR_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Инициализация кольцевого буфера. */
|
|
||||||
if (!ring_buffer_init(&g_s_rx_ring, g_s_rx_buf, BSP_UART_HOST_RX_BUFFER_SIZE))
|
if (!ring_buffer_init(&g_s_rx_ring, g_s_rx_buf, BSP_UART_HOST_RX_BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
/* Размер не степень двойки — ошибка конфигурации. */
|
/* Размер не степень двойки — ошибка конфигурации. */
|
||||||
return BSP_ERR_INIT;
|
return BSP_ERR_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Тактирование LPUART1. */
|
|
||||||
CLOCK_EnableClock(kCLOCK_Lpuart1);
|
CLOCK_EnableClock(kCLOCK_Lpuart1);
|
||||||
|
|
||||||
/* Настройка периферии. */
|
|
||||||
lpuart_config_t config;
|
lpuart_config_t config;
|
||||||
LPUART_GetDefaultConfig(&config);
|
LPUART_GetDefaultConfig(&config);
|
||||||
config.baudRate_Bps = baud_rate;
|
config.baudRate_Bps = baud_rate;
|
||||||
|
|
@ -191,7 +188,6 @@ size_t bsp_uart_host_read(uint8_t *p_buf, size_t len, uint32_t timeout_ms)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Буфер пуст — проверяем таймаут. */
|
|
||||||
if (timeout_ms == 0U)
|
if (timeout_ms == 0U)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -566,8 +566,6 @@ bsp_status_t bsp_usb_cdc_init(void)
|
||||||
|
|
||||||
USB_DeviceIsrEnable();
|
USB_DeviceIsrEnable();
|
||||||
|
|
||||||
/* FIXME:Задержка для стабилизации DP pull-down. */
|
|
||||||
//SDK_DelayAtLeastUs(USB_ATTACH_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
|
|
||||||
bsp_delay(USB_ATTACH_DELAY_US / 1000);
|
bsp_delay(USB_ATTACH_DELAY_US / 1000);
|
||||||
USB_DeviceRun(g_usbDeviceHandle);
|
USB_DeviceRun(g_usbDeviceHandle);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ static size_t parse_string_array(const char *p_array_start, char (*p_out_bufs)[T
|
||||||
{
|
{
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
p++; /* пропустить '[' */
|
p++;
|
||||||
|
|
||||||
size_t count = 0U;
|
size_t count = 0U;
|
||||||
while (count < max_items)
|
while (count < max_items)
|
||||||
|
|
@ -285,8 +285,6 @@ static void handle_cmd_run_selected(const char *p_line)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Обработать сообщение {"type":"cmd",...}.
|
* @brief Обработать сообщение {"type":"cmd",...}.
|
||||||
*
|
|
||||||
* Команды: ping → pong, run_all → test_runner, run → test_runner.
|
|
||||||
*/
|
*/
|
||||||
static void handle_cmd(const char *p_line)
|
static void handle_cmd(const char *p_line)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,6 @@ void protocol_send_confirm_request(const confirm_params_t *p_params)
|
||||||
|
|
||||||
void protocol_send_test_list(const test_module_t *const *p_pp_registry, size_t count)
|
void protocol_send_test_list(const test_module_t *const *p_pp_registry, size_t count)
|
||||||
{
|
{
|
||||||
/* Заголовок массива */
|
|
||||||
cli_send("{\"type\":\"test_list\",\"tests\":[");
|
cli_send("{\"type\":\"test_list\",\"tests\":[");
|
||||||
|
|
||||||
for (size_t i = 0U; i < count; i++)
|
for (size_t i = 0U; i < count; i++)
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ static volatile bool g_s_confirm_value;
|
||||||
static char g_s_pending_confirm_id[RUNNER_CONFIRM_ID_SIZE];
|
static char g_s_pending_confirm_id[RUNNER_CONFIRM_ID_SIZE];
|
||||||
static uint32_t g_s_confirm_deadline_ms;
|
static uint32_t g_s_confirm_deadline_ms;
|
||||||
|
|
||||||
/* Счётчики итога (используются только в RUNNER_MODE_ALL) */
|
/* Счётчики итога (ALL и SELECTED; в SINGLE не используются) */
|
||||||
static uint8_t g_s_passed;
|
static uint8_t g_s_passed;
|
||||||
static uint8_t g_s_failed;
|
static uint8_t g_s_failed;
|
||||||
static uint8_t g_s_skipped;
|
static uint8_t g_s_skipped;
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,6 @@ def main() -> int:
|
||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# ── Проверить FCB ─────────────────────────────────────────────────────────
|
|
||||||
if not args.fcb.exists():
|
if not args.fcb.exists():
|
||||||
print(f" ❌ FCB not found: {args.fcb}", file=sys.stderr)
|
print(f" ❌ FCB not found: {args.fcb}", file=sys.stderr)
|
||||||
print(
|
print(
|
||||||
|
|
@ -174,7 +173,6 @@ def main() -> int:
|
||||||
)
|
)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# ── Найти HAB-образ ───────────────────────────────────────────────────────
|
|
||||||
hab_name = HAB_NAMES[args.firmware]
|
hab_name = HAB_NAMES[args.firmware]
|
||||||
hab_path = BUILD_DIR / args.build_type / hab_name
|
hab_path = BUILD_DIR / args.build_type / hab_name
|
||||||
|
|
||||||
|
|
@ -195,7 +193,6 @@ def main() -> int:
|
||||||
print(f" Target : {args.target}")
|
print(f" Target : {args.target}")
|
||||||
print(f" Frequency : {args.frequency} Hz\n")
|
print(f" Frequency : {args.frequency} Hz\n")
|
||||||
|
|
||||||
# ── Собрать объединённый образ ────────────────────────────────────────────
|
|
||||||
image = build_full_image(args.fcb, hab_path)
|
image = build_full_image(args.fcb, hab_path)
|
||||||
|
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
|
|
@ -205,7 +202,6 @@ def main() -> int:
|
||||||
print(f"\n Dry run — image saved to {out}")
|
print(f"\n Dry run — image saved to {out}")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# ── Записать во Flash через pyOCD ─────────────────────────────────────────
|
|
||||||
with tempfile.NamedTemporaryFile(
|
with tempfile.NamedTemporaryFile(
|
||||||
suffix=f"_{args.firmware}_full.bin", delete=False
|
suffix=f"_{args.firmware}_full.bin", delete=False
|
||||||
) as tmp:
|
) as tmp:
|
||||||
|
|
|
||||||
|
|
@ -387,7 +387,6 @@ def main() -> None:
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Группа: что прошивать (взаимоисключающие варианты)
|
|
||||||
target_group = parser.add_mutually_exclusive_group()
|
target_group = parser.add_mutually_exclusive_group()
|
||||||
target_group.add_argument(
|
target_group.add_argument(
|
||||||
"--firmware",
|
"--firmware",
|
||||||
|
|
@ -420,9 +419,6 @@ def main() -> None:
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Валидация: --firmware требует --build-type (уже есть default, но запомним)
|
|
||||||
# --bin-path: build-type игнорируется
|
|
||||||
# --erase-chip: несовместим с --ram-only
|
|
||||||
if args.erase_chip and args.ram_only:
|
if args.erase_chip and args.ram_only:
|
||||||
parser.error("--erase-chip несовместим с --ram-only")
|
parser.error("--erase-chip несовместим с --ram-only")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ TUI-приложение для диагностики и прошивки пл
|
||||||
Написано на Python + [Textual](https://textual.textualize.io/). Работает на Linux, macOS, Windows.
|
Написано на Python + [Textual](https://textual.textualize.io/). Работает на Linux, macOS, Windows.
|
||||||
|
|
||||||
> Внутреннее устройство, диаграммы архитектуры и заметки для разработчиков —
|
> Внутреннее устройство, диаграммы архитектуры и заметки для разработчиков —
|
||||||
> в [DEV_ARCH.md](DEV_ARCH.md). Этот документ — только про то, как приложением
|
> в [DEV_ARCH.md](DEV_ARCH.md).
|
||||||
> пользоваться.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,6 @@ class ServiceApp(App):
|
||||||
self.push_screen(WaitingScreen())
|
self.push_screen(WaitingScreen())
|
||||||
|
|
||||||
# ── Переходы между экранами ───────────────────────────────────────────────
|
# ── Переходы между экранами ───────────────────────────────────────────────
|
||||||
|
|
||||||
@on(WaitingScreen.DeviceDetected)
|
|
||||||
@on(WaitingScreen.DeviceDetected)
|
@on(WaitingScreen.DeviceDetected)
|
||||||
def _on_device_detected(self, event: WaitingScreen.DeviceDetected) -> None:
|
def _on_device_detected(self, event: WaitingScreen.DeviceDetected) -> None:
|
||||||
if event.mode == AppMode.FLASHING:
|
if event.mode == AppMode.FLASHING:
|
||||||
|
|
@ -97,7 +95,6 @@ class ServiceApp(App):
|
||||||
|
|
||||||
@on(DiagScreen.DiagDone)
|
@on(DiagScreen.DiagDone)
|
||||||
def _on_diag_done(self, event: DiagScreen.DiagDone) -> None:
|
def _on_diag_done(self, event: DiagScreen.DiagDone) -> None:
|
||||||
"""После диагностики — отключиться, вернуться в Waiting."""
|
|
||||||
self._disconnect()
|
self._disconnect()
|
||||||
self.switch_screen(WaitingScreen(disconnect_reason=event.reason))
|
self.switch_screen(WaitingScreen(disconnect_reason=event.reason))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,9 @@ from .models import TestInfo
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Таймаут чтения одной строки (сек)
|
|
||||||
_READLINE_TIMEOUT_S = 0.1
|
_READLINE_TIMEOUT_S = 0.1
|
||||||
# Таймаут ping→pong при подключении (сек)
|
|
||||||
_PING_TIMEOUT_S = 5.0
|
_PING_TIMEOUT_S = 5.0
|
||||||
# Таймаут ожидания событий теста (сек) — длиннее самого долгого теста (SDRAM ~15 с)
|
# Длиннее самого долгого теста (SDRAM ~15 с)
|
||||||
_TEST_EVENT_TIMEOUT_S = 120.0
|
_TEST_EVENT_TIMEOUT_S = 120.0
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import serial.tools.list_ports
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# VID/PID M5StampPLC
|
|
||||||
_M5_VID = int(os.environ.get("SERVICE_M5_VID", "0x303A"), 16)
|
_M5_VID = int(os.environ.get("SERVICE_M5_VID", "0x303A"), 16)
|
||||||
_M5_PID = int(os.environ.get("SERVICE_M5_PID", "0x4001"), 16)
|
_M5_PID = int(os.environ.get("SERVICE_M5_PID", "0x4001"), 16)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,10 @@ from .models import ConfirmRequest, TestResult, TestStatus
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Задержки для HIL
|
|
||||||
_RELAY_ON_S = 0.15
|
_RELAY_ON_S = 0.15
|
||||||
_RELAY_OFF_S = 0.50
|
_RELAY_OFF_S = 0.50
|
||||||
|
|
||||||
# Карта confirm_id → реле M5 для opto-теста
|
# confirm_id → (relay_num, target_state)
|
||||||
# Формат: confirm_id → (relay_num, target_state)
|
|
||||||
_OPTO_RELAY_MAP: dict[str, tuple[int, bool]] = {
|
_OPTO_RELAY_MAP: dict[str, tuple[int, bool]] = {
|
||||||
"opto_in1_active": (3, True),
|
"opto_in1_active": (3, True),
|
||||||
"opto_in1_inactive": (3, False),
|
"opto_in1_inactive": (3, False),
|
||||||
|
|
@ -66,7 +64,6 @@ _OPTO_RELAY_MAP: dict[str, tuple[int, bool]] = {
|
||||||
"opto_rs_inactive": (2, False),
|
"opto_rs_inactive": (2, False),
|
||||||
}
|
}
|
||||||
|
|
||||||
# CAN параметры
|
|
||||||
_CAN_RX_ID = 0x100
|
_CAN_RX_ID = 0x100
|
||||||
_CAN_RX_DATA = [0xDE, 0xAD, 0xBE, 0xEF]
|
_CAN_RX_DATA = [0xDE, 0xAD, 0xBE, 0xEF]
|
||||||
_CAN_TX_ID = 0x200
|
_CAN_TX_ID = 0x200
|
||||||
|
|
@ -80,13 +77,13 @@ _TIMEOUT_EVENT_TYPE = "_timeout"
|
||||||
|
|
||||||
|
|
||||||
class OrchestratorEventType(Enum):
|
class OrchestratorEventType(Enum):
|
||||||
TEST_BEGIN = auto() # тест начался
|
TEST_BEGIN = auto()
|
||||||
TEST_RESULT = auto() # тест завершился
|
TEST_RESULT = auto()
|
||||||
TEST_PROGRESS = auto() # внутришаговый прогресс долгого теста (usd и т.п.)
|
TEST_PROGRESS = auto() # внутришаговый прогресс долгого теста (usd и т.п.)
|
||||||
CONFIRM_NEEDED = auto() # нужен ответ оператора (standalone)
|
CONFIRM_NEEDED = auto() # нужен ответ оператора (standalone)
|
||||||
CONFIRM_RESOLVED = auto() # HIL confirm выполнен автоматически
|
CONFIRM_RESOLVED = auto() # HIL confirm выполнен автоматически
|
||||||
BUTTONS_PROMPT = auto() # показать инструкцию для buttons (без confirm)
|
BUTTONS_PROMPT = auto() # показать инструкцию для buttons (без confirm)
|
||||||
SUMMARY = auto() # итог всей сессии
|
SUMMARY = auto()
|
||||||
ERROR = auto() # ошибка протокола, M5, или обрыв по таймауту
|
ERROR = auto() # ошибка протокола, M5, или обрыв по таймауту
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ class TestListPanel(Widget):
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
def __init__(self, **kwargs) -> None:
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
# test_id → Checkbox для быстрого доступа
|
|
||||||
self._checkboxes: dict[str, Checkbox] = {}
|
self._checkboxes: dict[str, Checkbox] = {}
|
||||||
# test_id → True если HIL-тест недоступен без M5 (постоянное состояние,
|
# test_id → True если HIL-тест недоступен без M5 (постоянное состояние,
|
||||||
# не зависящее от прогона). Отдельно от Checkbox.disabled, который
|
# не зависящее от прогона). Отдельно от Checkbox.disabled, который
|
||||||
|
|
|
||||||
|
|
@ -173,9 +173,8 @@ class FlashScreen(Screen, ConnectionWatcherMixin):
|
||||||
self._stop_connection_watch()
|
self._stop_connection_watch()
|
||||||
|
|
||||||
def _check_sdp_present(self) -> bool:
|
def _check_sdp_present(self) -> bool:
|
||||||
# Не считаем потерей соединения, если идёт активная операция —
|
# Не считаем потерей соединения, если идёт активная операция — обрыв
|
||||||
# flash_usb.py сам обработает реальный обрыв через subprocess.
|
# в этом случае обнаружит и обработает сам flash_backend
|
||||||
# обрыв в этом случае обнаружит и обработает сам flash_backend
|
|
||||||
# (ConnectionLostError, см. Фазу 4), не watcher.
|
# (ConnectionLostError, см. Фазу 4), не watcher.
|
||||||
if self._flashing:
|
if self._flashing:
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,6 @@ def test_flash_write_memory_fails(monkeypatch, events, tmp_path):
|
||||||
with pytest.raises(fb.FlashBackendError, match="write_memory"):
|
with pytest.raises(fb.FlashBackendError, match="write_memory"):
|
||||||
fb.flash(hab_bin, progress_cb=_collector(events))
|
fb.flash(hab_bin, progress_cb=_collector(events))
|
||||||
|
|
||||||
# reset/done не должны наступить после ошибки записи
|
|
||||||
assert "reset" not in _phases(events)
|
assert "reset" not in _phases(events)
|
||||||
assert "done" not in _phases(events)
|
assert "done" not in _phases(events)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue