port_idf.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /*
  7. * This file contains most of the code located in the demo application in the
  8. * upstream FreeRTOS repository. It is put here so that IDF applications can
  9. * seamlessly switch between Linux and chip targets without the need to provide
  10. * or implement additional functionality if the target is the Linux target.
  11. */
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <assert.h>
  16. #include <time.h>
  17. #include <unistd.h>
  18. /* Scheduler includes. */
  19. #include "FreeRTOS.h"
  20. #include "task.h"
  21. #include "utils/wait_for_event.h"
  22. #include "esp_log.h"
  23. static const char *TAG = "port";
  24. static volatile UBaseType_t uxInterruptNesting = 0;
  25. /* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can
  26. * use a callback function to optionally provide the memory required by the idle
  27. * and timer tasks. This is the stack that will be used by the timer task. It is
  28. * declared here, as a global, so it can be checked by a test that is implemented
  29. * in a different file. */
  30. StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
  31. BaseType_t xPortCheckIfInISR(void)
  32. {
  33. return uxInterruptNesting;
  34. }
  35. void app_main(void);
  36. static void main_task(void* args)
  37. {
  38. app_main();
  39. vTaskDelete(NULL);
  40. }
  41. int main(int argc, const char **argv)
  42. {
  43. // This makes sure that stdio is flushed after each '\n' so that idf.py monitor
  44. // reads the program output on time.
  45. setvbuf(stdout, NULL, _IOLBF, 0);
  46. usleep(1000);
  47. BaseType_t res = xTaskCreatePinnedToCore(&main_task, "main",
  48. ESP_TASK_MAIN_STACK, NULL,
  49. ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE);
  50. assert(res == pdTRUE);
  51. (void)res;
  52. ESP_LOGI(TAG, "Starting scheduler.");
  53. vTaskStartScheduler();
  54. // This line should never be reached
  55. assert(false);
  56. }
  57. void esp_vApplicationIdleHook(void)
  58. {
  59. /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
  60. * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
  61. * task. It is essential that code added to this hook function never attempts
  62. * to block in any way (for example, call xQueueReceive() with a block time
  63. * specified, or call vTaskDelay()). If application tasks make use of the
  64. * vTaskDelete() API function to delete themselves then it is also important
  65. * that vApplicationIdleHook() is permitted to return to its calling function,
  66. * because it is the responsibility of the idle task to clean up memory
  67. * allocated by the kernel to any task that has since deleted itself. */
  68. usleep( 15000 );
  69. }
  70. void esp_vApplicationTickHook( void ) { }
  71. #if ( configUSE_TICK_HOOK > 0 )
  72. void vApplicationTickHook( void )
  73. {
  74. esp_vApplicationTickHook();
  75. }
  76. #endif
  77. void vPortYieldOtherCore( BaseType_t coreid ) { } // trying to skip for now
  78. #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
  79. /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
  80. * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
  81. * used by the Idle task. */
  82. void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
  83. StackType_t ** ppxIdleTaskStackBuffer,
  84. uint32_t * pulIdleTaskStackSize )
  85. {
  86. /* If the buffers to be provided to the Idle task are declared inside this
  87. * function then they must be declared static - otherwise they will be allocated on
  88. * the stack and so not exists after this function exits. */
  89. static StaticTask_t xIdleTaskTCB;
  90. static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
  91. /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
  92. * state will be stored. */
  93. *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
  94. /* Pass out the array that will be used as the Idle task's stack. */
  95. *ppxIdleTaskStackBuffer = uxIdleTaskStack;
  96. /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
  97. * Note that, as the array is necessarily of type StackType_t,
  98. * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
  99. *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
  100. }
  101. #endif // configSUPPORT_STATIC_ALLOCATION == 1
  102. /*-----------------------------------------------------------*/
  103. #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
  104. /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
  105. * application must provide an implementation of vApplicationGetTimerTaskMemory()
  106. * to provide the memory that is used by the Timer service task. */
  107. void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
  108. StackType_t ** ppxTimerTaskStackBuffer,
  109. uint32_t * pulTimerTaskStackSize )
  110. {
  111. /* If the buffers to be provided to the Timer task are declared inside this
  112. * function then they must be declared static - otherwise they will be allocated on
  113. * the stack and so not exists after this function exits. */
  114. static StaticTask_t xTimerTaskTCB;
  115. /* Pass out a pointer to the StaticTask_t structure in which the Timer
  116. * task's state will be stored. */
  117. *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
  118. /* Pass out the array that will be used as the Timer task's stack. */
  119. *ppxTimerTaskStackBuffer = uxTimerTaskStack;
  120. /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
  121. * Note that, as the array is necessarily of type StackType_t,
  122. * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
  123. *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
  124. }
  125. #endif // configSUPPORT_STATIC_ALLOCATION == 1
  126. void __attribute__((weak)) vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
  127. {
  128. #define ERR_STR1 "***ERROR*** A stack overflow in task "
  129. #define ERR_STR2 " has been detected."
  130. const char *str[] = {ERR_STR1, pcTaskName, ERR_STR2};
  131. char buf[sizeof(ERR_STR1) + CONFIG_FREERTOS_MAX_TASK_NAME_LEN + sizeof(ERR_STR2) + 1 /* null char */] = {0};
  132. char *dest = buf;
  133. for (int i = 0; i < sizeof(str) / sizeof(str[0]); i++) {
  134. dest = strcat(dest, str[i]);
  135. }
  136. printf("%s\n", buf);
  137. abort();
  138. }