Add support for FreeRTOS and lwIP (#166)

Add support for FreeRTOS and lwIP

Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
This commit is contained in:
Jeroen Koekkoek 2019-05-23 14:27:56 +02:00 committed by eboasson
parent dba4e6d391
commit aa2715f4fe
67 changed files with 3691 additions and 200 deletions

View file

@ -0,0 +1,126 @@
#
# Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
# v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
cmake_minimum_required(VERSION 3.5)
project(FreeRTOS-Sim VERSION 10.0.2.0)
include(GNUInstallDirs)
# Some distributions place libraries in lib64 when the architecture is x86_64,
# but since the simulator is compiled with -m32, lib is a better name.
if(UNIX AND CMAKE_INSTALL_LIBDIR STREQUAL "lib64")
set(CMAKE_INSTALL_LIBDIR "lib")
endif()
# Conflicts may be introduced when placing the libraries or headers in the
# default system locations, i.e. /usr/lib and /usr/include on *NIX platforms.
# The install prefix must therefore be postfixed with the project name.
if(UNIX)
set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/${CMAKE_PROJECT_NAME}")
endif()
set(ENTRYPOINT "real_main"
CACHE STRING "Alternate name of original entrypoint")
set(FREERTOS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/FreeRTOS-Sim"
CACHE STRING "Location of FreeRTOS POSIX Port sources")
set(source_path "${FREERTOS_SOURCE_DIR}/Source")
list(APPEND sources
"${source_path}/croutine.c"
"${source_path}/event_groups.c"
"${source_path}/list.c"
"${source_path}/queue.c"
"${source_path}/tasks.c"
"${source_path}/timers.c"
"${source_path}/portable/MemMang/heap_3.c"
"${source_path}/portable/GCC/POSIX/port.c")
list(APPEND headers
"${source_path}/include/croutine.h"
"${source_path}/include/deprecated_definitions.h"
"${source_path}/include/event_groups.h"
"${source_path}/include/FreeRTOS.h"
"${source_path}/include/list.h"
"${source_path}/include/mpu_prototypes.h"
"${source_path}/include/mpu_wrappers.h"
"${source_path}/include/portable.h"
"${source_path}/include/projdefs.h"
"${source_path}/include/queue.h"
"${source_path}/include/semphr.h"
"${source_path}/include/StackMacros.h"
"${source_path}/include/task.h"
"${source_path}/include/timers.h"
"${source_path}/portable/GCC/POSIX/portmacro.h")
list(APPEND headers
"${CMAKE_CURRENT_SOURCE_DIR}/include/FreeRTOSConfig.h")
add_library(freertos-sim ${sources})
target_compile_definitions(
freertos-sim PUBLIC __GCC_POSIX=1 MAX_NUMBER_OF_TASKS=300)
target_compile_options(
freertos-sim
PUBLIC
-m32
PRIVATE
-W -Wall -Werror -Wmissing-braces -Wno-cast-align -Wparentheses -Wshadow
-Wno-sign-compare -Wswitch -Wuninitialized -Wunknown-pragmas
-Wunused-function -Wunused-label -Wunused-parameter -Wunused-value
-Wunused-variable -Wmissing-prototypes)
target_include_directories(
freertos-sim
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${source_path}/include>"
"$<BUILD_INTERFACE:${source_path}/portable/GCC/POSIX>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
target_link_libraries(
freertos-sim PUBLIC -m32 -pthread)
if(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR
CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
target_compile_options(freertos-sim PUBLIC -ggdb)
target_link_libraries(freertos-sim PUBLIC -ggdb)
endif()
# The FreeRTOS POSIX Port does not require hardware to be initialized (unless
# lwIP is used), but the scheduler must be started before it is safe to execute
# application code. A "loader" is built to avoid modifications to existing
# code. The generated toolchain file will automatically redefine "main" to
# "real_main". The "real_main" function is executed once the scheduler is
# started.
#
# The loader is not part of the freertos-sim target as it has no place in the
# board support package.
add_library(freertos-sim-loader
"${CMAKE_CURRENT_SOURCE_DIR}/src/loader.c")
set_source_files_properties(
"${CMAKE_CURRENT_SOURCE_DIR}/src/loader.c"
PROPERTIES COMPILE_DEFINITIONS real_main=${ENTRYPOINT})
target_link_libraries(freertos-sim-loader freertos-sim)
install(
FILES ${headers}
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file("freertos-sim.cmake.in" "freertos-sim.cmake" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/freertos-sim.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}")
install(
TARGETS freertos-sim freertos-sim-loader
EXPORT "${CMAKE_PROJECT_NAME}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")

View file

@ -0,0 +1,83 @@
# FreeRTOS POSIX Port
FreeRTOS is a supported platform for Eclipse Cyclone DDS. This document
explains how to build and run Eclipse Cyclone DDS on the FreeRTOS POSIX Port.
For basic information, see: [freertos.md](/docs/dev/freertos.md).
As the steps for building and running on the FreeRTOS POSIX Port are largely
the same as building and running on an actual embedded target, this document
should provide an excellent starting point for users. Apart from that, the
simulator can be used to verify commits do not break FreeRTOS compatibility.
> lwIP can also be used in combination with both UNIX and Windows targets, but
> the simulator does not yet have integration. Once integration between both
> is figured out, this document should be updated accordingly.
## Build and install the simulator
The FreeRTOS POSIX Port is not maintained by the FreeRTOS project. Various
projects are maintained across the internet. At the time of writing, the
version maintained by [Shilin][1] seemed the best as the version maintained by
[megakilo][2] was archived.
[1]: https://github.com/shlinym/FreeRTOS-Sim.git
[2]: https://github.com/megakilo/FreeRTOS-Sim
> A [FreeRTOS Linux Port][3] is in the works. Once it becomes stable, please
> update this document accordingly.
[3]: https://sourceforge.net/p/freertos/discussion/382005/thread/f28af711/
1. Clone the repository. The `CMakeLists.txt` in this directory assumes the
sources are available `./FreeRTOS-Sim` by default, but a different location
can be specified using the CMake option `FREERTOS_SOURCE_DIR`.
```
git clone https://github.com/shlinym/FreeRTOS-Sim.git
```
2. Specify an installation prefix and build the simulator like any other
CMake project.
```
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/install ..
cmake --build . --target install
```
> A CMake toolchain file is generated and installed into a `share` directory
> located under CMAKE\_INSTALL\_PREFIX/FreeRTOS-Sim. The compiler that CMake
> discovers and uses to build the simulator is exported in the toolchain file
> and will also be used to build Eclipse Cyclone DDS in the following steps.
## Build Eclipse Cyclone DDS for the simulator
1. Change to the root of the repository and install the dependencies.
```
mkdir build
cd build
conan install -s arch=x86 ..
```
> For actual cross-compilation environments the instructions above will not
> install the correct packages. Even when e.g. Clang instead of GCC was used
> to build the simulator, the mismatch between Conan and CMake will break the
> build. To install the correct packages for the target, specify the required
> settings e.g. when the simulator was built using Clang 7.0, use
> `conan install -s arch=x86 -s compiler=clang -s compiler.version=7.0 ..`.
> If packages are not yet available for the target, as is usually the case
> with actual embedded targets, export the path to the toolchain file in the
> `CONAN_CMAKE_TOOLCHAIN_FILE` environment variable and add the `-b` flag to
> build the packages.
2. Build Eclipse Cyclone DDS.
```
$ cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain/file -DWITH_FREERTOS=on ../src
```
> Examples (and tests) can be executed like usual. The simulator provides a
> *loader* that initializes the hardware (not used on non-embedded targets),
> starts the scheduler and loads the application.

View file

@ -0,0 +1,33 @@
#
# Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
# v. 1.0 which is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
#
# CMake toolchain file generated by @CMAKE_PROJECT_NAME@
#
set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@")
set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
set(include_path "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@")
set(library_path "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@")
set(CMAKE_C_FLAGS "-I${include_path} -Dmain=@ENTRYPOINT@ -m32")
set(CMAKE_EXE_LINKER_FLAGS "-L${library_path}")
set(CMAKE_SHARED_LINKER_FLAGS "-L${library_path}")
set(CMAKE_C_STANDARD_LIBRARIES "-Wl,--start-group,-lfreertos-sim,-lfreertos-sim-loader,--end-group -m32 -lpthread")
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View file

@ -0,0 +1,74 @@
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 64 ) /* This can be made smaller if required. */
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 64 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 0 /* Do not use this option on the PC port. */
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
//#define configMAX_SYSCALL_INTERRUPT_PRIORITY 1
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
/* Software timer related configuration options. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 10 )
#define configGENERATE_RUN_TIME_STATS 1
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. In most cases the linker will remove unused
functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0 /* Do not use this option on the PC port. */
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_pcTaskGetTaskName 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
/* It is a good idea to define configASSERT() while developing. configASSERT()
uses the same semantics as the standard C assert() macro. */
extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName );
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,165 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
/*
* Launcher to run existing programs in the FreeRTOS+lwIP Simulator.
*
* Verification of FreeRTOS+lwIP compatibility in Continuous Integration (CI)
* setups is another intended purpose.
*/
#include <assert.h>
#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if _WIN32
# define EX_OK (0)
# define EX_USAGE (64)
# define LF "\r\n"
#else
# include <sysexits.h>
# define LF "\n"
#endif
#include <FreeRTOS.h>
#include <task.h>
/* Setup system hardware. */
void prvSetupHardware(void)
{
/* No hardware to setup when running in the simulator. */
return;
}
void vAssertCalled(unsigned long ulLine, const char * const pcFileName)
{
taskENTER_CRITICAL();
{
fprintf(stderr, "[ASSERT] %s:%lu"LF, pcFileName, ulLine);
}
taskEXIT_CRITICAL();
abort();
}
void vApplicationMallocFailedHook(void)
{
vAssertCalled(__LINE__, __FILE__);
}
void vApplicationIdleHook(void) { return; }
void vApplicationTickHook( void ) { return; }
static void usage(const char *name)
{
static const char fmt[] =
"Usage: %s LAUNCHER_OPTIONS -- PROGRAM_OPTIONS"LF
"Try '%s -h' for more information"LF;
fprintf(stderr, fmt, name, name);
}
static void help(const char *name)
{
static const char fmt[] =
"Usage: %s LAUNCHER_OPTIONS -- PROGRAM_OPTIONS"LF
""LF
"Launcher options:"LF
" -h Show this help message and exit"LF;
fprintf(stdout, fmt, name);
}
typedef struct {
int argc;
char **argv;
} args_t;
extern int real_main(int argc, char *argv[]);
static void vMainTask(void *ptr)
{
args_t *args = (args_t *)ptr;
/* Reset getopt global variables. */
opterr = 1;
optind = 1;
(void)real_main(args->argc, args->argv);
vPortFree(args->argv);
vPortFree(args);
vTaskDelete(NULL);
_Exit(0);
}
int
main(int argc, char *argv[])
{
int opt;
char *name;
args_t *args = NULL;
/* Determine program name. */
assert(argc >= 0 && argv[0] != NULL);
name = strrchr(argv[0], '/');
if (name != NULL) {
name++;
} else {
name = argv[0];
}
if ((args = pvPortMalloc(sizeof(*args))) == NULL) {
return EX_OSERR;
}
memset(args, 0, sizeof(*args));
/* Parse command line options. */
while ((opt = getopt(argc, argv, ":a:dg:hn:")) != -1) {
switch (opt) {
case 'h':
help(name);
exit(EX_OK);
case '?':
fprintf(stderr, "Unknown option '%c'"LF, opt);
usage(name);
exit(EX_USAGE);
case ':':
/* fall through */
default:
fprintf(stderr, "Option '%c' requires an argument"LF, opt);
usage(name);
exit(EX_USAGE);
}
}
/* Copy leftover arguments into a new array. */
args->argc = (argc - optind) + 1;
args->argv = pvPortMalloc((args->argc + 1) * sizeof(*args->argv));
if (args->argv == NULL) {
return EX_OSERR;
}
args->argv[0] = argv[0];
for (int i = optind, j = 1; i < argc; i++, j++) {
args->argv[j] = argv[i];
}
prvSetupHardware();
xTaskCreate(vMainTask, name,
configMINIMAL_STACK_SIZE, args, (tskIDLE_PRIORITY + 1UL),
(xTaskHandle *) NULL);
vTaskStartScheduler();
return EX_SOFTWARE;
}