variable_trace.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "variable_trace.h"
  2. #include <stddef.h>
  3. #include <string.h>
  4. #ifdef NO_PRINT
  5. #error "You need undef NO_PRINT to use the variable trace feature"
  6. #endif
  7. #ifndef CONSOLE_ENABLE
  8. #error "The console needs to be enabled in the makefile to use the variable trace feature"
  9. #endif
  10. #define NUM_TRACED_VARIABLES 1
  11. #define MAX_TRACE_SIZE 4
  12. typedef struct {
  13. const char* name;
  14. void* addr;
  15. unsigned size;
  16. const char* func;
  17. int line;
  18. uint8_t last_value[MAX_TRACE_SIZE];
  19. } traced_variable_t;
  20. static traced_variable_t traced_variables[NUM_TRACED_VARIABLES];
  21. void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line) {
  22. verify_traced_variables(func, line);
  23. if (size > MAX_TRACE_SIZE) {
  24. #if defined(__AVR__)
  25. xprintf("Traced variable \"%S\" exceeds the maximum size %d\n", name, size);
  26. #else
  27. xprintf("Traced variable \"%s\" exceeds the maximum size %d\n", name, size);
  28. #endif
  29. size = MAX_TRACE_SIZE;
  30. }
  31. int index = -1;
  32. for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
  33. if (index == -1 && traced_variables[i].addr == NULL){
  34. index = i;
  35. }
  36. else if (strcmp_P(name, traced_variables[i].name)==0) {
  37. index = i;
  38. break;
  39. }
  40. }
  41. if (index == -1) {
  42. xprintf("You can only trace %d variables at the same time\n", NUM_TRACED_VARIABLES);
  43. return;
  44. }
  45. traced_variable_t* t = &traced_variables[index];
  46. t->name = name;
  47. t->addr = addr;
  48. t->size = size;
  49. t->func = func;
  50. t->line = line;
  51. memcpy(&t->last_value[0], addr, size);
  52. }
  53. void remove_traced_variable(const char* name, const char* func, int line) {
  54. verify_traced_variables(func, line);
  55. for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
  56. if (strcmp_P(name, traced_variables[i].name)==0) {
  57. traced_variables[i].name = 0;
  58. traced_variables[i].addr = NULL;
  59. break;
  60. }
  61. }
  62. }
  63. void verify_traced_variables(const char* func, int line) {
  64. for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
  65. traced_variable_t* t = &traced_variables[i];
  66. if (t->addr != NULL && t->name != NULL) {
  67. if (memcmp(t->last_value, t->addr, t->size)!=0){
  68. #if defined(__AVR__)
  69. xprintf("Traced variable \"%S\" has been modified\n", t->name);
  70. xprintf("Between %S:%d\n", t->func, t->line);
  71. xprintf("And %S:%d\n", func, line);
  72. #else
  73. xprintf("Traced variable \"%s\" has been modified\n", t->name);
  74. xprintf("Between %s:%d\n", t->func, t->line);
  75. xprintf("And %s:%d\n", func, line);
  76. #endif
  77. xprintf("Previous value ");
  78. for (int j=0; j<t->size;j++) {
  79. print_hex8(t->last_value[j]);
  80. }
  81. xprintf("\nNew value ");
  82. uint8_t* addr = (uint8_t*)(t->addr);
  83. for (int j=0; j<t->size;j++) {
  84. print_hex8(addr[j]);
  85. }
  86. xprintf("\n");
  87. memcpy(t->last_value, addr, t->size);
  88. }
  89. }
  90. t->func = func;
  91. t->line = line;
  92. }
  93. }