mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 13:09:38 +00:00 
			
		
		
		
	 486cc33fb3
			
		
	
	486cc33fb3
	
	
	
		
			
			This commit refactors port_common.c so that it only contains implementation of FreeRTOS port functions that are common to all FreeRTOS ports (i.e., on all architectures and on all FreeRTOS implementations).
		
			
				
	
	
		
			169 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * 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
 | |
| 
 | |
| #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 | |
| /* 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;
 | |
| }
 | |
| #endif // configSUPPORT_STATIC_ALLOCATION == 1
 | |
| /*-----------------------------------------------------------*/
 | |
| 
 | |
| #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 | |
| /* 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;
 | |
| }
 | |
| #endif // configSUPPORT_STATIC_ALLOCATION == 1
 | |
| 
 | |
| 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();
 | |
| }
 |