Skip to content

Commit 76f7644

Browse files
aescolarAnas Nashif
authored and
Anas Nashif
committed
arch: native: Run Zephyr natively in a POSIX OS
A new arch (posix) which relies on pthreads to emulate the context switching A new soc for it (inf_clock) which emulates a CPU running at an infinely high clock (so when the CPU is awaken it runs till completion in 0 time) A new board, which provides a trivial system tick timer and irq generation. Origin: Original Fixes #1891 Signed-off-by: Alberto Escolar Piedras <[email protected]> Signed-off-by: Anas Nashif <[email protected]>
1 parent 274ad46 commit 76f7644

Some content is hidden

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

42 files changed

+2324
-9
lines changed

CMakeLists.txt

+25-9
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ zephyr_include_directories(
6464
${STDINCLUDE}
6565
)
6666

67-
6867
zephyr_compile_definitions(
6968
KERNEL
7069
__ZEPHYR__=1
@@ -95,11 +94,13 @@ zephyr_compile_options(
9594
-Wformat
9695
-Wformat-security
9796
-Wno-format-zero-length
98-
-Wno-main
97+
-imacros ${AUTOCONF_H}
9998
-ffreestanding
100-
-include ${AUTOCONF_H}
99+
-Wno-main
100+
${NOSTDINC_F}
101101
)
102102

103+
103104
zephyr_compile_options(
104105
$<$<COMPILE_LANGUAGE:C>:-std=c99>
105106

@@ -114,13 +115,15 @@ zephyr_compile_options(
114115
$<$<COMPILE_LANGUAGE:ASM>:-D_ASMLANGUAGE>
115116
)
116117

118+
if(NOT CONFIG_NATIVE_APPLICATION)
117119
zephyr_ld_options(
118120
-nostartfiles
119121
-nodefaultlibs
120122
-nostdlib
121123
-static
122124
-no-pie
123-
)
125+
)
126+
endif()
124127

125128
# ==========================================================================
126129
#
@@ -231,7 +234,6 @@ endif()
231234
zephyr_cc_option_ifdef(CONFIG_DEBUG_SECTION_MISMATCH -fno-inline-functions-called-once)
232235
zephyr_cc_option_ifdef(CONFIG_STACK_USAGE -fstack-usage)
233236

234-
zephyr_compile_options(-nostdinc)
235237
zephyr_system_include_directories(${NOSTDINC})
236238

237239
# Force an error when things like SYS_INIT(foo, ...) occur with a missing header.
@@ -248,9 +250,15 @@ if(IS_TEST)
248250
endif()
249251

250252
set_ifndef(LINKERFLAGPREFIX -Wl)
253+
254+
if(NOT CONFIG_NATIVE_APPLICATION)
251255
zephyr_ld_options(
252256
${LINKERFLAGPREFIX},-X
253257
${LINKERFLAGPREFIX},-N
258+
)
259+
endif()
260+
261+
zephyr_ld_options(
254262
${LINKERFLAGPREFIX},--gc-sections
255263
${LINKERFLAGPREFIX},--build-id=none
256264
)
@@ -502,7 +510,7 @@ add_custom_command(
502510
# TODO: Remove duplication
503511
COMMAND ${CMAKE_C_COMPILER}
504512
-x assembler-with-cpp
505-
-nostdinc
513+
${NOSTDINC_F}
506514
-undef
507515
-MD -MF linker.cmd.dep -MT ${BASE_NAME}/linker.cmd
508516
${ZEPHYR_INCLUDES}
@@ -676,12 +684,20 @@ endif()
676684
get_property(GKOF GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES)
677685
get_property(GKSF GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES)
678686

687+
get_property(TOPT GLOBAL PROPERTY TOPT)
688+
set_ifndef( TOPT -T)
689+
679690
# FIXME: Is there any way to get rid of empty_file.c?
680691
add_executable( zephyr_prebuilt misc/empty_file.c)
681-
target_link_libraries(zephyr_prebuilt -T${PROJECT_BINARY_DIR}/linker.cmd ${zephyr_lnk})
692+
target_link_libraries(zephyr_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker.cmd ${zephyr_lnk})
682693
set_property(TARGET zephyr_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker.cmd)
683694
add_dependencies( zephyr_prebuilt linker_script offsets)
684695

696+
697+
if(NOT CONFIG_NATIVE_APPLICATION)
698+
set(NOSTDINC_F -nostdinc)
699+
endif()
700+
685701
if(GKOF OR GKSF)
686702
set(logical_target_for_zephyr_elf kernel_elf)
687703

@@ -694,7 +710,7 @@ if(GKOF OR GKSF)
694710
${LINKER_SCRIPT_DEP}
695711
COMMAND ${CMAKE_C_COMPILER}
696712
-x assembler-with-cpp
697-
-nostdinc
713+
${NOSTDINC_F}
698714
-undef
699715
-MD -MF linker_pass2.cmd.dep -MT ${BASE_NAME}/linker_pass2.cmd
700716
${ZEPHYR_INCLUDES}
@@ -713,7 +729,7 @@ if(GKOF OR GKSF)
713729
)
714730

715731
add_executable( kernel_elf misc/empty_file.c ${GKSF})
716-
target_link_libraries(kernel_elf ${GKOF} -T${PROJECT_BINARY_DIR}/linker_pass2.cmd ${zephyr_lnk})
732+
target_link_libraries(kernel_elf ${GKOF} ${TOPT} ${PROJECT_BINARY_DIR}/linker_pass2.cmd ${zephyr_lnk})
717733
set_property(TARGET kernel_elf PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_pass2.cmd)
718734
add_dependencies( kernel_elf linker_pass2_script)
719735
else()

arch/Kconfig

+8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ config RISCV32
3434
config XTENSA
3535
bool "Xtensa architecture"
3636

37+
config ARCH_POSIX
38+
bool "POSIX (native) architecture"
39+
select ATOMIC_OPERATIONS_BUILTIN
40+
select ARCH_HAS_CUSTOM_SWAP_TO_MAIN
41+
select ARCH_HAS_CUSTOM_BUSY_WAIT
42+
select ARCH_HAS_THREAD_ABORT
43+
select NATIVE_APPLICATION
44+
3745
endchoice
3846

3947

arch/posix/CMakeLists.txt

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
zephyr_cc_option_ifdef(CONFIG_LTO -flto)
2+
3+
zephyr_compile_options(
4+
-fno-freestanding
5+
-Wno-undef
6+
-Wno-implicit-function-declaration
7+
-m32
8+
-MMD
9+
-MP
10+
${TOOLCHAIN_C_FLAGS}
11+
${ARCH_FLAG}
12+
-include ${PROJECT_SOURCE_DIR}/arch/posix/include/posix_cheats.h
13+
)
14+
15+
zephyr_compile_definitions(_POSIX_C_SOURCE=199309)
16+
17+
zephyr_ld_options(
18+
-ldl
19+
-pthread
20+
-m32
21+
)
22+
23+
# About the -include directive: The reason to do it this way, is because in this
24+
# manner it is transparent to the application. Otherwise posix_cheats.h needs to
25+
# be included in all the applications' files which define main( ), and in any
26+
# app file which uses the pthreads like API provided by Zephyr
27+
# ( include/posix/pthread.h / kernel/pthread.c ) [And any future API added to
28+
# Zephyr which will clash with the native POSIX API] . It would also need to
29+
# be included in a few zephyr kernel files.
30+
31+
32+
add_subdirectory(soc)
33+
add_subdirectory(core)
34+
35+
# Override the flag used with linker.cmd
36+
# "-Wl,--just-symbols linker.cmd" instead of "-T linker.cmd"
37+
set_property(GLOBAL PROPERTY TOPT -Wl,--just-symbols)

arch/posix/Kconfig

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Kconfig - General configuration options
2+
3+
#
4+
# Copyright (c) 2017 Intel Corporation
5+
#
6+
# SPDX-License-Identifier: Apache-2.0
7+
#
8+
9+
choice
10+
prompt "POSIX Configuration Selection"
11+
depends on ARCH_POSIX
12+
13+
source "arch/posix/soc/*/Kconfig.soc"
14+
endchoice
15+
16+
menu "POSIX (native) Options"
17+
depends on ARCH_POSIX
18+
19+
config ARCH
20+
default "posix"
21+
22+
config ARCH_DEFCONFIG
23+
string
24+
default "arch/posix/defconfig"
25+
26+
source "arch/posix/core/Kconfig"
27+
28+
29+
source "arch/posix/soc/*/Kconfig"
30+
31+
endmenu

arch/posix/core/CMakeLists.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
zephyr_library()
2+
zephyr_library_compile_definitions(_POSIX_CHEATS_H)
3+
zephyr_library_sources(
4+
cpuhalt.c
5+
fatal.c
6+
posix_core.c
7+
swap.c
8+
thread.c
9+
)

arch/posix/core/cpuhalt.c

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2011-2015 Wind River Systems, Inc.
3+
* Copyright (c) 2017 Oticon A/S
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
/**
8+
* @file CPU power management code for POSIX
9+
*
10+
* This module provides an implementation of the architecture-specific
11+
* k_cpu_idle() primitive required by the kernel idle loop component.
12+
* It can be called within an implementation of _sys_power_save_idle(),
13+
* which is provided for the kernel by the platform.
14+
*
15+
* The module also provides an implementation of k_cpu_atomic_idle(), which
16+
* atomically re-enables interrupts and enters low power mode.
17+
*
18+
*/
19+
20+
#include "posix_core.h"
21+
#include "posix_soc_if.h"
22+
23+
/**
24+
*
25+
* @brief Power save idle routine for IA-32
26+
*
27+
* This function will be called by the kernel idle loop or possibly within
28+
* an implementation of _sys_power_save_idle in the kernel when the
29+
* '_sys_power_save_flag' variable is non-zero.
30+
*
31+
* This function is just a pass thru to the SOC one
32+
*
33+
* @return N/A
34+
*/
35+
void k_cpu_idle(void)
36+
{
37+
posix_irq_full_unlock();
38+
posix_halt_cpu();
39+
}
40+
41+
/**
42+
*
43+
* @brief Atomically re-enable interrupts and enter low power mode
44+
*
45+
* INTERNAL
46+
* The requirements for k_cpu_atomic_idle() are as follows:
47+
* 1) The enablement of interrupts and entering a low-power mode needs to be
48+
* atomic, i.e. there should be no period of time where interrupts are
49+
* enabled before the processor enters a low-power mode. See the comments
50+
* in k_lifo_get(), for example, of the race condition that
51+
* occurs if this requirement is not met.
52+
*
53+
* 2) After waking up from the low-power mode, the interrupt lockout state
54+
* must be restored as indicated in the 'imask' input parameter.
55+
*
56+
* This function is just a pass thru to the SOC one
57+
*
58+
* @return N/A
59+
*/
60+
61+
void k_cpu_atomic_idle(unsigned int imask)
62+
{
63+
posix_atomic_halt_cpu(imask);
64+
}

arch/posix/core/fatal.c

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright (c) 2016 Intel Corporation
3+
* Copyright (c) 2017 Oticon A/S
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <kernel.h>
9+
#include <arch/cpu.h>
10+
#include <kernel_structs.h>
11+
#include <misc/printk.h>
12+
#include <inttypes.h>
13+
#include "posix_soc_if.h"
14+
15+
const NANO_ESF _default_esf = {
16+
0xdeadbaad
17+
};
18+
19+
/**
20+
*
21+
* @brief Kernel fatal error handler
22+
*
23+
* This routine is called when a fatal error condition is detected
24+
*
25+
* The caller is expected to always provide a usable ESF. In the event that the
26+
* fatal error does not have a hardware generated ESF, the caller should either
27+
* create its own or call _Fault instead.
28+
*
29+
* @param reason the reason that the handler was called
30+
* @param pEsf pointer to the exception stack frame
31+
*
32+
* @return This function does not return.
33+
*/
34+
FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
35+
const NANO_ESF *esf)
36+
{
37+
#ifdef CONFIG_PRINTK
38+
switch (reason) {
39+
case _NANO_ERR_CPU_EXCEPTION:
40+
case _NANO_ERR_SPURIOUS_INT:
41+
break;
42+
43+
case _NANO_ERR_INVALID_TASK_EXIT:
44+
printk("***** Invalid Exit Software Error! *****\n");
45+
break;
46+
47+
48+
case _NANO_ERR_ALLOCATION_FAIL:
49+
printk("**** Kernel Allocation Failure! ****\n");
50+
break;
51+
52+
case _NANO_ERR_KERNEL_OOPS:
53+
printk("***** Kernel OOPS! *****\n");
54+
break;
55+
56+
case _NANO_ERR_KERNEL_PANIC:
57+
printk("***** Kernel Panic! *****\n");
58+
break;
59+
60+
#ifdef CONFIG_STACK_SENTINEL
61+
case _NANO_ERR_STACK_CHK_FAIL:
62+
printk("***** Stack overflow *****\n");
63+
break;
64+
#endif
65+
default:
66+
printk("**** Unknown Fatal Error %u! ****\n", reason);
67+
break;
68+
}
69+
70+
#endif
71+
72+
void _SysFatalErrorHandler(unsigned int reason,
73+
const NANO_ESF *pEsf);
74+
_SysFatalErrorHandler(reason, esf);
75+
}
76+
77+
78+
/**
79+
*
80+
* @brief Fatal error handler
81+
*
82+
* This routine implements the corrective action to be taken when the system
83+
* detects a fatal error.
84+
*
85+
* This sample implementation attempts to abort the current thread and allow
86+
* the system to continue executing, which may permit the system to continue
87+
* functioning with degraded capabilities.
88+
*
89+
* System designers may wish to enhance or substitute this sample
90+
* implementation to take other actions, such as logging error (or debug)
91+
* information to a persistent repository and/or rebooting the system.
92+
*
93+
* @param reason the fatal error reason
94+
* @param pEsf pointer to exception stack frame
95+
*
96+
* @return N/A
97+
*/
98+
FUNC_NORETURN __weak void _SysFatalErrorHandler(unsigned int reason,
99+
const NANO_ESF *pEsf)
100+
{
101+
ARG_UNUSED(pEsf);
102+
103+
#ifdef CONFIG_STACK_SENTINEL
104+
if (reason == _NANO_ERR_STACK_CHK_FAIL) {
105+
goto hang_system;
106+
}
107+
#endif
108+
if (reason == _NANO_ERR_KERNEL_PANIC) {
109+
goto hang_system;
110+
}
111+
if (k_is_in_isr() || _is_thread_essential()) {
112+
posix_print_error_and_exit(
113+
"Fatal fault in %s! Stopping...\n",
114+
k_is_in_isr() ? "ISR" : "essential thread");
115+
}
116+
printk("Fatal fault in thread %p! Aborting.\n", _current);
117+
k_thread_abort(_current);
118+
119+
hang_system:
120+
121+
posix_print_error_and_exit(
122+
"Stopped in _SysFatalErrorHandler()\n");
123+
CODE_UNREACHABLE;
124+
}

0 commit comments

Comments
 (0)