fix freertos kernel compatibility

This commit is contained in:
rmanach 2025-02-21 10:37:40 +01:00
parent 02e1de09ff
commit b27b45fb9a
6 changed files with 315 additions and 228 deletions

4
.gitignore vendored
View File

@ -2,7 +2,9 @@
picotool
sdk
freertos
freertos*
build
toolchain
*.orig

View File

@ -4,7 +4,7 @@ SDK_VERSION := 2.1.0
PICOTOOL := $(INSTALL_PATH)/picotool/$(SDK_VERSION)/build/picotool
export PICO_SDK_PATH=$(INSTALL_PATH)/sdk/$(SDK_VERSION)
# if using a different platform or arch, set ot here
# if using a different platform or arch, set it here
export PICO_PLATFORM=rp2350
# project name, need to be passed as make input (ex: make project name=test)
@ -13,6 +13,7 @@ name := ""
install:
@./scripts/install_sdk.bash $(SDK_VERSION)
@./scripts/install_picotool.bash $(SDK_VERSION)
@./scripts/install_freertos.bash
info:
@$(PICOTOOL) info -a
@ -20,7 +21,22 @@ info:
project:
@./scripts/scaffold_project.bash $(name) $(SDK_VERSION)
compile:
.check-name:
ifeq ($(strip $(name)), "")
@echo "error: project name must be set, ex: name=<project_name>"
@false
endif
ifeq ($(shell test -d $(name) && echo "ok"),)
@echo "error: project $(name) does not exist"
@false
endif
format: .check-name
@test -f "$(shell find /usr/bin/ -name astyle)" && astyle --style=java --indent=spaces=4 -K -xC120 $(name)/*.c
compile: format
rm -f ${name}/build/CMakeCache.txt
@(test -d ${name} && mkdir -p ${name}/build && cd ${name}/build && cmake .. && make -j$(nproc) && echo "project compile successfully") || echo "error: unable to compile project: $(name)"
push: compile

View File

@ -13,92 +13,88 @@
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ((unsigned long)150000000) // RP2350 default clock is 150 MHz
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES 5
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 256 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITIES 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
// Scheduler Configuration
#define configUSE_PREEMPTION 1 // 1: Preemptive scheduler, 0: Cooperative scheduler
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 // Use optimized task selection if available
#define configUSE_IDLE_HOOK 0 // 1: Use Idle hook function
#define configUSE_TICK_HOOK 0 // 1: Use Tick hook function
#define configIDLE_SHOULD_YIELD 1 // 1: Idle task yields to same priority tasks
#define configSUPPORT_DYNAMIC_ALLOCATION 1
// System Clock Configuration
#define configCPU_CLOCK_HZ ((unsigned long)150000000) // CPU frequency: 150 MHz for RP2350
#define configTICK_RATE_HZ ((TickType_t)1000) // RTOS tick frequency (1000 Hz = 1ms tick)
#define configENABLE_FPU 0
#define configENABLE_TRUSTZONE 0
// Task Configuration
#define configMAX_PRIORITIES 5 // Maximum number of priority levels
#define configMINIMAL_STACK_SIZE ((unsigned short)256) // Minimum stack size in words
#define configMAX_TASK_NAME_LEN (16) // Maximum length of task names
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
// Memory Configuration
#define configTOTAL_HEAP_SIZE ((size_t)(16 * 1024)) // Total RTOS heap size (16 KB)
#define configSUPPORT_DYNAMIC_ALLOCATION 1 // 1: Enable dynamic memory allocation
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
// Synchronization Primitives
#define configUSE_MUTEXES 1 // 1: Enable mutexes
#define configUSE_RECURSIVE_MUTEXES 1 // 1: Enable recursive mutexes
#define configUSE_COUNTING_SEMAPHORES 1 // 1: Enable counting semaphores
#define configQUEUE_REGISTRY_SIZE 8 // Number of queues/semaphores that can be registered
#define configENABLE_MPU 0
// Debugging and Diagnostics
#define configUSE_TRACE_FACILITIES 0 // 1: Enable trace/debug facilities
#define configCHECK_FOR_STACK_OVERFLOW 2 // Stack overflow checking method (0=off, 1=method1, 2=method2)
#define configUSE_MALLOC_FAILED_HOOK 0 // 1: Use memory allocation failure hook
#define configUSE_APPLICATION_TASK_TAG 0 // 1: Enable task tagging
#define configGENERATE_RUN_TIME_STATS 0 // 1: Generate run-time statistics
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xSemaphoreGetMutexHolder 0
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xQueueGetMutexHolder 0
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 1
// Timer Configuration
#define configUSE_TIMERS 1 // 1: Enable software timers
#define configTIMER_TASK_PRIORITY (2) // Timer service task priority
#define configTIMER_QUEUE_LENGTH 10 // Timer command queue length
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) // Timer task stack size
/* Cortex-M specific definitions. */
// Co-routine Configuration
#define configUSE_CO_ROUTINES 0 // 1: Enable co-routines
#define configMAX_CO_ROUTINE_PRIORITIES (2) // Maximum co-routine priorities
// Hardware Specific Configuration
#define configENABLE_FPU 1 // 1: Enable Floating Point Unit
#define configENABLE_TRUSTZONE 0 // 1: Enable TrustZone
#define configENABLE_MPU 0 // 1: Enable Memory Protection Unit (defined twice in original)
#define configRUN_FREERTOS_SECURE_ONLY 1 // 1: Run in secure mode only
#define configUSE_16_BIT_TICKS 0 // 0: Use 32-bit ticks, 1: Use 16-bit ticks
// API Inclusion Configuration
#define INCLUDE_vTaskPrioritySet 1 // Include task priority set API
#define INCLUDE_uxTaskPriorityGet 1 // Include task priority get API
#define INCLUDE_vTaskDelete 1 // Include task delete API
#define INCLUDE_vTaskCleanUpResources 0 // Include task cleanup API
#define INCLUDE_vTaskSuspend 1 // Include task suspend API
#define INCLUDE_vTaskDelayUntil 1 // Include delay until API
#define INCLUDE_vTaskDelay 1 // Include delay API
#define INCLUDE_xTaskGetSchedulerState 1 // Include scheduler state API
#define INCLUDE_xTaskGetCurrentTaskHandle 1 // Include current task handle API
#define INCLUDE_uxTaskGetStackHighWaterMark 0 // Include stack high water mark API
#define INCLUDE_xTaskGetIdleTaskHandle 0 // Include idle task handle API
#define INCLUDE_eTaskGetState 0 // Include task state API
#define INCLUDE_xSemaphoreGetMutexHolder 0 // Include mutex holder API
#define INCLUDE_xTimerPendFunctionCall 1 // Include timer pend function call API (defined twice in original)
#define INCLUDE_xQueueGetMutexHolder 0 // Include queue mutex holder API
#define INCLUDE_xEventGroupSetBitFromISR 1 // Include event group set bit from ISR API
// Cortex-M Interrupt Configuration
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS // Use CMSIS defined priority bits
#else
#define configPRIO_BITS 3 /* 7 priority levels */
#define configPRIO_BITS 3 // 7 priority levels (default)
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x7
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x7 // Lowest interrupt priority
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 // Highest priority for FreeRTOS API calls
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
// Assertion Definition
#define configASSERT(x) if((x) == 0) { taskDISABLE_INTERRUPTS(); for(;;); } // Basic assert implementation
#endif /* FREERTOS_CONFIG_H */

