Skip to content

Commit

Permalink
arch: native: Run Zephyr natively in a POSIX OS
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
aescolar authored and Anas Nashif committed Dec 27, 2017
1 parent 274ad46 commit 76f7644
Show file tree
Hide file tree
Showing 42 changed files with 2,324 additions and 9 deletions.
34 changes: 25 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ zephyr_include_directories(
${STDINCLUDE}
)


zephyr_compile_definitions(
KERNEL
__ZEPHYR__=1
Expand Down Expand Up @@ -95,11 +94,13 @@ zephyr_compile_options(
-Wformat
-Wformat-security
-Wno-format-zero-length
-Wno-main
-imacros ${AUTOCONF_H}
-ffreestanding
-include ${AUTOCONF_H}
-Wno-main
${NOSTDINC_F}
)


zephyr_compile_options(
$<$<COMPILE_LANGUAGE:C>:-std=c99>

Expand All @@ -114,13 +115,15 @@ zephyr_compile_options(
$<$<COMPILE_LANGUAGE:ASM>:-D_ASMLANGUAGE>
)

if(NOT CONFIG_NATIVE_APPLICATION)
zephyr_ld_options(
-nostartfiles
-nodefaultlibs
-nostdlib
-static
-no-pie
)
)
endif()

# ==========================================================================
#
Expand Down Expand Up @@ -231,7 +234,6 @@ endif()
zephyr_cc_option_ifdef(CONFIG_DEBUG_SECTION_MISMATCH -fno-inline-functions-called-once)
zephyr_cc_option_ifdef(CONFIG_STACK_USAGE -fstack-usage)

zephyr_compile_options(-nostdinc)
zephyr_system_include_directories(${NOSTDINC})

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

set_ifndef(LINKERFLAGPREFIX -Wl)

if(NOT CONFIG_NATIVE_APPLICATION)
zephyr_ld_options(
${LINKERFLAGPREFIX},-X
${LINKERFLAGPREFIX},-N
)
endif()

zephyr_ld_options(
${LINKERFLAGPREFIX},--gc-sections
${LINKERFLAGPREFIX},--build-id=none
)
Expand Down Expand Up @@ -502,7 +510,7 @@ add_custom_command(
# TODO: Remove duplication
COMMAND ${CMAKE_C_COMPILER}
-x assembler-with-cpp
-nostdinc
${NOSTDINC_F}
-undef
-MD -MF linker.cmd.dep -MT ${BASE_NAME}/linker.cmd
${ZEPHYR_INCLUDES}
Expand Down Expand Up @@ -676,12 +684,20 @@ endif()
get_property(GKOF GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES)
get_property(GKSF GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES)

get_property(TOPT GLOBAL PROPERTY TOPT)
set_ifndef( TOPT -T)

# FIXME: Is there any way to get rid of empty_file.c?
add_executable( zephyr_prebuilt misc/empty_file.c)
target_link_libraries(zephyr_prebuilt -T${PROJECT_BINARY_DIR}/linker.cmd ${zephyr_lnk})
target_link_libraries(zephyr_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker.cmd ${zephyr_lnk})
set_property(TARGET zephyr_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker.cmd)
add_dependencies( zephyr_prebuilt linker_script offsets)


if(NOT CONFIG_NATIVE_APPLICATION)
set(NOSTDINC_F -nostdinc)
endif()

if(GKOF OR GKSF)
set(logical_target_for_zephyr_elf kernel_elf)

Expand All @@ -694,7 +710,7 @@ if(GKOF OR GKSF)
${LINKER_SCRIPT_DEP}
COMMAND ${CMAKE_C_COMPILER}
-x assembler-with-cpp
-nostdinc
${NOSTDINC_F}
-undef
-MD -MF linker_pass2.cmd.dep -MT ${BASE_NAME}/linker_pass2.cmd
${ZEPHYR_INCLUDES}
Expand All @@ -713,7 +729,7 @@ if(GKOF OR GKSF)
)

add_executable( kernel_elf misc/empty_file.c ${GKSF})
target_link_libraries(kernel_elf ${GKOF} -T${PROJECT_BINARY_DIR}/linker_pass2.cmd ${zephyr_lnk})
target_link_libraries(kernel_elf ${GKOF} ${TOPT} ${PROJECT_BINARY_DIR}/linker_pass2.cmd ${zephyr_lnk})
set_property(TARGET kernel_elf PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_pass2.cmd)
add_dependencies( kernel_elf linker_pass2_script)
else()
Expand Down
8 changes: 8 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ config RISCV32
config XTENSA
bool "Xtensa architecture"

config ARCH_POSIX
bool "POSIX (native) architecture"
select ATOMIC_OPERATIONS_BUILTIN
select ARCH_HAS_CUSTOM_SWAP_TO_MAIN
select ARCH_HAS_CUSTOM_BUSY_WAIT
select ARCH_HAS_THREAD_ABORT
select NATIVE_APPLICATION

endchoice


Expand Down
37 changes: 37 additions & 0 deletions arch/posix/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
zephyr_cc_option_ifdef(CONFIG_LTO -flto)

zephyr_compile_options(
-fno-freestanding
-Wno-undef
-Wno-implicit-function-declaration
-m32
-MMD
-MP
${TOOLCHAIN_C_FLAGS}
${ARCH_FLAG}
-include ${PROJECT_SOURCE_DIR}/arch/posix/include/posix_cheats.h
)

zephyr_compile_definitions(_POSIX_C_SOURCE=199309)

zephyr_ld_options(
-ldl
-pthread
-m32
)

# About the -include directive: The reason to do it this way, is because in this
# manner it is transparent to the application. Otherwise posix_cheats.h needs to
# be included in all the applications' files which define main( ), and in any
# app file which uses the pthreads like API provided by Zephyr
# ( include/posix/pthread.h / kernel/pthread.c ) [And any future API added to
# Zephyr which will clash with the native POSIX API] . It would also need to
# be included in a few zephyr kernel files.


add_subdirectory(soc)
add_subdirectory(core)

# Override the flag used with linker.cmd
# "-Wl,--just-symbols linker.cmd" instead of "-T linker.cmd"
set_property(GLOBAL PROPERTY TOPT -Wl,--just-symbols)
31 changes: 31 additions & 0 deletions arch/posix/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Kconfig - General configuration options

#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

choice
prompt "POSIX Configuration Selection"
depends on ARCH_POSIX

source "arch/posix/soc/*/Kconfig.soc"
endchoice

menu "POSIX (native) Options"
depends on ARCH_POSIX

config ARCH
default "posix"

config ARCH_DEFCONFIG
string
default "arch/posix/defconfig"

source "arch/posix/core/Kconfig"


source "arch/posix/soc/*/Kconfig"

endmenu
9 changes: 9 additions & 0 deletions arch/posix/core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
zephyr_library()
zephyr_library_compile_definitions(_POSIX_CHEATS_H)
zephyr_library_sources(
cpuhalt.c
fatal.c
posix_core.c
swap.c
thread.c
)
64 changes: 64 additions & 0 deletions arch/posix/core/cpuhalt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2011-2015 Wind River Systems, Inc.
* Copyright (c) 2017 Oticon A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file CPU power management code for POSIX
*
* This module provides an implementation of the architecture-specific
* k_cpu_idle() primitive required by the kernel idle loop component.
* It can be called within an implementation of _sys_power_save_idle(),
* which is provided for the kernel by the platform.
*
* The module also provides an implementation of k_cpu_atomic_idle(), which
* atomically re-enables interrupts and enters low power mode.
*
*/

#include "posix_core.h"
#include "posix_soc_if.h"

/**
*
* @brief Power save idle routine for IA-32
*
* This function will be called by the kernel idle loop or possibly within
* an implementation of _sys_power_save_idle in the kernel when the
* '_sys_power_save_flag' variable is non-zero.
*
* This function is just a pass thru to the SOC one
*
* @return N/A
*/
void k_cpu_idle(void)
{
posix_irq_full_unlock();
posix_halt_cpu();
}

/**
*
* @brief Atomically re-enable interrupts and enter low power mode
*
* INTERNAL
* The requirements for k_cpu_atomic_idle() are as follows:
* 1) The enablement of interrupts and entering a low-power mode needs to be
* atomic, i.e. there should be no period of time where interrupts are
* enabled before the processor enters a low-power mode. See the comments
* in k_lifo_get(), for example, of the race condition that
* occurs if this requirement is not met.
*
* 2) After waking up from the low-power mode, the interrupt lockout state
* must be restored as indicated in the 'imask' input parameter.
*
* This function is just a pass thru to the SOC one
*
* @return N/A
*/

void k_cpu_atomic_idle(unsigned int imask)
{
posix_atomic_halt_cpu(imask);
}
124 changes: 124 additions & 0 deletions arch/posix/core/fatal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2016 Intel Corporation
* Copyright (c) 2017 Oticon A/S
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <kernel.h>
#include <arch/cpu.h>
#include <kernel_structs.h>
#include <misc/printk.h>
#include <inttypes.h>
#include "posix_soc_if.h"

const NANO_ESF _default_esf = {
0xdeadbaad
};

/**
*
* @brief Kernel fatal error handler
*
* This routine is called when a fatal error condition is detected
*
* The caller is expected to always provide a usable ESF. In the event that the
* fatal error does not have a hardware generated ESF, the caller should either
* create its own or call _Fault instead.
*
* @param reason the reason that the handler was called
* @param pEsf pointer to the exception stack frame
*
* @return This function does not return.
*/
FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
const NANO_ESF *esf)
{
#ifdef CONFIG_PRINTK
switch (reason) {
case _NANO_ERR_CPU_EXCEPTION:
case _NANO_ERR_SPURIOUS_INT:
break;

case _NANO_ERR_INVALID_TASK_EXIT:
printk("***** Invalid Exit Software Error! *****\n");
break;


case _NANO_ERR_ALLOCATION_FAIL:
printk("**** Kernel Allocation Failure! ****\n");
break;

case _NANO_ERR_KERNEL_OOPS:
printk("***** Kernel OOPS! *****\n");
break;

case _NANO_ERR_KERNEL_PANIC:
printk("***** Kernel Panic! *****\n");
break;

#ifdef CONFIG_STACK_SENTINEL
case _NANO_ERR_STACK_CHK_FAIL:
printk("***** Stack overflow *****\n");
break;
#endif
default:
printk("**** Unknown Fatal Error %u! ****\n", reason);
break;
}

#endif

void _SysFatalErrorHandler(unsigned int reason,
const NANO_ESF *pEsf);
_SysFatalErrorHandler(reason, esf);
}


