mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-11 12:56:18 +00:00
feat(core/prodtest): Introduce unit test extension into prodtest [no changelog]
This commit is contained in:
parent
acdf549fc4
commit
f2054ff409
@ -79,6 +79,7 @@ SOURCE_MOD += [
|
||||
'embed/rtl/error_handling.c',
|
||||
'embed/rtl/mini_printf.c',
|
||||
'embed/rtl/strutils.c',
|
||||
'embed/rtl/unit_test.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
@ -124,6 +125,7 @@ SOURCE_PRODTEST = [
|
||||
'embed/projects/prodtest/cmd/prodtest_sbu.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_touch.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_tropic.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_unit_test.c',
|
||||
'embed/projects/prodtest/cmd/prodtest_wpc.c',
|
||||
]
|
||||
|
||||
|
@ -935,5 +935,25 @@ Example:
|
||||
nfc-write_card <timeout_seconds>
|
||||
# NFC reader on, put the card on the reader (timeout <timeout_seconds> s)
|
||||
# Writting URI to NFC tag 7AF403
|
||||
### unit-test-run
|
||||
Prodtest have capability to verify the overall firmware functionality by running built-in unit tests which should excercise the basic
|
||||
features of the firmware drivers. This command will run all registered unit tests and return 'OK' if all tests passed.
|
||||
|
||||
Example:
|
||||
```
|
||||
# Running all unit tests...
|
||||
# ut-pmic-battery: PASSED
|
||||
# ut-pmic-init-deinit: PASSED
|
||||
OK
|
||||
```
|
||||
|
||||
### unit-test-list
|
||||
List all build-in unit tests
|
||||
|
||||
Example:
|
||||
```
|
||||
# List of all registered unit tests:
|
||||
# ut-pmic-battery - Test PMIC battery connection
|
||||
# ut-pmic-init-deinit - Test PMIC driver initialization and deinitialization
|
||||
OK
|
||||
```
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <rtl/cli.h>
|
||||
#include <rtl/unit_test.h>
|
||||
#include <sys/systick.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -198,6 +199,65 @@ static void prodtest_pmic_report(cli_t* cli) {
|
||||
cli_ok(cli, "");
|
||||
}
|
||||
|
||||
// ut-pmic-init-deinit
|
||||
// This unit test verifies the PMIC driver initialization and deinitialization
|
||||
// routine could be called repeatably witout failure. It should verify that all
|
||||
// driver components are properly cleaned by deinit function.
|
||||
static ut_status_t ut_pmic_init_deinit() {
|
||||
ut_status_t ut_result = UT_PASSED;
|
||||
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
// deinitilize the pmic driver
|
||||
npm1300_deinit();
|
||||
if (npm1300_init() == false) {
|
||||
ut_result = UT_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
npm1300_deinit();
|
||||
|
||||
return ut_result;
|
||||
}
|
||||
|
||||
// ut-pmic-battery
|
||||
// This unit test verifies the battery connection to NPM1300 PMIC.
|
||||
// Firstly it initilize the PMIC driver and request the measurement
|
||||
// report. From the measurement report it checks, if the battery voltage and
|
||||
// NTC temperature are within the expeted range. At last, it checks if NTC
|
||||
// temperature measurement is not too far away from the die temperarture.
|
||||
static ut_status_t ut_pmic_battery() {
|
||||
ut_status_t ut_result = UT_PASSED;
|
||||
npm1300_report_t report;
|
||||
|
||||
if (npm1300_init() == false) {
|
||||
ut_result = UT_FAILED;
|
||||
} else {
|
||||
// Request mesaurement report from PMIC
|
||||
if (npm1300_measure_sync(&report) == false) {
|
||||
ut_result = UT_FAILED;
|
||||
} else {
|
||||
// Battery voltage outside given range
|
||||
if (report.vbat < 3.0 || report.vbat > 3.8) {
|
||||
ut_result = UT_FAILED;
|
||||
}
|
||||
|
||||
// Battery NTC outside given range
|
||||
if (report.ntc_temp < -40.0 || report.ntc_temp > 50.0) {
|
||||
ut_result = UT_FAILED;
|
||||
}
|
||||
|
||||
// Battery NTC too far from die temp
|
||||
if (abs(report.ntc_temp - report.die_temp) > 10.0) {
|
||||
ut_result = UT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
npm1300_deinit();
|
||||
return ut_result;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
@ -242,4 +302,16 @@ PRODTEST_CLI_CMD(
|
||||
.args = "[<count>] [<period>]"
|
||||
);
|
||||
|
||||
REGISTER_UNIT_TEST(
|
||||
.name = "ut-pmic-init-deinit",
|
||||
.func = ut_pmic_init_deinit,
|
||||
.info = "Test PMIC driver initialization and deinitialization",
|
||||
)
|
||||
|
||||
REGISTER_UNIT_TEST(
|
||||
.name = "ut-pmic-battery",
|
||||
.func = ut_pmic_battery,
|
||||
.info = "Test PMIC battery connection",
|
||||
)
|
||||
|
||||
#endif // USE_POWERCTL
|
||||
|
89
core/embed/projects/prodtest/cmd/prodtest_unit_test.c
Normal file
89
core/embed/projects/prodtest/cmd/prodtest_unit_test.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <rust_ui_prodtest.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <rtl/cli.h>
|
||||
#include <rtl/unit_test.h>
|
||||
|
||||
static void prodtest_unit_test_list(cli_t* cli) {
|
||||
if (cli_arg_count(cli) > 0) {
|
||||
cli_error_arg_count(cli);
|
||||
return;
|
||||
}
|
||||
|
||||
cli_trace(cli, "List of all registered unit tests:");
|
||||
|
||||
unit_test_t* ut = unit_test_get_records();
|
||||
|
||||
for (size_t i = 0; i < ut->unit_test_count; i++) {
|
||||
cli_trace(cli, " %s - %s ", ut->unit_test_array[i].name,
|
||||
ut->unit_test_array[i].info);
|
||||
}
|
||||
|
||||
cli_ok(cli, "");
|
||||
}
|
||||
|
||||
static void prodtest_unit_test_run(cli_t* cli) {
|
||||
if (cli_arg_count(cli) > 0) {
|
||||
cli_error_arg_count(cli);
|
||||
return;
|
||||
}
|
||||
|
||||
bool ut_passed = true;
|
||||
|
||||
cli_trace(cli, "Running all unit tests...");
|
||||
|
||||
unit_test_t* ut = unit_test_get_records();
|
||||
|
||||
for (size_t i = 0; i < ut->unit_test_count; i++) {
|
||||
ut_status_t test_result = ut->unit_test_array[i].func(cli);
|
||||
|
||||
cli_trace(cli, "%s: %s", ut->unit_test_array[i].name,
|
||||
test_result == UT_PASSED ? "PASSED" : "FAILED");
|
||||
|
||||
if (test_result == UT_FAILED) {
|
||||
ut_passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ut_passed) {
|
||||
cli_ok(cli, "");
|
||||
} else {
|
||||
cli_error(cli, CLI_ERROR, "Some of the unit test failed");
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
.name = "unit-test-list",
|
||||
.func = prodtest_unit_test_list,
|
||||
.info = "Print list of all registered unit tests",
|
||||
.args = ""
|
||||
)
|
||||
|
||||
PRODTEST_CLI_CMD(
|
||||
.name = "unit-test-run",
|
||||
.func = prodtest_unit_test_run,
|
||||
.info = "Run all registerd unit tests",
|
||||
.args = ""
|
||||
)
|
60
core/embed/rtl/inc/rtl/unit_test.h
Normal file
60
core/embed/rtl/inc/rtl/unit_test.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
#include <rtl/cli.h>
|
||||
|
||||
typedef enum {
|
||||
UT_PASSED = 0,
|
||||
UT_FAILED,
|
||||
} ut_status_t;
|
||||
|
||||
// unit test handler routine prototype
|
||||
typedef ut_status_t (*ut_handler_t)(cli_t* ut);
|
||||
|
||||
// Structure describing the registration record for a CLI unit test handler
|
||||
typedef struct {
|
||||
// Unit test name
|
||||
const char* name;
|
||||
// Unit test handler
|
||||
ut_handler_t func;
|
||||
// Single line unit test description
|
||||
const char* info;
|
||||
} unit_test_record_t;
|
||||
|
||||
#define CONCAT_UT_INDIRECT(x, y) x##y
|
||||
#define CONCAT_UT(x, y) CONCAT_INDIRECT(x, y)
|
||||
|
||||
// Register a unit test by placing its registration record
|
||||
// into a specially designated linker script section
|
||||
#define REGISTER_UNIT_TEST(...) \
|
||||
__attribute__((used, section(".unit_test"))) static const unit_test_record_t \
|
||||
CONCAT_UT(_ut_handler, __COUNTER__) = {__VA_ARGS__};
|
||||
|
||||
typedef struct {
|
||||
// Registered unit test record handlers
|
||||
const unit_test_record_t* unit_test_array;
|
||||
size_t unit_test_count;
|
||||
} unit_test_t;
|
||||
|
||||
// Returns the pointer to unit_test_t structure with all registered records
|
||||
unit_test_t* unit_test_get_records(void);
|
33
core/embed/rtl/unit_test.c
Normal file
33
core/embed/rtl/unit_test.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
#include <rtl/unit_test.h>
|
||||
|
||||
extern unit_test_record_t _unit_test_section_start;
|
||||
extern unit_test_record_t _unit_test_section_end;
|
||||
|
||||
unit_test_t g_ut = {0};
|
||||
|
||||
unit_test_t* unit_test_get_records(void) {
|
||||
g_ut.unit_test_array = &_unit_test_section_start;
|
||||
g_ut.unit_test_count = &_unit_test_section_end - &_unit_test_section_start;
|
||||
return &g_ut;
|
||||
}
|
@ -57,6 +57,11 @@ SECTIONS {
|
||||
_prodtest_cli_cmd_section_start = .;
|
||||
KEEP(*(.prodtest_cli_cmd))
|
||||
_prodtest_cli_cmd_section_end = .;
|
||||
. = ALIGN(4);
|
||||
|
||||
_unit_test_section_start = .;
|
||||
KEEP(*(.unit_test))
|
||||
_unit_test_section_end = .;
|
||||
|
||||
. = ALIGN(128K);
|
||||
} >FLASH
|
||||
|
@ -59,6 +59,11 @@ SECTIONS {
|
||||
_prodtest_cli_cmd_section_start = .;
|
||||
KEEP(*(.prodtest_cli_cmd))
|
||||
_prodtest_cli_cmd_section_end = .;
|
||||
. = ALIGN(4);
|
||||
|
||||
_unit_test_section_start = .;
|
||||
KEEP(*(.unit_test))
|
||||
_unit_test_section_end = .;
|
||||
|
||||
. = ALIGN(512);
|
||||
} >FLASH AT>FLASH
|
||||
|
@ -65,6 +65,11 @@ SECTIONS {
|
||||
_prodtest_cli_cmd_section_start = .;
|
||||
KEEP(*(.prodtest_cli_cmd))
|
||||
_prodtest_cli_cmd_section_end = .;
|
||||
. = ALIGN(4);
|
||||
|
||||
_unit_test_section_start = .;
|
||||
KEEP(*(.unit_test))
|
||||
_unit_test_section_end = .;
|
||||
|
||||
. = ALIGN(512);
|
||||
} >FLASH AT>FLASH
|
||||
|
Loading…
Reference in New Issue
Block a user