plugins.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <sys/queue.h>
  9. #include "plugins_api.h"
  10. /**
  11. * Demonstration of dynamic registration (self-registration):
  12. *
  13. * - example_plugin_register function is called from "constructor" functions of each plugin.
  14. * Information about the plugin is passed inside 'example_plugin_desc_t' structure.
  15. * This function adds each plugin description into linked list (s_plugins_list).
  16. *
  17. * - example_plugins_greet function iterates over the linked list.
  18. */
  19. struct plugin_record {
  20. example_plugin_desc_t plugin_desc;
  21. LIST_ENTRY(plugin_record) list_entry;
  22. };
  23. static LIST_HEAD(plugins_list, plugin_record) s_plugins_list = LIST_HEAD_INITIALIZER(s_plugins_list);
  24. void example_plugin_register(const example_plugin_desc_t* plugin_desc)
  25. {
  26. struct plugin_record *record = (struct plugin_record *) malloc(sizeof(struct plugin_record));
  27. if (record == NULL) {
  28. abort();
  29. }
  30. memcpy(&record->plugin_desc, plugin_desc, sizeof(*plugin_desc));
  31. struct plugin_record *head = LIST_FIRST(&s_plugins_list);
  32. if (head == NULL) {
  33. LIST_INSERT_HEAD(&s_plugins_list, record, list_entry);
  34. } else {
  35. LIST_INSERT_BEFORE(head, record, list_entry);
  36. }
  37. printf("Successfully registered plugin '%s'\n", plugin_desc->name);
  38. }
  39. void example_plugins_greet(const char* arg)
  40. {
  41. struct plugin_record *it;
  42. LIST_FOREACH(it, &s_plugins_list, list_entry) {
  43. printf("Calling greet function of plugin '%s'...\n", it->plugin_desc.name);
  44. (*it->plugin_desc.greet)(arg);
  45. printf("Done with greet function of plugin '%s'.\n", it->plugin_desc.name);
  46. }
  47. }
  48. /**
  49. * Demonstration of static registration.
  50. * Symbols '_plugins_array_start' and '_plugins_array_end' mark the beginning and end
  51. * of the array where 'example_plugin_desc_t' structures are placed by the linker.
  52. * The names of these variables are determined by linker.lf in 'plugins' component,
  53. * look for 'SURROUND(plugins_array)'.
  54. */
  55. void example_plugins_list(void)
  56. {
  57. printf("List of plugins:\n");
  58. extern const example_plugin_desc_t _plugins_array_start;
  59. extern const example_plugin_desc_t _plugins_array_end;
  60. for (const example_plugin_desc_t* it = &_plugins_array_start; it != &_plugins_array_end; ++it) {
  61. printf("- Plugin '%s', function greet=%p\n", it->name, it->greet);
  62. }
  63. }