Skip to content

Commit ecd0a0c

Browse files
committed
Add ThreadX posix support
Change-Id: Ie4909fbdc30770dc6a4c20d46020a6f4f8212e14
1 parent 27fb564 commit ecd0a0c

File tree

68 files changed

+3043
-302
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+3043
-302
lines changed

.ci/build.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import shutil
2+
from pathlib import Path
3+
import subprocess
4+
import sys
5+
import os
6+
7+
def get_full_command_path(command):
8+
if (cmd := shutil.which(command)) is None:
9+
print(f"ERROR: Compiler command {command} not found!")
10+
sys.exit(1)
11+
return cmd
12+
13+
def get_environment_variables(platform, compiler):
14+
env = dict(os.environ)
15+
if platform == "s32k148":
16+
if compiler == "gcc":
17+
env["CC"] = get_full_command_path("arm-none-eabi-gcc")
18+
env["CXX"] = get_full_command_path("arm-none-eabi-gcc")
19+
elif compiler == "clang":
20+
env["CC"] = get_full_command_path("/usr/bin/llvm-arm/bin/clang")
21+
env["CXX"] = get_full_command_path("/usr/bin/llvm-arm/bin/clang++")
22+
23+
elif platform == "posix":
24+
if compiler == "clang":
25+
env["CC"] = get_full_command_path("clang")
26+
env["CXX"] = get_full_command_path("clang++")
27+
elif compiler == "gcc":
28+
env["CC"] = get_full_command_path("gcc")
29+
env["CXX"] = get_full_command_path("gcc")
30+
return env
31+
32+
def configure_and_build(platform, compiler, cpp_standard):
33+
build_dir = Path(f"cmake-build-{platform}-{compiler}")
34+
if build_dir.exists():
35+
shutil.rmtree(build_dir)
36+
37+
cmake_command = [
38+
"cmake",
39+
"-B", build_dir,
40+
"-S", "executables/referenceApp",
41+
f"-DCMAKE_CXX_STANDARD={cpp_standard}",
42+
f"-DBUILD_TARGET_PLATFORM={'POSIX' if platform == 'posix' else 'S32K148EVB'}",
43+
f"-DCMAKE_TOOLCHAIN_FILE={'../../admin/cmake/ArmNoneEabi-' + compiler + '.cmake' if platform == 's32k148' else ''}"
44+
]
45+
subprocess.run(cmake_command, check=True, env=get_environment_variables(platform, compiler))
46+
subprocess.run(["cmake", "--build", build_dir, "--target", "app.referenceApp", "-j"], check=True, env=get_environment_variables(platform, compiler))
47+
48+
def main():
49+
if len(sys.argv) != 4:
50+
print("ERROR: Usage: build.py <platform> <compiler> <cpp_standard>")
51+
sys.exit(1)
52+
53+
platform = sys.argv[1]
54+
compiler = sys.argv[2]
55+
cpp_standard = sys.argv[3]
56+
57+
configure_and_build(platform, compiler, cpp_standard)
58+
59+
if __name__ == "__main__":
60+
main()

.ci/build_matrix.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import subprocess
2+
3+
platforms = ["posix", "s32k148"]
4+
compilers = ["clang", "gcc"]
5+
cpp_standards = ["14", "17", "20", "23"]
6+
7+
def main():
8+
for platform in platforms:
9+
for compiler in compilers:
10+
for cpp_standard in cpp_standards:
11+
print(f"Running build for platform={platform}, compiler={compiler}, cpp_standard={cpp_standard}")
12+
subprocess.run(
13+
["python3", ".ci/build.py", platform, compiler, str(cpp_standard)],
14+
check=True
15+
)
16+
print("All combinations have been processed.")
17+
18+
if __name__ == "__main__":
19+
main()