/**
*
* @brief Fatal error handler
*
* This routine implements the corrective action to be taken when the system
* detects a fatal error.
*
* This sample implementation attempts to abort the current thread and allow
* the system to continue executing, which may permit the system to continue
* functioning with degraded capabilities.
*
* System designers may wish to enhance or substitute this sample
* implementation to take other actions, such as logging error (or debug)
* information to a persistent repository and/or rebooting the system.
*
* @param reason the fatal error reason
* @param pEsf pointer to exception stack frame
*
* @return N/A
*/
FUNC_NORETURN __weak void _SysFatalErrorHandler(unsigned int reason,
const NANO_ESF *pEsf)
{
ARG_UNUSED(pEsf);

#ifdef CONFIG_STACK_SENTINEL
if (reason == _NANO_ERR_STACK_CHK_FAIL) {
goto hang_system;
}
#endif
if (reason == _NANO_ERR_KERNEL_PANIC) {
goto hang_system;
}
if (k_is_in_isr() || _is_thread_essential()) {
posix_print_error_and_exit(
"Fatal fault in %s! Stopping...\n",
k_is_in_isr() ? "ISR" : "essential thread");
}
printk("Fatal fault in thread %p! Aborting.\n", _current);
k_thread_abort(_current);

hang_system:

posix_print_error_and_exit(
"Stopped in _SysFatalErrorHandler()\n");
CODE_UNREACHABLE;
}
Loading

0 comments on commit 76f7644

Please sign in to comment.