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.

126 lines
3.9 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. }
  53. else if (strcmp_P(name, traced_variables[i].name)==0) {
  54. index = i;
  55. break;
  56. }
  57. }
  58. if (index == -1) {
  59. xprintf("You can only trace %d variables at the same time\n", NUM_TRACED_VARIABLES);
  60. return;
  61. }
  62. traced_variable_t* t = &traced_variables[index];
  63. t->name = name;
  64. t->addr = addr;
  65. t->size = size;
  66. t->func = func;
  67. t->line = line;
  68. memcpy(&t->last_value[0], addr, size);
  69. }
  70. void remove_traced_variable(const char* name, const char* func, int line) {
  71. verify_traced_variables(func, line);
  72. for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
  73. if (strcmp_P(name, traced_variables[i].name)==0) {
  74. traced_variables[i].name = 0;
  75. traced_variables[i].addr = NULL;
  76. break;
  77. }
  78. }
  79. }
  80. void verify_traced_variables(const char* func, int line) {
  81. for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
  82. traced_variable_t* t = &traced_variables[i];
  83. if (t->addr != NULL && t->name != NULL) {
  84. if (memcmp(t->last_value, t->addr, t->size)!=0){
  85. #if defined(__AVR__)
  86. xprintf("Traced variable \"%S\" has been modified\n", t->name);
  87. xprintf("Between %S:%d\n", t->func, t->line);
  88. xprintf("And %S:%d\n", func, line);
  89. #else
  90. xprintf("Traced variable \"%s\" has been modified\n", t->name);
  91. xprintf("Between %s:%d\n", t->func, t->line);
  92. xprintf("And %s:%d\n", func, line);
  93. #endif
  94. xprintf("Previous value ");
  95. for (int j=0; j<t->size;j++) {
  96. print_hex8(t->last_value[j]);
  97. }
  98. xprintf("\nNew value ");
  99. uint8_t* addr = (uint8_t*)(t->addr);
  100. for (int j=0; j<t->size;j++) {
  101. print_hex8(addr[j]);
  102. }
  103. xprintf("\n");
  104. memcpy(t->last_value, addr, t->size);
  105. }
  106. }
  107. t->func = func;
  108. t->line = line;
  109. }
  110. }