2022-09-06 14:09:23 +00:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file contains most of the code located in the demo application in the
|
|
|
|
* upstream FreeRTOS repository. It is put here so that IDF applications can
|
|
|
|
* seamlessly switch between Linux and chip targets without the need to provide
|
|
|
|
* or implement additional functionality if the target is the Linux target.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
/* Scheduler includes. */
|
|
|
|
#include "FreeRTOS.h"
|
|
|
|
#include "task.h"
|
|
|
|
#include "utils/wait_for_event.h"
|
|
|
|
#include "esp_log.h"
|
|
|
|
|
|
|
|
static const char *TAG = "port";
|
|
|
|
|
|
|
|
static volatile UBaseType_t uxInterruptNesting = 0;
|
|
|
|
|
|
|
|
/* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can
|
|
|
|
* use a callback function to optionally provide the memory required by the idle
|
|
|
|
* and timer tasks. This is the stack that will be used by the timer task. It is
|
|
|
|
* declared here, as a global, so it can be checked by a test that is implemented
|
|
|
|
* in a different file. */
|
|
|
|
StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
|
|
|
|
|
|
|
BaseType_t xPortCheckIfInISR(void)
|
|
|
|
{
|
|
|
|
return uxInterruptNesting;
|
|
|
|
}
|
|
|
|
|
|
|
|
void app_main(void);
|
|
|
|
|
|
|
|
static void main_task(void* args)
|
|
|
|
{
|
|
|
|
app_main();
|
|
|
|
vTaskDelete(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, const char **argv)
|
|
|
|
{
|
|
|
|
// This makes sure that stdio is flushed after each '\n' so that idf.py monitor
|
|
|
|
// reads the program output on time.
|
|
|
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
|
|
|
|
|
|
|
usleep(1000);
|
|
|
|
portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
|
|
|
|
ESP_TASK_MAIN_STACK, NULL,
|
|
|
|
ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE);
|
|
|
|
assert(res == pdTRUE);
|
|
|
|
(void)res;
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "Starting scheduler.");
|
|
|
|
vTaskStartScheduler();
|
|
|
|
|
|
|
|
// This line should never be reached
|
|
|
|
assert(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void esp_vApplicationIdleHook(void)
|
|
|
|
{
|
|
|
|
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
|
|
|
|
* to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
|
|
|
|
* task. It is essential that code added to this hook function never attempts
|
|
|
|
* to block in any way (for example, call xQueueReceive() with a block time
|
|
|
|
* specified, or call vTaskDelay()). If application tasks make use of the
|
|
|
|
* vTaskDelete() API function to delete themselves then it is also important
|
|
|
|
* that vApplicationIdleHook() is permitted to return to its calling function,
|
|
|
|
* because it is the responsibility of the idle task to clean up memory
|
|
|
|
* allocated by the kernel to any task that has since deleted itself. */
|
|
|
|
|
|
|
|
|
|
|
|
usleep( 15000 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void esp_vApplicationTickHook( void ) { }
|
|
|
|
|
|
|
|
#if ( configUSE_TICK_HOOK > 0 )
|
|
|
|
void vApplicationTickHook( void )
|
|
|
|
{
|
|
|
|
esp_vApplicationTickHook();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void vPortYieldOtherCore( BaseType_t coreid ) { } // trying to skip for now
|
|
|
|
|
2022-11-24 14:28:13 +00:00
|
|
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
2022-09-06 14:09:23 +00:00
|
|
|
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
|
|
|
|
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
|
|
|
|
* used by the Idle task. */
|
|
|
|
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
|
|
|
|
StackType_t ** ppxIdleTaskStackBuffer,
|
|
|
|
uint32_t * pulIdleTaskStackSize )
|
|
|
|
{
|
|
|
|
/* If the buffers to be provided to the Idle task are declared inside this
|
|
|
|
* function then they must be declared static - otherwise they will be allocated on
|
|
|
|
* the stack and so not exists after this function exits. */
|
|
|
|
static StaticTask_t xIdleTaskTCB;
|
|
|
|
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
|
|
|
|
|
|
|
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
|
|
|
|
* state will be stored. */
|
|
|
|
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
|
|
|
|
|
|
|
/* Pass out the array that will be used as the Idle task's stack. */
|
|
|
|
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
|
|
|
|
|
|
|
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
|
|
|
* Note that, as the array is necessarily of type StackType_t,
|
|
|
|
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
|
|
|
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
|
|
|
}
|
2022-11-24 14:28:13 +00:00
|
|
|
#endif // configSUPPORT_STATIC_ALLOCATION == 1
|
2022-09-06 14:09:23 +00:00
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
2022-11-24 14:28:13 +00:00
|
|
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
2022-09-06 14:09:23 +00:00
|
|
|
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
|
|
|
* application must provide an implementation of vApplicationGetTimerTaskMemory()
|
|
|
|
* to provide the memory that is used by the Timer service task. */
|
|
|
|
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
|
|
|
|
StackType_t ** ppxTimerTaskStackBuffer,
|
|
|
|
uint32_t * pulTimerTaskStackSize )
|
|
|
|
{
|
|
|
|
/* If the buffers to be provided to the Timer task are declared inside this
|
|
|
|
* function then they must be declared static - otherwise they will be allocated on
|
|
|
|
* the stack and so not exists after this function exits. */
|
|
|
|
static StaticTask_t xTimerTaskTCB;
|
|
|
|
|
|
|
|
/* Pass out a pointer to the StaticTask_t structure in which the Timer
|
|
|
|
* task's state will be stored. */
|
|
|
|
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
|
|
|
|
|
|
|
/* Pass out the array that will be used as the Timer task's stack. */
|
|
|
|
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
|
|
|
|
|
|
|
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
|
|
|
|
* Note that, as the array is necessarily of type StackType_t,
|
|
|
|
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
|
|
|
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
|
|
|
}
|
2022-11-24 14:28:13 +00:00
|
|
|
#endif // configSUPPORT_STATIC_ALLOCATION == 1
|
2022-09-06 14:09:23 +00:00
|
|
|
|
|
|
|
void __attribute__((weak)) vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
|
|
|
|
{
|
|
|
|
#define ERR_STR1 "***ERROR*** A stack overflow in task "
|
|
|
|
#define ERR_STR2 " has been detected."
|
|
|
|
const char *str[] = {ERR_STR1, pcTaskName, ERR_STR2};
|
|
|
|
|
|
|
|
char buf[sizeof(ERR_STR1) + CONFIG_FREERTOS_MAX_TASK_NAME_LEN + sizeof(ERR_STR2) + 1 /* null char */] = {0};
|
|
|
|
|
|
|
|
char *dest = buf;
|
|
|
|
for (int i = 0; i < sizeof(str) / sizeof(str[0]); i++) {
|
|
|
|
dest = strcat(dest, str[i]);
|
|
|
|
}
|
|
|
|
printf("%s\n", buf);
|
|
|
|
abort();
|
|
|
|
}
|