28
scripts/install_freertos.bash Executable file
View File

@ -0,0 +1,28 @@
#!/bin/bash
######################################################
#
# Install FreeRTOS Raspberry Pi Kernel.
# src: https://github.com/raspberrypi/FreeRTOS-Kernel
#
# ex: ./install_freertos.bash
#
######################################################
if [[ -z ${INSTALL_PATH} ]]
then
INSTALL_PATH=${PWD}
fi
if [[ ! -d ${INSTALL_PATH}/freertos ]]
then
echo "installing freertos..."
git clone https://github.com/raspberrypi/FreeRTOS-Kernel ${INSTALL_PATH}/freertos
if [[ $? != 0 ]]
then
echo "error: unable to clone freertos"
exit 1
fi
fi
echo "freertos installation completed"

View File

@ -12,9 +12,11 @@ project(simple_led C CXX ASM)
pico_sdk_init()
set(FREERTOS_SRC_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../freertos/FreeRTOSv202411.00/FreeRTOS/Source)
set(FREERTOS_SRC_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../freertos)
set(FREERTOS_CONFIG_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../config)
include(${FREERTOS_SRC_DIRECTORY}/portable/ThirdParty/GCC/RP2350_ARM_NTZ/FreeRTOS_Kernel_import.cmake)
# add_library(FreeRTOS STATIC
# ${FREERTOS_SRC_DIRECTORY}/event_groups.c
# ${FREERTOS_SRC_DIRECTORY}/list.c
@ -31,7 +33,7 @@ set(FREERTOS_CONFIG_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../config)
include_directories(
${FREERTOS_CONFIG_DIRECTORY}
${FREERTOS_SRC_DIRECTORY}/include
${FREERTOS_SRC_DIRECTORY}/portable/GCC/ARM_CM33_NTZ/non_secure
${FREERTOS_SRC_DIRECTORY}/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure
)
set(FREERTOS_SOURCES
@ -45,8 +47,9 @@ set(FREERTOS_SOURCES
)
set(FREERTOS_PORT_FILES
${FREERTOS_SRC_DIRECTORY}/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
${FREERTOS_SRC_DIRECTORY}/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c
${FREERTOS_SRC_DIRECTORY}/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure/port.c
${FREERTOS_SRC_DIRECTORY}/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure/portasm.c
${FREERTOS_SRC_DIRECTORY}/portable/ThirdParty/GCC/RP2350_ARM_NTZ/non_secure/mpu_wrappers_v2_asm.c
)
add_executable(simple_led main.c ${FREERTOS_SOURCES} ${FREERTOS_PORT_FILES})
@ -57,10 +60,11 @@ pico_set_program_version(simple_led "0.1")
target_link_libraries(
simple_led
pico_stdlib
hardware_exception
# FreeRTOS
)
pico_enable_stdio_uart(simple_led 0)
pico_enable_stdio_uart(simple_led 1)
pico_enable_stdio_usb(simple_led 1)
pico_add_extra_outputs(simple_led)

View File

@ -1,92 +1,55 @@
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include "pico/stdlib.h"
#include <FreeRTOS.h>
#include <pico/printf.h>
#include <pico/stdlib.h>
#include <pico/time.h>
#include <semphr.h>
#include <task.h>
#include <queue.h>
#ifndef LED_DELAY_MS
#define LED_DELAY_MS 500
#endif
#define GPIO_15 15
#define GPIO_13 13
void blink_success(bool in_task) {
gpio_put(PICO_DEFAULT_LED_PIN, true);
if (in_task)
vTaskDelay(pdMS_TO_TICKS(500));
else
sleep_ms(500);
gpio_put(PICO_DEFAULT_LED_PIN, false);
}
void blink_failed(bool in_task) {
for (;;) {
gpio_put(PICO_DEFAULT_LED_PIN, true);
if (in_task)
vTaskDelay(pdMS_TO_TICKS(500));
else
sleep_ms(500);
gpio_put(PICO_DEFAULT_LED_PIN, false);
if (in_task)
vTaskDelay(pdMS_TO_TICKS(500));
else
sleep_ms(500);
}
}
void blink_default_led(void) {
#ifdef PICO_DEFAULT_LED_PIN
while (true) {
gpio_put(PICO_DEFAULT_LED_PIN, true);
// sleep_ms(LED_DELAY_MS);
vTaskDelay(LED_DELAY_MS / portTICK_PERIOD_MS);
gpio_put(PICO_DEFAULT_LED_PIN, false);
// sleep_ms(1000);
vTaskDelay(LED_DELAY_MS / portTICK_PERIOD_MS);
}
#endif
}
void run_health() {
BaseType_t res = xTaskCreate(
blink_default_led,
"healthcheck",
configMINIMAL_STACK_SIZE,
NULL,
configMAX_PRIORITIES - 1U,
NULL
);
if (res != pdPASS) {
printf("error: unable to launch healthcheck task, code error: %d\n", res);
}
return;
}
enum status { STOP, RUNNING, FAILED, UNKNOWN };
/**
* Handle the application state.
*/
typedef struct state state;
struct state {
SemaphoreHandle_t lock;
int counter;
int bs;
bool can_incr;
clock_t push_clock;
absolute_time_t push_clock;
bool on_reset;
bool is_reset;
int status;
};
static state global_state = (state) {
/**
* Parameters available to be passed in task function.
*/
typedef struct params params;
struct params {
uint gpio;
uint32_t delays_ms;
bool in_task;
state *s;
};
static state global_state = {
.counter = 0,
.can_incr = true,
.on_reset = false,
.is_reset = false,
.status = RUNNING,
};
void init_state(state *s) {
s->lock = xSemaphoreCreateMutex();
}
void incr_counter(state *s) {
if (s != NULL) {
if (s->can_incr) {
@ -112,15 +75,37 @@ void set_push_clock(state *s) {
if (s != NULL) {
if (s->push_clock)
return;
s->push_clock = clock();
s->push_clock = get_absolute_time();
}
}
void set_status(state *s, int status) {
if (s != NULL) {
if (xSemaphoreTake(s->lock, (TickType_t)10) == pdTRUE) {
s->status = status;
xSemaphoreGive(s->lock);
return;
}
blink_failed(PICO_DEFAULT_LED_PIN, 200, false);
}
}
int get_status(state *s) {
if (s != NULL) {
if (xSemaphoreTake(s->lock, (TickType_t)10) == pdTRUE) {
int res = s->status;
xSemaphoreGive(s->lock);
return res;
}
blink_failed(PICO_DEFAULT_LED_PIN, 200, false);
}
}
bool is_resetting(state *s) {
if (s != NULL) {
clock_t c = clock();
double exec_time = (double)(c - s->push_clock) / CLOCKS_PER_SEC;
if (exec_time >= 2)
absolute_time_t end = get_absolute_time();
uint64_t elapsed_ms = absolute_time_diff_us(s->push_clock, end) / 1000;
if (elapsed_ms >= 2000)
return true;
}
return false;
@ -132,76 +117,133 @@ void reset(state *s) {
s->is_reset = true;
}
void led_control() {
while (1) {
// return low level when the button is pressed
if (!gpio_get(GPIO_13)) {
// sleep_ms(20); // avoid "bounce" phenomenon (buffeting)
vTaskDelay(20 / portTICK_PERIOD_MS);
if (!gpio_get(GPIO_13)) {
if (global_state.is_reset)
continue;
void blink_success(uint gpio, uint32_t delay_ms, bool in_task) {
gpio_put(gpio, true);
if (in_task)
vTaskDelay(pdMS_TO_TICKS(delay_ms));
else
sleep_ms(delay_ms);
gpio_put(gpio, false);
}
set_push_clock(&global_state);
if (is_resetting(&global_state)) {
gpio_put(GPIO_15, true);
// sleep_ms(500);
vTaskDelay(500 / portTICK_PERIOD_MS);
gpio_put(GPIO_15, false);
// sleep_ms(500);
vTaskDelay(500 / portTICK_PERIOD_MS);
gpio_put(GPIO_15, true);
// sleep_ms(500);
vTaskDelay(500 / portTICK_PERIOD_MS);
gpio_put(GPIO_15, false);
// sleep_ms(500);
vTaskDelay(500 / portTICK_PERIOD_MS);
gpio_put(GPIO_15, true);
// sleep_ms(500);
vTaskDelay(500 / portTICK_PERIOD_MS);
gpio_put(GPIO_15, false);
void blink_failed(uint gpio, uint32_t delay_ms, bool in_task) {
for (;;) {
gpio_put(gpio, false);
if (in_task)
vTaskDelay(pdMS_TO_TICKS(delay_ms));
else
sleep_ms(delay_ms);
reset(&global_state);
continue;
}
incr_counter(&global_state);
if (can_push(&global_state))
gpio_put(GPIO_15, true);
continue;
}
}
if (global_state.is_reset) {
global_state.on_reset = false;
global_state.is_reset = false;
}
global_state.push_clock = 0;
set_can_incr(&global_state, true);
gpio_put(GPIO_15, false);
gpio_put(gpio, true);
if (in_task)
vTaskDelay(pdMS_TO_TICKS(delay_ms));
else
sleep_ms(delay_ms);
}
}
void run_led_control() {
BaseType_t res = xTaskCreate(
led_control,
"led_controller",
configMINIMAL_STACK_SIZE,
NULL,
configMAX_PRIORITIES - 1U,
NULL
);
void healtchheck(void *const vParameters) {
params *p = (params *const)vParameters;
for (;;) {
if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING ||
get_status(p->s) != RUNNING)
gpio_put(p->gpio, false);
else
gpio_put(p->gpio, true);
vTaskDelay(pdMS_TO_TICKS(p->delays_ms));
}
}
void run_health(state *s) {
static params p = {
.delays_ms = 50,
.gpio = PICO_DEFAULT_LED_PIN,
.in_task = true,
};
p.s = s;
TaskHandle_t t;
BaseType_t res =
xTaskCreate(healtchheck, "healthcheck", configMINIMAL_STACK_SIZE,
(void *const)&p, configMAX_PRIORITIES - 1U, &t);
if (res != pdPASS) {
printf("error: unable to launch led control task, code error: %d\n", res);
stdio_printf("error: unable to launch healthcheck task, code error: %d\n",
res);
blink_failed(PICO_DEFAULT_LED_PIN, 200, false);
}
return;
}
void led_control(void *const vParameters) {
params *p = (params *const)vParameters;
for (;;) {
// return low level when the button is pressed
if (!gpio_get(GPIO_13)) {
vTaskDelay(pdMS_TO_TICKS(20)); // avoid "bounce" phenomenon (buffeting)
if (!gpio_get(GPIO_13)) {
if (p->s->is_reset)
continue;
set_push_clock(p->s);
if (is_resetting(p->s)) {
set_status(p->s, STOP);
reset(p->s);
for (int i = 0; i < 3; i++) {
gpio_put(GPIO_15, true);
vTaskDelay(pdMS_TO_TICKS(200));
gpio_put(GPIO_15, false);
vTaskDelay(pdMS_TO_TICKS(200));
}
continue;
}
incr_counter(p->s);
if (can_push(p->s))
gpio_put(GPIO_15, true);
else
set_status(p->s, STOP);
continue;
}
}
if (p->s->is_reset) {
set_status(p->s, RUNNING);
p->s->on_reset = false;
p->s->is_reset = false;
}
p->s->push_clock = 0;
set_can_incr(p->s, true);
gpio_put(GPIO_15, false);
}
}
void run_led_control(state *s) {
static params p;
p.s = s;
BaseType_t res =
xTaskCreate(led_control, "led_controller", configMINIMAL_STACK_SIZE,
(void *const)&p, configMAX_PRIORITIES - 1U, NULL);
if (res != pdPASS) {
stdio_printf("error: unable to launch led control task, code error: %d\n",
res);
blink_failed(PICO_DEFAULT_LED_PIN, 200, false);
}
}
/**
* Initialize needed GPIO.
*/
void init_gpio() {
#ifdef PICO_DEFAULT_LED_PIN
#ifdef PICO_DEFAULT_LED_PIN
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
#endif
#endif
gpio_init(GPIO_15);
gpio_set_dir(GPIO_15, GPIO_OUT);
@ -210,42 +252,41 @@ void init_gpio() {
gpio_set_dir(GPIO_13, GPIO_IN);
}
void check_scheduler_init(void *pvParameters) {
for (;;) {
BaseType_t state = xTaskGetSchedulerState();
if (state == taskSCHEDULER_RUNNING)
blink_success(true);
blink_success(true);
// vTaskDelay(pdMS_TO_TICKS(500));
}
}
/**
* Callback when unable to initialize task (not enough stask memory).
* Increase `uxStackDepth` arg when creating task if needed.
*/
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) {
blink_failed(false);
blink_failed(PICO_DEFAULT_LED_PIN, 100, true);
}
int main()
{
/**
* A simple application to play with leds with FreeRTOS.
* Yes, FreeRTOS is overkill for this kind of application
* but it's cool to see how easyly it can be integrated and
* easy to use for concurrent tasks.
*
* Hardware:
* - a push button switch
* - a red led
* - 2 10k ohm resistors
* - 1 200 ohm resistor
*
* When the Pico is on, the default led is on (acts as a healthcheck).
* You can then push the button and see the red led lights on.
* After 10 pushed, the red light lights off and the default led too.
* To reset the application, holds the button ~2 secs, the red light will
* blink two time and the application will be started again.
*
*/
int main() {
stdio_init_all();
init_gpio();
// TaskHandle_t health_task = run_health();
// TaskHandle_t led_task = run_led_control();
init_state(&global_state);
BaseType_t res = xTaskCreate(
check_scheduler_init,
"check_init",
256,
NULL,
configMAX_PRIORITIES - 1,
NULL
);
if (res != pdPASS)
blink_failed(false);
else
blink_success(false);
run_health(&global_state);
run_led_control(&global_state);
vTaskStartScheduler();
blink_failed(false);
}