furi_ac.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 = xTaskCreateStatic(
  37. (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. );
  45. // save task
  46. task_buffer[current_buffer_idx].application = app;
  47. task_buffer[current_buffer_idx].prev_name = NULL;
  48. task_buffer[current_buffer_idx].prev = NULL;
  49. task_buffer[current_buffer_idx].records_count = 0;
  50. task_buffer[current_buffer_idx].name = name;
  51. current_buffer_idx++;
  52. return &task_buffer[current_buffer_idx - 1];
  53. }
  54. bool furiac_kill(FuriApp* app) {
  55. #ifdef FURI_DEBUG
  56. printf("[FURIAC] kill %s\n", app->name);
  57. #endif
  58. // check handler
  59. if(app == NULL || app->handler == NULL) return false;
  60. // kill task
  61. vTaskDelete(app->handler);
  62. // cleanup its registry
  63. // TODO realy free memory
  64. app->handler = NULL;
  65. return true;
  66. }
  67. void furiac_exit(void* param) {
  68. // get current task handler
  69. FuriApp* current_task = find_task(xTaskGetCurrentTaskHandle());
  70. // run prev
  71. if(current_task != NULL) {
  72. #ifdef FURI_DEBUG
  73. printf("[FURIAC] exit %s\n", current_task->name);
  74. #endif
  75. if(current_task->prev != NULL) {
  76. furiac_start(current_task->prev, current_task->prev_name, param);
  77. } else {
  78. #ifdef FURI_DEBUG
  79. printf("[FURIAC] no prev\n");
  80. #endif
  81. }
  82. // cleanup registry
  83. // TODO realy free memory
  84. current_task->handler = NULL;
  85. }
  86. // kill itself
  87. vTaskDelete(NULL);
  88. }
  89. void furiac_switch(FlipperApplication app, char* name, void* param) {
  90. // get current task handler
  91. FuriApp* current_task = find_task(xTaskGetCurrentTaskHandle());
  92. if(current_task == NULL) {
  93. #ifdef FURI_DEBUG
  94. printf("[FURIAC] no current task found\n");
  95. #endif
  96. }
  97. #ifdef FURI_DEBUG
  98. printf("[FURIAC] switch %s to %s\n", current_task->name, name);
  99. #endif
  100. // run next
  101. FuriApp* next = furiac_start(app, name, param);
  102. if(next != NULL) {
  103. // save current application pointer as prev
  104. next->prev = current_task->application;
  105. next->prev_name = current_task->name;
  106. // kill itself
  107. vTaskDelete(NULL);
  108. }
  109. }