furi_ac.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "furi.h"
  2. #include "cmsis_os.h"
  3. // TODO: this file contains printf, that not implemented on uC target
  4. #ifdef FURI_DEBUG
  5. #include <stdio.h>
  6. #endif
  7. #define DEFAULT_STACK_SIZE 1024 // Stack size in bytes
  8. #define MAX_TASK_COUNT 8
  9. static StaticTask_t task_info_buffer[MAX_TASK_COUNT];
  10. static StackType_t stack_buffer[MAX_TASK_COUNT][DEFAULT_STACK_SIZE / 4];
  11. static FuriApp task_buffer[MAX_TASK_COUNT];
  12. static size_t current_buffer_idx = 0;
  13. // find task pointer by handle
  14. FuriApp* find_task(TaskHandle_t handler) {
  15. FuriApp* res = NULL;
  16. for(size_t i = 0; i < MAX_TASK_COUNT; i++) {
  17. if(task_equal(task_buffer[i].handler, handler)) {
  18. res = &task_buffer[i];
  19. }
  20. }
  21. return res;
  22. }
  23. FuriApp* furiac_start(FlipperApplication app, const char* name, void* param) {
  24. #ifdef FURI_DEBUG
  25. printf("[FURIAC] start %s\n", name);
  26. #endif
  27. // TODO check first free item (.handler == NULL) and use it
  28. if(current_buffer_idx >= MAX_TASK_COUNT) {
  29. // max task count exceed
  30. #ifdef FURI_DEBUG
  31. printf("[FURIAC] max task count exceed\n");
  32. #endif
  33. return NULL;
  34. }
  35. // create task on static stack memory
  36. task_buffer[current_buffer_idx].handler =
  37. xTaskCreateStatic((TaskFunction_t)app,
  38. (const char* const)name,
  39. DEFAULT_STACK_SIZE / 4, // freertos specify stack size in words
  40. (void* const)param,
  41. tskIDLE_PRIORITY + 3, // normal priority
  42. stack_buffer[current_buffer_idx],
  43. &task_info_buffer[current_buffer_idx]);
  44. // save task
  45. task_buffer[current_buffer_idx].application = app;
  46. task_buffer[current_buffer_idx].prev_name = NULL;
  47. task_buffer[current_buffer_idx].prev = NULL;
  48. task_buffer[current_buffer_idx].records_count = 0;
  49. task_buffer[current_buffer_idx].name = name;
  50. current_buffer_idx++;
  51. return &task_buffer[current_buffer_idx - 1];
  52. }
  53. bool furiac_kill(FuriApp* app) {
  54. #ifdef FURI_DEBUG
  55. printf("[FURIAC] kill %s\n", app->name);
  56. #endif
  57. // check handler
  58. if(app == NULL || app->handler == NULL) return false;
  59. // kill task
  60. vTaskDelete(app->handler);
  61. // cleanup its registry
  62. // TODO realy free memory
  63. app->handler = NULL;
  64. return true;
  65. }
  66. void furiac_exit(void* param) {
  67. // get current task handler
  68. FuriApp* current_task = find_task(xTaskGetCurrentTaskHandle());
  69. // run prev
  70. if(current_task != NULL) {
  71. #ifdef FURI_DEBUG
  72. printf("[FURIAC] exit %s\n", current_task->name);
  73. #endif
  74. if(current_task->prev != NULL) {
  75. furiac_start(current_task->prev, current_task->prev_name, param);
  76. } else {
  77. #ifdef FURI_DEBUG
  78. printf("[FURIAC] no prev\n");
  79. #endif
  80. }
  81. // cleanup registry
  82. // TODO realy free memory
  83. current_task->handler = NULL;
  84. }
  85. // kill itself
  86. vTaskDelete(NULL);
  87. }
  88. void furiac_switch(FlipperApplication app, char* name, void* param) {
  89. // get current task handler
  90. FuriApp* current_task = find_task(xTaskGetCurrentTaskHandle());
  91. if(current_task == NULL) {
  92. #ifdef FURI_DEBUG
  93. printf("[FURIAC] no current task found\n");
  94. #endif
  95. }
  96. #ifdef FURI_DEBUG
  97. printf("[FURIAC] switch %s to %s\n", current_task->name, name);
  98. #endif
  99. // run next
  100. FuriApp* next = furiac_start(app, name, param);
  101. if(next != NULL) {
  102. // save current application pointer as prev
  103. next->prev = current_task->application;
  104. next->prev_name = current_task->name;
  105. // kill itself
  106. vTaskDelete(NULL);
  107. }
  108. }