LCOV - code coverage report
Current view: top level - stackusage - stackusage.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 45 46 97.8 %
Date: 2023-02-14 20:10:26 Functions: 5 5 100.0 %

          Line data    Source code
       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             : 
      20           2 : void start_stack_measuring()
      21             : {
      22           2 :     uint32_t i = 0;
      23           2 :     g_stackptr = (volatile uint32_t*)((uintptr_t)&i - MAX_STACK_ENTRIES * sizeof(uint32_t));
      24        2050 :     for (i = 0; i < MAX_STACK_ENTRIES; i++)
      25             :     {
      26        2048 :         g_stackbuf[i] = g_stackptr[i];
      27             :     }
      28           2 : }
      29             : 
      30           2 : int end_stack_measuring()
      31             : {
      32           2 :     uint32_t i = 0;
      33         944 :     for (i = 0; i < MAX_STACK_ENTRIES; i++)
      34             :     {
      35         944 :         if (g_stackbuf[i] != g_stackptr[i])
      36             :         {
      37           2 :             return (MAX_STACK_ENTRIES - i) * sizeof(uint32_t);
      38             :         }
      39             :     }
      40           0 :     assert(false);
      41             :     return 0;
      42             : }
      43             : 
      44           1 : void do_encode()
      45             : {
      46           1 :     pb_ostream_t stream = pb_ostream_from_buffer(g_msgbuf, sizeof(g_msgbuf));
      47           1 :     SettingsGroup msg = SettingsGroup_init_zero;
      48             :     bool status;
      49             : 
      50           1 :     msg.has_settings = true;
      51           1 :     msg.settings.id = 1;
      52           1 :     strcpy(msg.settings.name, "abcd");
      53           1 :     msg.settings.en = true;
      54           1 :     msg.settings.has_begin = true;
      55           1 :     msg.settings.begin.label = 1234;
      56           1 :     msg.settings.begin.properties_count = 1;
      57           1 :     msg.settings.begin.properties[0].which_field = Property_DeviceA_Mode_tag;
      58           1 :     msg.settings.begin.properties[0].field.DeviceA_Mode = 2;
      59             : 
      60           1 :     status = pb_encode(&stream, SettingsGroup_fields, &msg);
      61           1 :     g_msglen = stream.bytes_written;
      62           1 :     assert(status);
      63           1 :     assert(g_msglen > 10);
      64           1 : }
      65             : 
      66           1 : void do_decode()
      67             : {
      68           1 :     pb_istream_t stream = pb_istream_from_buffer(g_msgbuf, g_msglen);
      69           1 :     SettingsGroup msg = SettingsGroup_init_zero;
      70             :     bool status;
      71             : 
      72           1 :     status = pb_decode(&stream, SettingsGroup_fields, &msg);
      73           1 :     assert(status);
      74           1 :     assert(msg.settings.begin.properties[0].field.DeviceA_Mode == 2);
      75           1 : }
      76             : 
      77           1 : int main()
      78             : {
      79             :     int stack_encode, stack_decode;
      80             : 
      81           1 :     start_stack_measuring();
      82           1 :     do_encode();
      83           1 :     stack_encode = end_stack_measuring();
      84             : 
      85           1 :     start_stack_measuring();
      86           1 :     do_decode();
      87           1 :     stack_decode = end_stack_measuring();
      88             : 
      89             :     /* Print machine-readable to stdout and user-readable to stderr */
      90           1 :     printf("%d %d\n", stack_encode, stack_decode);
      91           1 :     fprintf(stderr, "Stack usage: encode %d bytes, decode %d bytes\n",
      92             :             stack_encode, stack_decode);
      93           1 :     return 0;
      94             : }

Generated by: LCOV version 1.14