Skip to content

Commit f8b5099

Browse files
committed
Initial commit
0 parents  commit f8b5099

14 files changed

+687
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build/
2+
.vscode/

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "deps/pico_freertos_shell"]
2+
path = deps/pico_freertos_shell
3+
url = https://github.com/JZimnol/pico_freertos_shell

CMakeLists.txt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Copyright (c) 2025 Jakub Zimnol
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
#
21+
22+
cmake_minimum_required(VERSION 3.13)
23+
24+
# Change the board if needed
25+
set(PICO_BOARD pico_w)
26+
27+
set(PICO_SDK_PATH "${CMAKE_CURRENT_LIST_DIR}/../pico-sdk"
28+
CACHE PATH "Path to the Raspberry Pi Pico SDK")
29+
set(FREERTOS_KERNEL_PATH "${CMAKE_CURRENT_LIST_DIR}/../FreeRTOS-Kernel"
30+
CACHE PATH "Path to the FreeRTOS kernel sources")
31+
set(PICO_FREERTOS_SHELL_PATH "${CMAKE_CURRENT_LIST_DIR}/deps/pico_freertos_shell"
32+
CACHE PATH "Path to the pico_freertos_shell root directory")
33+
34+
# important - include these files before calling project() and pico_sdk_init()
35+
include(pico_sdk_import.cmake)
36+
include(FreeRTOS_Kernel_import.cmake)
37+
include(${PICO_FREERTOS_SHELL_PATH}/pico_freertos_shell_import.cmake)
38+
39+
project(example_app)
40+
pico_sdk_init()
41+
42+
file(GLOB FREERTOS_SOURCES ${FREERTOS_KERNEL_PATH}/*.c)
43+
44+
add_library(FreeRTOS
45+
${FREERTOS_SOURCES}
46+
${FREERTOS_KERNEL_PATH}/portable/ThirdParty/GCC/RP2040/port.c
47+
${CMAKE_CURRENT_LIST_DIR}/port/freertos.c)
48+
target_include_directories(FreeRTOS PUBLIC
49+
${FREERTOS_KERNEL_PATH}/include
50+
${FREERTOS_KERNEL_PATH}/portable/ThirdParty/GCC/RP2040/include
51+
${CMAKE_CURRENT_LIST_DIR}/port)
52+
target_link_libraries(FreeRTOS
53+
FreeRTOS-Kernel-Heap4
54+
hardware_clocks)
55+
56+
# important - add this subdirectory before creating the main targets
57+
add_subdirectory(${PICO_FREERTOS_SHELL_PATH})
58+
add_subdirectory(example_app)

FreeRTOS_Kernel_import.cmake

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)

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Jakub Zimnol
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Raspberry Pi Pico FreeRTOS Shell Example Application
2+
3+
This repository showcases an example usage of
4+
[pico_freertos_shell](https://github.com/JZimnol/pico_freertos_shell) - a
5+
FreeRTOS module that allows you to add an interactive shell with custom commands
6+
to your application.
7+
8+
## Compiling the application
9+
10+
**NOTE:** This example assumes that this repository is in the same folder as
11+
[FreeRTOS-Kernel](https://github.com/FreeRTOS/FreeRTOS-Kernel.git) and
12+
[pico-sdk](https://github.com/raspberrypi/pico-sdk.git). If not, change the
13+
`PICO_SDK_PATH` and `FREERTOS_KERNEL_PATH` variables in the `CMakeLists.txt`
14+
file accordingly.
15+
16+
**NOTE:** This example targets the `pico_w` board but can also be built for the
17+
`pico` board.
18+
19+
To compile the application, run the following commands:
20+
21+
```shell
22+
# these commands may vary depending on the OS
23+
mkdir build/
24+
cd build
25+
cmake .. && make -j
26+
```
27+
28+
**NOTE:** please refer to the pico_freertos_shell's main
29+
[CMakeLists.txt](https://github.com/JZimnol/pico_freertos_shell/blob/master/CMakeLists.txt)
30+
file for a list of available compile time CMake options.
31+
32+
## Running the application
33+
34+
Flash the board using generated binary file. Open your serial terminal (e.g.
35+
minicom, picocom, putty) and a shell prompt should appear. Type `help` or
36+
`helptree` for a list of available commads. Try some example commands:
37+
- `helloworld arg1 "arg with a space"`
38+
- `helptree variable`
39+
- `variable read`
40+
- `variable set 123`
41+
- `reboot 1000`

deps/pico_freertos_shell

Submodule pico_freertos_shell added at a98f3b3

example_app/CMakeLists.txt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright (c) 2025 Jakub Zimnol
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
#
21+
22+
cmake_minimum_required(VERSION 3.13)
23+
24+
add_executable(example_app
25+
main.c
26+
commands.c)
27+
target_link_libraries(example_app PUBLIC
28+
pico_stdlib
29+
FreeRTOS
30+
hardware_watchdog
31+
pico_freertos_shell_lib)
32+
33+
pico_freertos_shell_link_freertos(FreeRTOS)
34+
35+
# use suitable stdio
36+
pico_enable_stdio_usb(example_app 0)
37+
pico_enable_stdio_uart(example_app 1)
38+
39+
pico_add_extra_outputs(example_app)

example_app/commands.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright (c) 2025 Jakub Zimnol
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
#include <hardware/watchdog.h>
24+
#include <pico/stdlib.h>
25+
26+
#include <stdio.h>
27+
#include <stdlib.h>
28+
29+
#include <FreeRTOS.h>
30+
#include <task.h>
31+
32+
#include <pico_freertos_shell/commands.h>
33+
34+
#include "common.h"
35+
36+
static int m_some_variable;
37+
38+
static void variable_set_cmd_handler(int argc, char **argv) {
39+
if (argc != 1) {
40+
LOG(variable_set, CMD_HANDLER, "Invalid number of arguments\n");
41+
return;
42+
}
43+
44+
m_some_variable = atoi(argv[0]);
45+
LOG(variable_set, CMD_HANDLER, "Set variable to %d\n", m_some_variable);
46+
}
47+
48+
static void variable_read_cmd_handler(int argc, char **argv) {
49+
if (argc != 0) {
50+
LOG(variable_read, CMD_HANDLER, "Invalid number of arguments\n");
51+
return;
52+
}
53+
54+
LOG(variable_get, CMD_HANDLER, "Variable is %d\n", m_some_variable);
55+
}
56+
57+
static void helloworld_cmd_handler(int argc, char **argv) {
58+
LOG(helloworld, CMD_HANDLER, "Hello World!\n");
59+
if (argc > 0) {
60+
LOG(helloworld, CMD_HANDLER, "My arguments:\n");
61+
for (size_t i = 0; i < argc; i++) {
62+
LOG(helloworld, CMD_HANDLER, "argv[%d] = %s\n", i, argv[i]);
63+
}
64+
}
65+
}
66+
67+
static void reboot_cmd_handler(int argc, char **argv) {
68+
if (argc != 1) {
69+
LOG(reboot, CMD_HANDLER, "Invalid number of arguments\n");
70+
return;
71+
}
72+
73+
int delay_ms = atoi(argv[0]);
74+
if (delay_ms < 0) {
75+
LOG(reboot, CMD_HANDLER, "Invalid delay: %d\n", delay_ms);
76+
return;
77+
}
78+
79+
LOG(reboot, CMD_HANDLER, "Rebooting in %d milliseconds\n", delay_ms);
80+
vTaskDelay(delay_ms / portTICK_PERIOD_MS);
81+
watchdog_enable(1, 1);
82+
while (1)
83+
;
84+
}
85+
86+
static const pfs_command_t VARIABLE_SUBCOMMANDS[] = {
87+
PFS_COMMAND_INITIALIZER(set,
88+
"set the variable to a value",
89+
PFS_COMMAND_HANDLER(variable_set_cmd_handler)),
90+
PFS_COMMAND_INITIALIZER(read,
91+
"read the value of the variable",
92+
PFS_COMMAND_HANDLER(variable_read_cmd_handler)),
93+
};
94+
95+
static const pfs_command_t SHELL_COMMANDS[] = {
96+
PFS_COMMAND_INITIALIZER(
97+
variable,
98+
"set or read a variable",
99+
PFS_SUBCOMMANDS(VARIABLE_SUBCOMMANDS,
100+
ARRAY_SIZE(VARIABLE_SUBCOMMANDS))),
101+
PFS_COMMAND_INITIALIZER(helloworld,
102+
"prints 'Hello World!' and a list of arguments",
103+
PFS_COMMAND_HANDLER(helloworld_cmd_handler)),
104+
PFS_COMMAND_INITIALIZER(reboot,
105+
"reboot the device after a delay",
106+
PFS_COMMAND_HANDLER(reboot_cmd_handler)),
107+
};
108+
109+
int example_app_register_commands(void) {
110+
return pfs_commands_register(SHELL_COMMANDS, ARRAY_SIZE(SHELL_COMMANDS));
111+
}

example_app/common.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2025 Jakub Zimnol
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
#pragma once
24+
25+
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
26+
27+
#define _STRINGIFY(ToStr) #ToStr
28+
#define STRINGIFY(ToStr) _STRINGIFY(ToStr)
29+
30+
#define LOG(Module, Level, ...) \
31+
printf(STRINGIFY(Level) " [" STRINGIFY(Module) "] " __VA_ARGS__);
32+
33+
int example_app_register_commands(void);

0 commit comments

Comments
 (0)