stackusage.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include <pb_encode.h>
  2. #include <pb_decode.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <stdio.h>
  6. #include "stackusage.pb.h"
  7. static uint8_t g_msgbuf[256];
  8. static size_t g_msglen;
  9. /* This is a hacky way to measure actual stack usage of functions.
  10. * It works by copying the stack to a global variable, and then
  11. * finding the lowest location that has been modified.
  12. * Currently this assumes that the platform uses a descending stack.
  13. */
  14. #define MAX_STACK_ENTRIES 1024
  15. static uint32_t g_stackbuf[MAX_STACK_ENTRIES];
  16. static volatile uint32_t *g_stackptr;
  17. void start_stack_measuring()
  18. {
  19. uint32_t i = 0;
  20. g_stackptr = (volatile uint32_t*)((uintptr_t)&i - MAX_STACK_ENTRIES * sizeof(uint32_t));
  21. for (i = 0; i < MAX_STACK_ENTRIES; i++)
  22. {
  23. g_stackbuf[i] = g_stackptr[i];
  24. }
  25. }
  26. int end_stack_measuring()
  27. {
  28. uint32_t i = 0;
  29. for (i = 0; i < MAX_STACK_ENTRIES; i++)
  30. {
  31. if (g_stackbuf[i] != g_stackptr[i])
  32. {
  33. return (MAX_STACK_ENTRIES - i) * sizeof(uint32_t);
  34. }
  35. }
  36. assert(false);
  37. return 0;
  38. }
  39. void do_encode()
  40. {
  41. pb_ostream_t stream = pb_ostream_from_buffer(g_msgbuf, sizeof(g_msgbuf));
  42. SettingsGroup msg = SettingsGroup_init_zero;
  43. bool status;
  44. msg.has_settings = true;
  45. msg.settings.id = 1;
  46. strcpy(msg.settings.name, "abcd");
  47. msg.settings.en = true;
  48. msg.settings.has_begin = true;
  49. msg.settings.begin.label = 1234;
  50. msg.settings.begin.properties_count = 1;
  51. msg.settings.begin.properties[0].which_field = Property_DeviceA_Mode_tag;
  52. msg.settings.begin.properties[0].field.DeviceA_Mode = 2;
  53. status = pb_encode(&stream, SettingsGroup_fields, &msg);
  54. g_msglen = stream.bytes_written;
  55. assert(status);
  56. assert(g_msglen > 10);
  57. }
  58. void do_decode()
  59. {
  60. pb_istream_t stream = pb_istream_from_buffer(g_msgbuf, g_msglen);
  61. SettingsGroup msg = SettingsGroup_init_zero;
  62. bool status;
  63. status = pb_decode(&stream, SettingsGroup_fields, &msg);
  64. assert(status);
  65. assert(msg.settings.begin.properties[0].field.DeviceA_Mode == 2);
  66. }
  67. int main()
  68. {
  69. int stack_encode, stack_decode;
  70. start_stack_measuring();
  71. do_encode();
  72. stack_encode = end_stack_measuring();
  73. start_stack_measuring();
  74. do_decode();
  75. stack_decode = end_stack_measuring();
  76. /* Print machine-readable to stdout and user-readable to stderr */
  77. printf("%d %d\n", stack_encode, stack_decode);
  78. fprintf(stderr, "Stack usage: encode %d bytes, decode %d bytes\n",
  79. stack_encode, stack_decode);
  80. return 0;
  81. }