You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
4.0 KiB

  1. /* Copyright 2016 Fred Sundvik
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "variable_trace.h"
  17. #include <stddef.h>
  18. #include <string.h>
  19. #ifdef NO_PRINT
  20. # error "You need undef NO_PRINT to use the variable trace feature"
  21. #endif
  22. #ifndef CONSOLE_ENABLE
  23. # error "The console needs to be enabled in the makefile to use the variable trace feature"
  24. #endif
  25. #define NUM_TRACED_VARIABLES 1
  26. #ifndef MAX_VARIABLE_TRACE_SIZE
  27. # define MAX_VARIABLE_TRACE_SIZE 4
  28. #endif
  29. typedef struct {
  30. const char* name;
  31. void* addr;
  32. unsigned size;
  33. const char* func;
  34. int line;
  35. uint8_t last_value[MAX_VARIABLE_TRACE_SIZE];
  36. } traced_variable_t;
  37. static traced_variable_t traced_variables[NUM_TRACED_VARIABLES];
  38. void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line) {
  39. verify_traced_variables(func, line);
  40. if (size > MAX_VARIABLE_TRACE_SIZE) {
  41. #if defined(__AVR__)
  42. xprintf("Traced variable \"%S\" exceeds the maximum size %d\n", name, size);
  43. #else
  44. xprintf("Traced variable \"%s\" exceeds the maximum size %d\n", name, size);
  45. #endif
  46. size = MAX_VARIABLE_TRACE_SIZE;
  47. }
  48. int index = -1;
  49. for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
  50. if (index == -1 && traced_variables[i].addr == NULL) {
  51. index = i;
  52. } else if (strcmp_P(name, traced_variables[i].name) == 0) {
  53. index = i;
  54. break;
  55. }
  56. }
  57. if (index == -1) {
  58. xprintf("You can only trace %d variables at the same time\n", NUM_TRACED_VARIABLES);
  59. return;
  60. }
  61. traced_variable_t* t = &traced_variables[index];
  62. t->name = name;
  63. t->addr = addr;
  64. t->size = size;
  65. t->func = func;
  66. t->line = line;
  67. memcpy(&t->last_value[0], addr, size);
  68. }
  69. void remove_traced_variable(const char* name, const char* func, int line) {
  70. verify_traced_variables(func, line);
  71. for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
  72. if (strcmp_P(name, traced_variables[i].name) == 0) {
  73. traced_variables[i].name = 0;
  74. traced_variables[i].addr = NULL;
  75. break;
  76. }
  77. }
  78. }
  79. void verify_traced_variables(const char* func, int line) {
  80. for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
  81. traced_variable_t* t = &traced_variables[i];
  82. if (t->addr != NULL && t->name != NULL) {
  83. if (memcmp(t->last_value, t->addr, t->size) != 0) {
  84. #if defined(__AVR__)
  85. xprintf("Traced variable \"%S\" has been modified\n", t->name);
  86. xprintf("Between %S:%d\n", t->func, t->line);
  87. xprintf("And %S:%d\n", func, line);
  88. #else
  89. xprintf("Traced variable \"%s\" has been modified\n", t->name);
  90. xprintf("Between %s:%d\n", t->func, t->line);
  91. xprintf("And %s:%d\n", func, line);
  92. #endif
  93. xprintf("Previous value ");
  94. for (int j = 0; j < t->size; j++) {
  95. print_hex8(t->last_value[j]);
  96. }
  97. xprintf("\nNew value ");
  98. uint8_t* addr = (uint8_t*)(t->addr);
  99. for (int j = 0; j < t->size; j++) {
  100. print_hex8(addr[j]);
  101. }
  102. xprintf("\n");
  103. memcpy(t->last_value, addr, t->size);
  104. }
  105. }
  106. t->func = func;
  107. t->line = line;
  108. }
  109. }