Skip to content

Commit 9af72db

Browse files
kilograhampaulbartellaggarg
authored
Add RP2040 support (#341)
* Add RP2040 support * remove spurious tab/spaces comments * add .cmake to ignored kernel checks * Apply suggestions from code review Co-authored-by: Paul Bartell <[email protected]> * license and end of file newline fixes * Rename LICENSE.TXT to LICENSE.md Co-authored-by: Paul Bartell <[email protected]> Co-authored-by: Gaurav-Aggarwal-AWS <[email protected]>
1 parent 4200226 commit 9af72db

14 files changed

+1517
-3
lines changed

.github/scripts/kernel_checker.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
'.png',
6161
'.bat',
6262
'.sh',
63-
'.txt'
63+
'.txt',
64+
'.cmake'
6465
]
6566

6667
KERNEL_ASM_EXTENSIONS = [

include/stack_macros.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,21 @@
4545

4646
/*-----------------------------------------------------------*/
4747

48+
/*
49+
* portSTACK_LIMIT_PADDING is a number of extra words to consider to be in
50+
* use on the stack.
51+
*/
52+
#ifndef portSTACK_LIMIT_PADDING
53+
#define portSTACK_LIMIT_PADDING 0
54+
#endif
55+
4856
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
4957

5058
/* Only the current stack state is to be checked. */
5159
#define taskCHECK_FOR_STACK_OVERFLOW() \
5260
{ \
5361
/* Is the currently saved stack pointer within the stack limit? */ \
54-
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
62+
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING) \
5563
{ \
5664
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
5765
} \
@@ -67,7 +75,7 @@
6775
{ \
6876
\
6977
/* Is the currently saved stack pointer within the stack limit? */ \
70-
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
78+
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING) \
7179
{ \
7280
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
7381
} \
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
**/cmake-*
2+
.idea
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
3+
if (NOT TARGET _FreeRTOS_kernel_inclusion_marker)
4+
add_library(_FreeRTOS_kernel_inclusion_marker INTERFACE)
5+
6+
# Pull in PICO SDK (must be before project)
7+
include(pico_sdk_import.cmake)
8+
if (PICO_SDK_VERSION_STRING VERSION_LESS "1.2.0")
9+
message(FATAL_ERROR "Require at least Raspberry Pi Pico SDK version 1.2.0")
10+
endif()
11+
12+
if (NOT FREERTOS_KERNEL_PATH)
13+
get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../.. REALPATH)
14+
endif ()
15+
16+
message(DEBUG "FREERTOS_KERNEL_PATH is ${FREERTOS_KERNEL_PATH}")
17+
project(FreeRTOS-Kernel C CXX)
18+
19+
set(CMAKE_C_STANDARD 11)
20+
set(CMAKE_CXX_STANDARD 17)
21+
22+
pico_is_top_level_project(FREERTOS_KERNEL_TOP_LEVEL_PROJECT)
23+
24+
# The real work gets done in library.cmake which is called at the end of pico_sdk_init
25+
list(APPEND PICO_SDK_POST_LIST_FILES ${CMAKE_CURRENT_LIST_DIR}/library.cmake)
26+
27+
# We need to inject the following header file into ALL SDK files (which we do via the config header)
28+
list(APPEND PICO_CONFIG_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/include/freertos_sdk_config.h)
29+
30+
if (FREERTOS_KERNEL_TOP_LEVEL_PROJECT)
31+
message("FreeRTOS: initialize SDK since we're the top-level")
32+
# Initialize the SDK
33+
pico_sdk_init()
34+
else()
35+
set(PICO_SDK_POST_LIST_FILES ${PICO_SDK_POST_LIST_FILES} PARENT_SCOPE)
36+
set(PICO_CONFIG_HEADER_FILES ${PICO_CONFIG_HEADER_FILES} PARENT_SCOPE)
37+
set(FREERTOS_KERNEL_PATH ${FREERTOS_KERNEL_PATH} PARENT_SCOPE)
38+
endif()
39+
endif()
40+
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# This is a copy of <FREERTOS_KERNEL_PATH>/portable/ThirdParty/GCC/RP2040/FREERTOS_KERNEL_import.cmake
2+
3+
# This can be dropped into an external project to help locate the FreeRTOS kernel
4+
# It should be include()ed prior to project(). Alternatively this file may
5+
# or the CMakeLists.txt in this directory may be included or added via add_subdirectory
6+
# respectively.
7+
8+
if (DEFINED ENV{FREERTOS_KERNEL_PATH} AND (NOT FREERTOS_KERNEL_PATH))
9+
set(FREERTOS_KERNEL_PATH $ENV{FREERTOS_KERNEL_PATH})
10+
message("Using FREERTOS_KERNEL_PATH from environment ('${FREERTOS_KERNEL_PATH}')")
11+
endif ()
12+
13+
set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC/RP2040")
14+
# undo the above
15+
set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..")
16+
17+
if (NOT FREERTOS_KERNEL_PATH)
18+
# check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly)
19+
get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH)
20+
get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH)
21+
if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH)
22+
get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH)
23+
endif()
24+
if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH)
25+
get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH)
26+
message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake")
27+
elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel")
28+
set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel)
29+
message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}")
30+
endif()
31+
endif ()
32+
33+
if (NOT FREERTOS_KERNEL_PATH)
34+
foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source)
35+
# check if FreeRTOS-Kernel exists under directory that included us
36+
set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}})
37+
set(SEARCH_ROOT ../../../..)
38+
get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH)
39+
if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt)
40+
get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH)
41+
message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project")
42+
break()
43+
endif()
44+
endforeach()
45+
endif()
46+
47+
if (NOT FREERTOS_KERNEL_PATH)
48+
message(FATAL_ERROR "FreeRTOS location was not specified. Please set FREERTOS_KERNEL_PATH.")
49+
endif()
50+
51+
set(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" CACHE PATH "Path to the FreeRTOS Kernel")
52+
53+
get_filename_component(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
54+
if (NOT EXISTS ${FREERTOS_KERNEL_PATH})
55+
message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' not found")
56+
endif()
57+
if (NOT EXISTS ${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt)
58+
message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain an RP2040 port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}")
59+
endif()
60+
set(FREERTOS_KERNEL_PATH ${FREERTOS_KERNEL_PATH} CACHE PATH "Path to the FreeRTOS_KERNEL" FORCE)
61+
62+
add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
BSD-3-Clause License
2+
3+
Copyright (c) 2020-2021 Raspberry Pi (Trading) Ltd.
4+
5+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
6+
following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
9+
disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
12+
disclaimer in the documentation and/or other materials provided with the distribution.
13+
14+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
15+
derived from this software without specific prior written permission.
16+
17+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## Overview
2+
3+
This directory provides a FreeRTOS-Kernel port that can be used with the Raspberry Pi Pico SDK. It supports:
4+
5+
* Simple CMake INTERFACE libraries, to provide the FreeRTOS-Kernel and also the individual allocator types, without copying code into the user's project.
6+
* Running the FreeRTOS-Kernel and tasks on either core 0 or core 1
7+
* Use of SDK synchronization primitives (such as mutexes, semaphores, queues from pico_sync) between FreeRTOS tasks and code executing on the other core, or in IRQ handlers.
8+
9+
Note that a FreeRTOS SMP version of this port is also available in the FreeRTOS-Kernel smp branch, which additionally supports utilizing both RP2040 CPU cores for FreeRTOS tasks simultaneously.
10+
11+
## Using this port
12+
13+
Copy [FreeRTOS-Kernel-import.cmake](FreeRTOS-Kernel-import.cmake) into your project, and
14+
add:
15+
16+
```cmake
17+
import(FreeRTOS_Kernel_import.cmake)
18+
```
19+
20+
below the usual import of `pico_sdk_import.cmake`
21+
22+
This will find the FreeRTOS kernel if it is a direct sub-module of your project, or if you provide the `FREERTOS_KERNEL_PATH` variable in your environment or via `-DFREERTOS_KERNEL_PATH=/path/to/FreeRTOS-Kernel` on the CMake command line.
23+
24+
## Advanced Configuration
25+
26+
Some additional `config` options are defined [here](include/rp2040_config.h) which control some low level implementation details.
27+
28+
## Known Limitations
29+
30+
- Tickless idle has not currently been tested, and is likely non-functional
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
3+
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
5+
*
6+
* SPDX-License-Identifier: MIT AND BSD-3-Clause
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
9+
* this software and associated documentation files (the "Software"), to deal in
10+
* the Software without restriction, including without limitation the rights to
11+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12+
* the Software, and to permit persons to whom the Software is furnished to do so,
13+
* subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all
16+
* copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
*
25+
* https://www.FreeRTOS.org
26+
* https://github.com/FreeRTOS
27+
*/
28+
29+
#include "FreeRTOS.h"
30+
31+
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
32+
StackType_t **ppxIdleTaskStackBuffer,
33+
uint32_t *pulIdleTaskStackSize )
34+
{
35+
/* If the buffers to be provided to the Idle task are declared inside this
36+
function then they must be declared static - otherwise they will be allocated on
37+
the stack and so not exists after this function exits. */
38+
static StaticTask_t xIdleTaskTCB;
39+
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
40+
41+
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
42+
state will be stored. */
43+
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
44+
45+
/* Pass out the array that will be used as the Idle task's stack. */
46+
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
47+
48+
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
49+
Note that, as the array is necessarily of type StackType_t,
50+
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
51+
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
52+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* FreeRTOS Kernel V10.4.3
3+
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
5+
*
6+
* SPDX-License-Identifier: BSD-3-Clause
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
9+
* this software and associated documentation files (the "Software"), to deal in
10+
* the Software without restriction, including without limitation the rights to
11+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12+
* the Software, and to permit persons to whom the Software is furnished to do so,
13+
* subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all
16+
* copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
*
25+
* https://www.FreeRTOS.org
26+
* https://github.com/FreeRTOS
27+
*/
28+
29+
#ifndef FREERTOS_SDK_CONFIG_H
30+
#define FREERTOS_SDK_CONFIG_H
31+
32+
#ifndef __ASSEMBLER__
33+
#include "FreeRTOSConfig.h"
34+
#include "rp2040_config.h"
35+
36+
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 )
37+
// increase the amount of time it may reasonably take to wake us up
38+
#ifndef PICO_TIME_SLEEP_OVERHEAD_ADJUST_US
39+
#define PICO_TIME_SLEEP_OVERHEAD_ADJUST_US 150
40+
#endif
41+
42+
#define lock_owner_id_t uint32_t
43+
extern uint32_t ulPortLockGetCurrentOwnerId(void);
44+
#define lock_get_caller_owner_id() ulPortLockGetCurrentOwnerId()
45+
#define LOCK_INVALID_OWNER_ID ((uint32_t)-1)
46+
47+
struct lock_core;
48+
#ifndef lock_internal_spin_unlock_with_wait
49+
extern void vPortLockInternalSpinUnlockWithWait( struct lock_core *pxLock, uint32_t ulSave);
50+
#define lock_internal_spin_unlock_with_wait(lock, save) vPortLockInternalSpinUnlockWithWait(lock, save)
51+
#endif
52+
53+
#ifndef lock_internal_spin_unlock_with_notify
54+
extern void vPortLockInternalSpinUnlockWithNotify( struct lock_core *pxLock, uint32_t save);
55+
#define lock_internal_spin_unlock_with_notify(lock, save) vPortLockInternalSpinUnlockWithNotify(lock, save);
56+
#endif
57+
58+
#ifndef lock_internal_spin_unlock_with_best_effort_wait_or_timeout
59+
extern bool xPortLockInternalSpinUnlockWithBestEffortWaitOrTimeout( struct lock_core *pxLock, uint32_t ulSave, absolute_time_t uxUntil);
60+
#define lock_internal_spin_unlock_with_best_effort_wait_or_timeout(lock, save, until) \
61+
xPortLockInternalSpinUnlockWithBestEffortWaitOrTimeout(lock, save, until)
62+
#endif
63+
#endif /* configSUPPORT_PICO_SYNC_INTEROP */
64+
65+
#if ( configSUPPORT_PICO_TIME_INTEROP == 1 )
66+
extern void xPortSyncInternalYieldUntilBefore(absolute_time_t t);
67+
#define sync_internal_yield_until_before(t) xPortSyncInternalYieldUntilBefore(t)
68+
#endif /* configSUPPORT_PICO_TIME_INTEROP */
69+
#endif /* __ASSEMBLER__ */
70+
#endif

0 commit comments

Comments
 (0)