task.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /**
  2. This file encapsulates the SDK-based task handling for the NodeMCU Lua firmware.
  3. */
  4. #include "task/task.h"
  5. #include "mem.h"
  6. #include <stdio.h>
  7. #define TASK_HANDLE_MONIKER 0x68680000
  8. #define TASK_HANDLE_MASK 0xFFF80000
  9. #define TASK_HANDLE_UNMASK (~TASK_HANDLE_MASK)
  10. #define TASK_HANDLE_SHIFT 2
  11. #define TASK_HANDLE_ALLOCATION_BRICK 4 // must be a power of 2
  12. #define TASK_DEFAULT_QUEUE_LEN 8
  13. #define TASK_PRIORITY_MASK 3
  14. #define CHECK(p,v,msg) if (!(p)) { NODE_DBG ( msg ); return (v); }
  15. /*
  16. * Private arrays to hold the 3 event task queues and the dispatch callbacks
  17. */
  18. LOCAL os_event_t *task_Q[TASK_PRIORITY_COUNT];
  19. LOCAL task_callback_t *task_func;
  20. LOCAL int task_count;
  21. LOCAL void task_dispatch (os_event_t *e) {
  22. task_handle_t handle = e->sig;
  23. if ( (handle & TASK_HANDLE_MASK) == TASK_HANDLE_MONIKER) {
  24. uint16 entry = (handle & TASK_HANDLE_UNMASK) >> TASK_HANDLE_SHIFT;
  25. uint8 priority = handle & TASK_PRIORITY_MASK;
  26. if ( priority <= TASK_PRIORITY_HIGH && task_func && entry < task_count ){
  27. /* call the registered task handler with the specified parameter and priority */
  28. task_func[entry](e->par, priority);
  29. return;
  30. }
  31. }
  32. /* Invalid signals are ignored */
  33. NODE_DBG ( "Invalid signal issued: %08x", handle);
  34. }
  35. /*
  36. * Initialise the task handle callback for a given priority. This doesn't need
  37. * to be called explicitly as the get_id function will call this lazily.
  38. */
  39. bool task_init_handler(uint8 priority, uint8 qlen) {
  40. if (priority <= TASK_PRIORITY_HIGH && task_Q[priority] == NULL) {
  41. task_Q[priority] = (os_event_t *) os_malloc( sizeof(os_event_t)*qlen );
  42. os_memset (task_Q[priority], 0, sizeof(os_event_t)*qlen);
  43. if (task_Q[priority]) {
  44. return system_os_task( task_dispatch, priority, task_Q[priority], qlen );
  45. }
  46. }
  47. return false;
  48. }
  49. task_handle_t task_get_id(task_callback_t t) {
  50. int p = TASK_PRIORITY_COUNT;
  51. /* Initialise and uninitialised Qs with the default Q len */
  52. while(p--) if (!task_Q[p]) {
  53. CHECK(task_init_handler( p, TASK_DEFAULT_QUEUE_LEN ), 0, "Task initialisation failed");
  54. }
  55. if ( (task_count & (TASK_HANDLE_ALLOCATION_BRICK - 1)) == 0 ) {
  56. /* With a brick size of 4 this branch is taken at 0, 4, 8 ... and the new size is +4 */
  57. task_func =(task_callback_t *) os_realloc(task_func,
  58. sizeof(task_callback_t)*(task_count+TASK_HANDLE_ALLOCATION_BRICK));
  59. CHECK(task_func, 0 , "Malloc failure in task_get_id");
  60. os_memset (task_func+task_count, 0, sizeof(task_callback_t)*TASK_HANDLE_ALLOCATION_BRICK);
  61. }
  62. task_func[task_count++] = t;
  63. return TASK_HANDLE_MONIKER + ((task_count-1) << TASK_HANDLE_SHIFT);
  64. }