.ci/code_coverage.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import subprocess
2+
from pathlib import Path
3+
import shutil
4+
import sys
5+
import re
6+
7+
def configure_cmake(build_type):
8+
9+
unit_tests_build_dir = Path("cmake-build-unit-tests")
10+
if unit_tests_build_dir.exists():
11+
shutil.rmtree(unit_tests_build_dir)
12+
13+
subprocess.run([
14+
"cmake", "-B", "cmake-build-unit-tests", "-S", "executables/unitTest",
15+
"-DBUILD_UNIT_TESTS=ON",
16+
f"-DCMAKE_BUILD_TYPE={build_type}",
17+
"-DCMAKE_C_COMPILER_LAUNCHER=sccache",
18+
"-DCMAKE_CXX_COMPILER_LAUNCHER=sccache"
19+
], check=True)
20+
21+
def build_with_cmake():
22+
subprocess.run(["cmake", "--build", "cmake-build-unit-tests", "-j4"], check=True)
23+
24+
def run_tests():
25+
subprocess.run(["ctest", "--test-dir", "cmake-build-unit-tests", "-j4"], check=True)
26+
27+
def generate_coverage():
28+
# Capture coverage data
29+
subprocess.run([
30+
"lcov", "--no-external", "--capture", "--directory", ".",
31+
"--output-file", "cmake-build-unit-tests/coverage_unfiltered.info"
32+
], check=True)
33+
34+
# Remove unwanted paths from coverage
35+
subprocess.run([
36+
"lcov", "--remove", "cmake-build-unit-tests/coverage_unfiltered.info",
37+
"*libs/3rdparty/googletest/*", "*/mock/*", "*/gmock/*", "*/gtest/*", "*/test/*",
38+
"--output-file", "cmake-build-unit-tests/coverage.info"
39+
], check=True)
40+
41+
# Generate HTML report
42+
subprocess.run([
43+
"genhtml", "cmake-build-unit-tests/coverage.info",
44+
"--output-directory", "cmake-build-unit-tests/coverage"
45+
], check=True)
46+
47+
def generate_badges():
48+
result = subprocess.run(
49+
["lcov", "--summary", "cmake-build-unit-tests/coverage.info"],
50+
capture_output=True, text=True, check=True
51+
)
52+
summary = result.stdout
53+
54+
line_percentage = re.search(r"lines\.*:\s+(\d+\.\d+)%", summary)
55+
function_percentage = re.search(r"functions\.*:\s+(\d+\.\d+)%", summary)
56+
57+
if line_percentage:
58+
line_value = line_percentage.group(1)
59+
print(f"Line Percentage: {line_value}%")
60+
subprocess.run([
61+
"wget", f"https://img.shields.io/badge/coverage-{line_value}%25-brightgreen.svg",
62+
"-O", "line_coverage_badge.svg"
63+
], check=True)
64+
65+
if function_percentage:
66+
function_value = function_percentage.group(1)
67+
print(f"Function Percentage: {function_value}%")
68+
subprocess.run([
69+
"wget", f"https://img.shields.io/badge/coverage-{function_value}%25-brightgreen.svg",
70+
"-O", "function_coverage_badge.svg"
71+
], check=True)
72+
73+
if __name__ == "__main__":
74+
try:
75+
configure_cmake("Debug")
76+
build_with_cmake()
77+
run_tests()
78+
generate_coverage()
79+
generate_badges()
80+
except subprocess.CalledProcessError as e:
81+
print(f"Command failed with exit code {e.returncode}")
82+
sys.exit(e.returncode)

.ci/doxygen-docs.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import subprocess
2+
import os
3+
import shutil
4+
from pathlib import Path
5+
import sys
6+
7+
def clean_build():
8+
build_dir = Path("doc/doxygenOut")
9+
if build_dir.exists():
10+
shutil.rmtree(build_dir)
11+
file_path_doc_coverage = Path("doc/doc-coverage.info")
12+
if os.path.exists(file_path_doc_coverage):
13+
os.remove(file_path_doc_coverage)
14+
file_path_warning = Path("doc/DoxygenWarningLog.txt")
15+
if os.path.exists(file_path_warning):
16+
os.remove(file_path_warning)
17+
18+
def run_doxygen():
19+
os.chdir("./doc")
20+
subprocess.run(["doxygen", "Doxyfile"], check=True)
21+
22+
def print_doxygen_warning_log():
23+
with open("DoxygenWarningLog.txt", "r") as file:
24+
print(file.read())
25+
26+
def run_coverxygen():
27+
subprocess.run(["python3", "-m", "coverxygen", "--format", "summary", "--xml-dir", "doxygenOut/xml/", "--src-dir", "..", "--output", "doc-coverage.info"], check=True)
28+
29+
def print_doc_coverage():
30+
with open("doc-coverage.info", "r") as file:
31+
print(file.read())
32+
33+
if __name__ == "__main__":
34+
try:
35+
clean_build()
36+
run_doxygen()
37+
print_doxygen_warning_log()
38+
run_coverxygen()
39+
print_doc_coverage()
40+
except subprocess.CalledProcessError as e:
41+
print(f"Command failed with exit code {e.returncode}")
42+
sys.exit(e.returncode)

