mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp_system): add linux test for system init function regisration
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
# This file is used to check the order of execution of ESP_SYSTEM_INIT_FN functions.
|
# This file is used to check the order of execution of ESP_SYSTEM_INIT_FN functions.
|
||||||
@@ -13,12 +13,14 @@ import itertools
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import typing
|
|
||||||
|
|
||||||
ESP_SYSTEM_INIT_FN_STR = r'ESP_SYSTEM_INIT_FN'
|
COMMENT_REGEX = re.compile(r'//.*?$|/\*.*?\*/', re.DOTALL | re.MULTILINE)
|
||||||
ESP_SYSTEM_INIT_FN_REGEX_SIMPLE = re.compile(r'ESP_SYSTEM_INIT_FN')
|
ESP_SYSTEM_INIT_FN_REGEX_SIMPLE = re.compile(r'\bESP_SYSTEM_INIT_FN\s*\(')
|
||||||
ESP_SYSTEM_INIT_FN_REGEX = re.compile(r'ESP_SYSTEM_INIT_FN\(([a-zA-Z0-9_]+)\s*,\s*([a-zA-Z\ _0-9\(\)|]+)\s*,\s*([a-zA-Z\ _0-9\(\)|]+)\s*,\s*([0-9]+)\)')
|
ESP_SYSTEM_INIT_FN_REGEX = re.compile(
|
||||||
|
r'ESP_SYSTEM_INIT_FN\(([a-zA-Z0-9_]+)\s*,\s*([a-zA-Z\ _0-9\(\)|]+)\s*,\s*([a-zA-Z\ _0-9\(\)|]+)\s*,\s*([0-9]+)\)'
|
||||||
|
)
|
||||||
STARTUP_ENTRIES_FILE = 'components/esp_system/system_init_fn.txt'
|
STARTUP_ENTRIES_FILE = 'components/esp_system/system_init_fn.txt'
|
||||||
|
EXCLUDED_SOURCE_DIRS = {'test_apps', 'host_test', 'host_tests'}
|
||||||
|
|
||||||
|
|
||||||
class StartupEntry:
|
class StartupEntry:
|
||||||
@@ -33,6 +35,15 @@ class StartupEntry:
|
|||||||
return f'{self.stage}: {self.priority:3d}: {self.func} in {self.filename} on {self.affinity}'
|
return f'{self.stage}: {self.priority:3d}: {self.func} in {self.filename} on {self.affinity}'
|
||||||
|
|
||||||
|
|
||||||
|
def should_skip_source_file(filename: str, idf_path: str) -> bool:
|
||||||
|
relpath_parts = os.path.relpath(filename, idf_path).split(os.sep)
|
||||||
|
return any(part in EXCLUDED_SOURCE_DIRS for part in relpath_parts)
|
||||||
|
|
||||||
|
|
||||||
|
def strip_comments(contents: str) -> str:
|
||||||
|
return COMMENT_REGEX.sub('', contents)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
try:
|
try:
|
||||||
idf_path = os.environ['IDF_PATH']
|
idf_path = os.environ['IDF_PATH']
|
||||||
@@ -40,7 +51,7 @@ def main() -> None:
|
|||||||
raise SystemExit('IDF_PATH must be set before running this script')
|
raise SystemExit('IDF_PATH must be set before running this script')
|
||||||
|
|
||||||
has_errors = False
|
has_errors = False
|
||||||
startup_entries = [] # type: typing.List[StartupEntry]
|
startup_entries: list[StartupEntry] = []
|
||||||
|
|
||||||
#
|
#
|
||||||
# 1. Iterate over all .c and .cpp source files and find ESP_SYSTEM_INIT_FN definitions
|
# 1. Iterate over all .c and .cpp source files and find ESP_SYSTEM_INIT_FN definitions
|
||||||
@@ -50,24 +61,32 @@ def main() -> None:
|
|||||||
glob_iter = glob.glob(os.path.join(idf_path, 'components', '**', f'*.{extension}'), recursive=True)
|
glob_iter = glob.glob(os.path.join(idf_path, 'components', '**', f'*.{extension}'), recursive=True)
|
||||||
source_files_iters.append(glob_iter)
|
source_files_iters.append(glob_iter)
|
||||||
for filename in itertools.chain(*source_files_iters):
|
for filename in itertools.chain(*source_files_iters):
|
||||||
with open(filename, 'r', encoding='utf-8') as f_obj:
|
if should_skip_source_file(filename, idf_path):
|
||||||
file_contents = f_obj.read()
|
|
||||||
if ESP_SYSTEM_INIT_FN_STR not in file_contents:
|
|
||||||
continue
|
continue
|
||||||
count_expected = len(ESP_SYSTEM_INIT_FN_REGEX_SIMPLE.findall(file_contents))
|
|
||||||
found = ESP_SYSTEM_INIT_FN_REGEX.findall(file_contents)
|
relpath = os.path.relpath(filename, idf_path)
|
||||||
|
with open(filename, encoding='utf-8') as f_obj:
|
||||||
|
file_contents = f_obj.read()
|
||||||
|
|
||||||
|
file_contents_no_comments = strip_comments(file_contents)
|
||||||
|
if not ESP_SYSTEM_INIT_FN_REGEX_SIMPLE.search(file_contents_no_comments):
|
||||||
|
continue
|
||||||
|
|
||||||
|
count_expected = len(ESP_SYSTEM_INIT_FN_REGEX_SIMPLE.findall(file_contents_no_comments))
|
||||||
|
found = ESP_SYSTEM_INIT_FN_REGEX.findall(file_contents_no_comments)
|
||||||
if len(found) != count_expected:
|
if len(found) != count_expected:
|
||||||
print((f'error: In {filename}, found ESP_SYSTEM_INIT_FN {count_expected} time(s), '
|
print(
|
||||||
f'but regular expression matched {len(found)} time(s)'), file=sys.stderr)
|
(
|
||||||
|
f'error: In {filename}, found ESP_SYSTEM_INIT_FN {count_expected} time(s), '
|
||||||
|
f'but regular expression matched {len(found)} time(s)'
|
||||||
|
),
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
has_errors = True
|
has_errors = True
|
||||||
|
|
||||||
for match in found:
|
for match in found:
|
||||||
entry = StartupEntry(
|
entry = StartupEntry(
|
||||||
filename=os.path.relpath(filename, idf_path),
|
filename=relpath, func=match[0], stage=match[1], affinity=match[2], priority=int(match[3])
|
||||||
func=match[0],
|
|
||||||
stage=match[1],
|
|
||||||
affinity=match[2],
|
|
||||||
priority=int(match[3])
|
|
||||||
)
|
)
|
||||||
startup_entries.append(entry)
|
startup_entries.append(entry)
|
||||||
|
|
||||||
@@ -77,7 +96,7 @@ def main() -> None:
|
|||||||
# to have a stable sorting order in case when the same startup function is defined in multiple files,
|
# to have a stable sorting order in case when the same startup function is defined in multiple files,
|
||||||
# for example for different targets.
|
# for example for different targets.
|
||||||
#
|
#
|
||||||
def sort_key(entry: StartupEntry) -> typing.Tuple[str, int, str]:
|
def sort_key(entry: StartupEntry) -> tuple[str, int, str]:
|
||||||
# luckily 'core' and 'secondary' are in alphabetical order, so we can return the string
|
# luckily 'core' and 'secondary' are in alphabetical order, so we can return the string
|
||||||
return (entry.stage, entry.priority, entry.filename)
|
return (entry.stage, entry.priority, entry.filename)
|
||||||
|
|
||||||
@@ -88,7 +107,7 @@ def main() -> None:
|
|||||||
# 3. Load startup entries list from STARTUP_ENTRIES_FILE, removing comments and empty lines
|
# 3. Load startup entries list from STARTUP_ENTRIES_FILE, removing comments and empty lines
|
||||||
#
|
#
|
||||||
startup_entries_expected_lines = []
|
startup_entries_expected_lines = []
|
||||||
with open(os.path.join(idf_path, STARTUP_ENTRIES_FILE), 'r', encoding='utf-8') as startup_entries_expected_file:
|
with open(os.path.join(idf_path, STARTUP_ENTRIES_FILE), encoding='utf-8') as startup_entries_expected_file:
|
||||||
for line in startup_entries_expected_file:
|
for line in startup_entries_expected_file:
|
||||||
if line.startswith('#') or len(line.strip()) == 0:
|
if line.startswith('#') or len(line.strip()) == 0:
|
||||||
continue
|
continue
|
||||||
@@ -99,8 +118,13 @@ def main() -> None:
|
|||||||
#
|
#
|
||||||
diff_lines = list(difflib.unified_diff(startup_entries_expected_lines, startup_entries_lines, lineterm=''))
|
diff_lines = list(difflib.unified_diff(startup_entries_expected_lines, startup_entries_lines, lineterm=''))
|
||||||
if len(diff_lines) > 0:
|
if len(diff_lines) > 0:
|
||||||
print(('error: startup order doesn\'t match the reference file. '
|
print(
|
||||||
f'please update {STARTUP_ENTRIES_FILE} to match the actual startup order:'), file=sys.stderr)
|
(
|
||||||
|
"error: startup order doesn't match the reference file. "
|
||||||
|
f'please update {STARTUP_ENTRIES_FILE} to match the actual startup order:'
|
||||||
|
),
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
for line in diff_lines:
|
for line in diff_lines:
|
||||||
print(f'{line}', file=sys.stderr)
|
print(f'{line}', file=sys.stderr)
|
||||||
has_errors = True
|
has_errors = True
|
||||||
|
|||||||
@@ -229,3 +229,11 @@ static void start_cpu0_default(void)
|
|||||||
|
|
||||||
ESP_INFINITE_LOOP();
|
ESP_INFINITE_LOOP();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_LINUX && !defined(ESP_SYSTEM_LINUX_NO_MAIN)
|
||||||
|
__attribute__((weak)) int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
start_cpu0();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif // CONFIG_IDF_TARGET_LINUX
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# For more information about build system see
|
||||||
|
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||||
|
# The following five lines of boilerplate have to be in your project's
|
||||||
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
set(COMPONENTS main)
|
||||||
|
project(test_sys_init_fn)
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
idf_component_register(SRCS "test_sys_init_fn.c"
|
||||||
|
"test_init_fn_defs.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
PRIV_REQUIRES unity esp_system)
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file defines system init functions whose execution is verified
|
||||||
|
* by the test cases in test_sys_init_fn.c.
|
||||||
|
*
|
||||||
|
* The functions are placed into the esp_sys_init_fn linker section via the
|
||||||
|
* system init macro. On Linux this uses ELF section sorting; on macOS
|
||||||
|
* the same section is resolved at runtime via getsectiondata().
|
||||||
|
*
|
||||||
|
* Important: this file must be compiled into the same binary as the test
|
||||||
|
* runner so the linker/loader sees the section entries.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "esp_private/startup_internal.h"
|
||||||
|
#include "test_init_fn_defs.h"
|
||||||
|
|
||||||
|
/* ---- Global state read back by the test cases ---- */
|
||||||
|
|
||||||
|
int trace_log[INIT_FN_TRACE_MAX];
|
||||||
|
int trace_count = 0;
|
||||||
|
|
||||||
|
bool core_prio_200_executed = false;
|
||||||
|
bool core_prio_250_executed = false;
|
||||||
|
bool secondary_prio_200_executed = false;
|
||||||
|
bool secondary_prio_250_executed = false;
|
||||||
|
|
||||||
|
/* ---- Helper ---- */
|
||||||
|
static void trace_append(int tag)
|
||||||
|
{
|
||||||
|
if (trace_count < INIT_FN_TRACE_MAX) {
|
||||||
|
trace_log[trace_count++] = tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- CORE-stage init functions (executed during do_core_init) ---- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Two CORE-stage functions with different priorities.
|
||||||
|
* Priority 200 must execute before priority 250.
|
||||||
|
* We use tag values equal to the priority for easy identification.
|
||||||
|
*/
|
||||||
|
ESP_SYSTEM_INIT_FN(test_core_prio_200, CORE, BIT(0), 200)
|
||||||
|
{
|
||||||
|
core_prio_200_executed = true;
|
||||||
|
trace_append(200);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_SYSTEM_INIT_FN(test_core_prio_250, CORE, BIT(0), 250)
|
||||||
|
{
|
||||||
|
core_prio_250_executed = true;
|
||||||
|
trace_append(250);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- SECONDARY-stage init functions (executed during do_secondary_init) ---- */
|
||||||
|
|
||||||
|
ESP_SYSTEM_INIT_FN(test_secondary_prio_200, SECONDARY, BIT(0), 200)
|
||||||
|
{
|
||||||
|
secondary_prio_200_executed = true;
|
||||||
|
trace_append(1200); /* offset by 1000 so we can distinguish stage in trace */
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_SYSTEM_INIT_FN(test_secondary_prio_250, SECONDARY, BIT(0), 250)
|
||||||
|
{
|
||||||
|
secondary_prio_250_executed = true;
|
||||||
|
trace_append(1250);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of init function invocations we track for ordering tests.
|
||||||
|
*/
|
||||||
|
#define INIT_FN_TRACE_MAX 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global trace log filled by init functions to record their execution order.
|
||||||
|
* Each init function appends its own tag (an arbitrary integer) to
|
||||||
|
* trace_log[trace_count] and increments trace_count.
|
||||||
|
*/
|
||||||
|
extern int trace_log[INIT_FN_TRACE_MAX];
|
||||||
|
extern int trace_count;
|
||||||
|
|
||||||
|
/* Flags set by individual init functions so tests can verify they executed */
|
||||||
|
extern bool core_prio_200_executed;
|
||||||
|
extern bool core_prio_250_executed;
|
||||||
|
extern bool secondary_prio_200_executed;
|
||||||
|
extern bool secondary_prio_250_executed;
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test cases for the ESP_SYSTEM_INIT_FN mechanism.
|
||||||
|
*
|
||||||
|
* The init functions are defined in test_init_fn_defs.c and are executed
|
||||||
|
* automatically during startup (before app_main). These tests inspect the
|
||||||
|
* side-effects left by those functions to verify:
|
||||||
|
*
|
||||||
|
* 1. Init functions actually executed.
|
||||||
|
* 2. CORE-stage functions executed before SECONDARY-stage functions.
|
||||||
|
* 3. Within the same stage, lower priority values execute first.
|
||||||
|
* 4. All expected functions ran (no silent drops).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "unity.h"
|
||||||
|
#include "unity_test_runner.h"
|
||||||
|
#include "test_init_fn_defs.h"
|
||||||
|
|
||||||
|
/* ---------- Test cases ---------- */
|
||||||
|
|
||||||
|
TEST_CASE("CORE init functions executed", "[sys_init_fn]")
|
||||||
|
{
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(core_prio_200_executed,
|
||||||
|
"CORE priority-200 init function did not execute");
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(core_prio_250_executed,
|
||||||
|
"CORE priority-250 init function did not execute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SECONDARY init functions executed", "[sys_init_fn]")
|
||||||
|
{
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(secondary_prio_200_executed,
|
||||||
|
"SECONDARY priority-200 init function did not execute");
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(secondary_prio_250_executed,
|
||||||
|
"SECONDARY priority-250 init function did not execute");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("all four init functions traced", "[sys_init_fn]")
|
||||||
|
{
|
||||||
|
/* We registered 4 init functions total (2 CORE + 2 SECONDARY) */
|
||||||
|
TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(4, trace_count,
|
||||||
|
"expected at least 4 init function traces");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("CORE stage runs before SECONDARY stage", "[sys_init_fn]")
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* In the trace log, CORE entries have tags < 1000,
|
||||||
|
* SECONDARY entries have tags >= 1000.
|
||||||
|
* All CORE entries must appear before any SECONDARY entry.
|
||||||
|
*/
|
||||||
|
int first_secondary = -1;
|
||||||
|
int last_core = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < trace_count; i++) {
|
||||||
|
if (trace_log[i] < 1000) {
|
||||||
|
last_core = i;
|
||||||
|
} else if (first_secondary < 0) {
|
||||||
|
first_secondary = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(last_core >= 0, "no CORE trace entries found");
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(first_secondary >= 0, "no SECONDARY trace entries found");
|
||||||
|
TEST_ASSERT_LESS_THAN_INT_MESSAGE(first_secondary, last_core,
|
||||||
|
"a CORE init function ran after a SECONDARY one");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("priority ordering within CORE stage", "[sys_init_fn]")
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Within the CORE stage, priority 200 (tag 200) must appear
|
||||||
|
* before priority 250 (tag 250) in the trace log.
|
||||||
|
*/
|
||||||
|
int pos_200 = -1;
|
||||||
|
int pos_250 = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < trace_count; i++) {
|
||||||
|
if (trace_log[i] == 200 && pos_200 < 0) {
|
||||||
|
pos_200 = i;
|
||||||
|
}
|
||||||
|
if (trace_log[i] == 250 && pos_250 < 0) {
|
||||||
|
pos_250 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(pos_200 >= 0, "CORE prio-200 not in trace");
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(pos_250 >= 0, "CORE prio-250 not in trace");
|
||||||
|
TEST_ASSERT_LESS_THAN_INT_MESSAGE(pos_250, pos_200,
|
||||||
|
"CORE prio-200 did not run before prio-250");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("priority ordering within SECONDARY stage", "[sys_init_fn]")
|
||||||
|
{
|
||||||
|
int pos_1200 = -1;
|
||||||
|
int pos_1250 = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < trace_count; i++) {
|
||||||
|
if (trace_log[i] == 1200 && pos_1200 < 0) {
|
||||||
|
pos_1200 = i;
|
||||||
|
}
|
||||||
|
if (trace_log[i] == 1250 && pos_1250 < 0) {
|
||||||
|
pos_1250 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(pos_1200 >= 0, "SECONDARY prio-200 not in trace");
|
||||||
|
TEST_ASSERT_TRUE_MESSAGE(pos_1250 >= 0, "SECONDARY prio-250 not in trace");
|
||||||
|
TEST_ASSERT_LESS_THAN_INT_MESSAGE(pos_1250, pos_1200,
|
||||||
|
"SECONDARY prio-200 did not run before prio-250");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Entry point ---------- */
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
printf("Running sys_init_fn host test app\n");
|
||||||
|
unity_run_menu();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded_idf.dut import IdfDut
|
||||||
|
from pytest_embedded_idf.utils import idf_parametrize
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.host_test
|
||||||
|
@idf_parametrize('target', ['linux'], indirect=['target'])
|
||||||
|
def test_sys_init_fn_linux(dut: IdfDut) -> None:
|
||||||
|
dut.run_all_single_board_cases(timeout=60)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.host_test
|
||||||
|
@pytest.mark.macos
|
||||||
|
@idf_parametrize('target', ['linux'], indirect=['target'])
|
||||||
|
def test_sys_init_fn_macos(dut: IdfDut) -> None:
|
||||||
|
dut.run_all_single_board_cases(timeout=60)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
CONFIG_IDF_TARGET="linux"
|
||||||
@@ -98,7 +98,7 @@ static void main_task(void* args)
|
|||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
void esp_startup_start_app(void)
|
||||||
{
|
{
|
||||||
// This makes sure that stdio is always synchronized so that idf.py monitor
|
// This makes sure that stdio is always synchronized so that idf.py monitor
|
||||||
// and other tools read text output on time.
|
// and other tools read text output on time.
|
||||||
|
|||||||
@@ -30,3 +30,7 @@ idf_component_mock(INCLUDE_DIRS ${include_dirs}
|
|||||||
|
|
||||||
idf_component_get_property(freertos_lib freertos COMPONENT_LIB)
|
idf_component_get_property(freertos_lib freertos COMPONENT_LIB)
|
||||||
target_compile_definitions(${freertos_lib} PUBLIC "projCOVERAGE_TEST=0")
|
target_compile_definitions(${freertos_lib} PUBLIC "projCOVERAGE_TEST=0")
|
||||||
|
|
||||||
|
# When using FreeRTOS mocks, prevent esp_system from providing main() so tests can provide their own
|
||||||
|
idf_component_get_property(esp_system_lib esp_system COMPONENT_LIB)
|
||||||
|
target_compile_definitions(${esp_system_lib} PRIVATE ESP_SYSTEM_LINUX_NO_MAIN)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ menu "FreeRTOS"
|
|||||||
# Linux FreeRTOS port supports single-core only.
|
# Linux FreeRTOS port supports single-core only.
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
select ESP_SYSTEM_SINGLE_CORE_MODE
|
||||||
|
|
||||||
config FREERTOS_NUMBER_OF_CORES
|
config FREERTOS_NUMBER_OF_CORES
|
||||||
# Invisible option to configure the number of cores on which FreeRTOS runs
|
# Invisible option to configure the number of cores on which FreeRTOS runs
|
||||||
|
|||||||
Reference in New Issue
Block a user