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