.ci/format.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import subprocess
2+
import sys
3+
4+
def check_code_format():
5+
subprocess.run(["treefmt", "--no-cache"], check=True)
6+
subprocess.run(["git", "diff", "--exit-code"], check=True)
7+
8+
if __name__ == "__main__":
9+
try:
10+
check_code_format()
11+
except subprocess.CalledProcessError as e:
12+
print(f"Command failed with exit code {e.returncode}")
13+
sys.exit(e.returncode)

.ci/pytest.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import subprocess
2+
import os
3+
import sys
4+
5+
def build_reference_app():
6+
subprocess.run(["cmake", "-B", "cmake-build-posix", "-S", "executables/referenceApp"], check=True)
7+
subprocess.run(["cmake", "--build", "cmake-build-posix", "--target", "app.referenceApp", "-j"], check=True)
8+
9+
def run_pytest():
10+
os.chdir("./test/pyTest")
11+
subprocess.run(['pytest', '--target=posix'], check=True)
12+
13+
if __name__ == "__main__":
14+
try:
15+
build_reference_app()
16+
run_pytest()
17+
except subprocess.CalledProcessError as e:
18+
print(f"Command failed with exit code {e.returncode}")
19+
sys.exit(e.returncode)

.ci/sphinx-docs.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import os
2+
import subprocess
3+
import shutil
4+
from pathlib import Path
5+
import sys
6+
7+
def build_sphinx_docs():
8+
build_dir = Path("doc/build")
9+
if build_dir.exists():
10+
shutil.rmtree(build_dir)
11+
os.chdir("./doc")
12+
subprocess.run(["make", "html", "OFFICIAL_BUILD=1"], check=True)
13+
14+
if __name__ == "__main__":
15+
try:
16+
build_sphinx_docs()
17+
except subprocess.CalledProcessError as e:
18+
print(f"Command failed with exit code {e.returncode}")
19+
sys.exit(e.returncode)

Filelists.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ add_compile_options(
3030
"$<$<COMPILE_LANG_AND_ID:CXX,Clang,GNU>:-O2;-g3;-Werror;-Wall;-Wextra;-Wvla;-Wno-deprecated-volatile>"
3131
# todo: enforce -Wunused-parameter
3232
"$<$<COMPILE_LANG_AND_ID:CXX,Clang,GNU>:-Wno-error=unused-parameter>"
33+
"$<$<COMPILE_LANG_AND_ID:C,Clang,GNU>:-Wno-error=unused-parameter>"
3334
# note: the below warnings are often false positive
3435
"$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=stringop-overflow;-Wno-error=maybe-uninitialized>"
3536
)

admin/cmake/ArmNoneEabi.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ set(C_COMMON_FLAGS
2323
-fno-asynchronous-unwind-tables -fno-builtin -fno-common \
2424
-ffunction-sections -fdata-sections")
2525

26-
set(CMAKE_ASM_FLAGS "-g -mcpu=cortex-m4")
26+
set(CMAKE_ASM_FLAGS "-g -mcpu=cortex-m4 \
27+
-mfloat-abi=hard -mfpu=fpv4-sp-d16")
2728
set(CMAKE_C_FLAGS "${C_COMMON_FLAGS} -ffreestanding")
2829
set(CMAKE_CXX_FLAGS "${C_COMMON_FLAGS} -fno-rtti -fno-exceptions \
2930
-fno-non-call-exceptions -fno-threadsafe-statics -fno-use-cxa-atexit")

executables/referenceApp/CMakeLists.txt

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,41 @@ option(PLATFORM_SUPPORT_IO "Turn IO support on or off" OFF)
1515
option(PLATFORM_SUPPORT_UDS "Turn UDS support on or off" OFF)
1616

1717
set(BUILD_TARGET_PLATFORM
18-
"POSIX"
18+
"POSIX_FREERTOS"
1919
CACHE STRING "Target Platform")
2020

21-
set(SUPPORTED_PLATFORMS POSIX S32K148EVB)
21+
set(SUPPORTED_PLATFORMS POSIX_FREERTOS POSIX_THREADX S32K148EVB_FREERTOS
22+
S32K148EVB_THREADX)
2223
if (NOT (BUILD_TARGET_PLATFORM IN_LIST SUPPORTED_PLATFORMS))
2324
message(FATAL_ERROR "Unknown target platform <${BUILD_TARGET_PLATFORM}>")
2425
endif ()
2526

2627
message(STATUS "Target platform: <${BUILD_TARGET_PLATFORM}>")
2728

28-
if (BUILD_TARGET_PLATFORM STREQUAL "POSIX" AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
29+
if (BUILD_TARGET_PLATFORM STREQUAL "POSIX_FREERTOS"
30+
AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
2931
set(PLATFORM_SUPPORT_CAN
3032
ON
3133
CACHE BOOL "Turn CAN support on or off" FORCE)
3234
set(PLATFORM_SUPPORT_IO
3335
OFF
3436
CACHE BOOL "Turn IO support on or off" FORCE)
35-
elseif (BUILD_TARGET_PLATFORM STREQUAL "S32K148EVB")
37+
elseif (BUILD_TARGET_PLATFORM STREQUAL "POSIX_THREADX"
38+
AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
39+
set(PLATFORM_SUPPORT_CAN
40+
ON
41+
CACHE BOOL "Turn CAN support on or off" FORCE)
42+
set(PLATFORM_SUPPORT_IO
43+
OFF
44+
CACHE BOOL "Turn IO support on or off" FORCE)
45+
elseif (BUILD_TARGET_PLATFORM STREQUAL "S32K148EVB_FREERTOS")
46+
set(PLATFORM_SUPPORT_CAN
47+
ON
48+
CACHE BOOL "Turn CAN support on or off" FORCE)
49+
set(PLATFORM_SUPPORT_IO
50+
ON
51+
CACHE BOOL "Turn IO support on or off" FORCE)
52+
elseif (BUILD_TARGET_PLATFORM STREQUAL "S32K148EVB_THREADX")
3653
set(PLATFORM_SUPPORT_CAN
3754
ON
3855
CACHE BOOL "Turn CAN support on or off" FORCE)
@@ -65,18 +82,30 @@ endif ()
6582

6683
include(${OPENBSW_DIR}/Filelists.cmake)
6784

68-
# Configure async and freeRtos libs depending on build type.
69-
add_library(asyncPlatform ALIAS asyncFreeRtos)
70-
add_library(osFreeRtos ALIAS freeRtos)
71-
72-
if (BUILD_TARGET_PLATFORM STREQUAL "POSIX")
85+
if (BUILD_TARGET_PLATFORM STREQUAL "POSIX_FREERTOS")
86+
# Configure async and freeRtos libs depending on build type.
87+
add_library(asyncPlatform ALIAS asyncFreeRtos)
88+
add_library(osFreeRtos ALIAS freeRtos)
7389
add_subdirectory(platforms/posix)
7490
add_library(freeRtosPort ALIAS freeRtosPosixPort)
7591
add_library(freeRtosPortImpl ALIAS freeRtosPosix)
76-
elseif (BUILD_TARGET_PLATFORM STREQUAL "S32K148EVB")
92+
elseif (BUILD_TARGET_PLATFORM STREQUAL "POSIX_THREADX")
93+
add_library(asyncPlatform ALIAS asyncThreadX)
94+
add_subdirectory(platforms/posix)
95+
add_library(threadXPort ALIAS threadXLinuxPort)
96+
add_library(threadXPortImpl ALIAS threadXLinux)
97+
elseif (BUILD_TARGET_PLATFORM STREQUAL "S32K148EVB_FREERTOS")
98+
# Configure async and freeRtos libs depending on build type.
99+
add_library(asyncPlatform ALIAS asyncFreeRtos)
100+
add_library(osFreeRtos ALIAS freeRtos)
77101
add_subdirectory(platforms/s32k148evb)
78102
add_library(freeRtosPort ALIAS freeRtosCm4SysTickPort)
79103
add_library(freeRtosPortImpl ALIAS freeRtosCm4SysTick)
104+
elseif (BUILD_TARGET_PLATFORM STREQUAL "S32K148EVB_THREADX")
105+
add_library(asyncPlatform ALIAS asyncThreadX)
106+
add_subdirectory(platforms/s32k148evb)
107+
add_library(threadXPort ALIAS threadXCortexM4Port)
108+
add_library(threadXPortImpl ALIAS threadXCortexM4)
80109
endif ()
81110

82111
add_subdirectory(application)

0 commit comments

Comments
 (0)