#include "debug_tools.h" #include "IQmathLib.h" DebugLowLevel_t debug_ll = DEBUG_LOWLEVEL_INIT; static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var); static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var); ///////////////////////////----EXAPLE-----////////////////////////////// long var_numb = 1; long return_var; long return_ll_var; int result; char ext_date[] = {7, 233, 11, 07, 16, 50}; void Debug_Test_Example(void) { result = Debug_ReadVar(&dbg_vars[var_numb], &return_var); if(Debug_LowLevel_Initialize(ext_date) == 0) result = Debug_LowLevel_ReadVar(&return_ll_var); } ///////////////////////////----PUBLIC-----////////////////////////////// int Debug_LowLevel_ReadVar(long *return_long) { if (return_long == NULL) return 1; if (debug_ll.isVerified == 0) return 1; char *addr = debug_ll.dbg_var.Ptr; unsigned long addr_val = (unsigned long)addr; // Разрешённые диапазоны памяти (из .cmd файла) if (!( (addr_val <= 0x0007FF) || // RAMM0 + RAMM1 (addr_val >= 0x008120 && addr_val <= 0x009FFC) || // L0 + L1 SARAM (addr_val >= 0x3F8000 && addr_val <= 0x3F9FFF) || // PRAMH0 + DRAMH0 (addr_val >= 0x3FF000 && addr_val <= 0x3FFFFF) || // BOOTROM + RESET (addr_val >= 0x080002 && addr_val <= 0x09FFFF) || // RAMEX1 (addr_val >= 0x0F0000 && addr_val <= 0x0FFEFF) || // RAMEX4 (addr_val >= 0x100002 && addr_val <= 0x103FFF) || // RAMEX0 + RAMEX2 + RAMEX01 (addr_val >= 0x102000 && addr_val <= 0x103FFF) // RAMEX2 )) { return 2; // Запрещённый адрес — нельзя читать } convertDebugVarToIQx(&debug_ll.dbg_var, return_long); return 0; } int Debug_ReadVar(DebugVar_t *var, long *return_long) { long tmp_var; if (var == NULL) return 1; if((var->ptr_type == pt_struct) || (var->ptr_type == pt_union) || (var->ptr_type == pt_unknown)) return 1; convertDebugVarToIQx(var, return_long); return 0; } int Debug_ReadVarName(DebugVar_t *var, char *name_ptr) { if((var == NULL)||(name_ptr == NULL)) return 1; int i; // Копирование с защитой от переполнения и явной остановкой по '\0' for (i = 0; i < sizeof(var->name); i++) { name_ptr[i] = var->name[i]; if (var->name[i] == '\0') break; } // Гарантированное завершение строки (на случай, если в var->name не было '\0') name_ptr[sizeof(var->name) - 1] = '\0'; return 0; } int Debug_LowLevel_Initialize(const char* external_date) { if (external_date == NULL) { return -1; } // Преобразуем external_date в структуру DateTime_t ext; ext.year = (external_date[0] << 8) | external_date[1]; ext.day = external_date[2]; ext.month = external_date[3]; ext.hour = external_date[4]; ext.minute = external_date[5]; // Сравнение всех полей if (ext.year == debug_ll.build_date.year && ext.month == debug_ll.build_date.month && ext.day == debug_ll.build_date.day && ext.hour == debug_ll.build_date.hour && ext.minute == debug_ll.build_date.minute) { debug_ll.isVerified = 1; return 0; // Совпало } debug_ll.isVerified = 0; return 1; // Не совпало } /////////////////////----INTERNAL FUNCTIONS-----//////////////////////// static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var) { long iq_numb, iq_united, iq_final; float float_numb; if(getDebugVar(var, &iq_numb, &float_numb) != 0) return 1; // приведение к одному IQ switch(var->iq_type) { case t_iq_none: if(var->ptr_type == pt_float) { iq_united = _IQ(float_numb); } else { iq_united = _IQ(iq_numb); } break; case t_iq1: iq_united = _IQ1toIQ(iq_numb); break; case t_iq2: iq_united = _IQ2toIQ(iq_numb); break; case t_iq3: iq_united = _IQ3toIQ(iq_numb); break; case t_iq4: iq_united = _IQ4toIQ(iq_numb); break; case t_iq5: iq_united = _IQ5toIQ(iq_numb); break; case t_iq6: iq_united = _IQ6toIQ(iq_numb); break; case t_iq7: iq_united = _IQ7toIQ(iq_numb); break; case t_iq8: iq_united = _IQ8toIQ(iq_numb); break; case t_iq9: iq_united = _IQ9toIQ(iq_numb); break; case t_iq10: iq_united = _IQ10toIQ(iq_numb); break; case t_iq11: iq_united = _IQ11toIQ(iq_numb); break; case t_iq12: iq_united = _IQ12toIQ(iq_numb); break; case t_iq13: iq_united = _IQ13toIQ(iq_numb); break; case t_iq14: iq_united = _IQ14toIQ(iq_numb); break; case t_iq15: iq_united = _IQ15toIQ(iq_numb); break; case t_iq16: iq_united = _IQ16toIQ(iq_numb); break; case t_iq17: iq_united = _IQ17toIQ(iq_numb); break; case t_iq18: iq_united = _IQ18toIQ(iq_numb); break; case t_iq19: iq_united = _IQ19toIQ(iq_numb); break; case t_iq20: iq_united = _IQ20toIQ(iq_numb); break; case t_iq21: iq_united = _IQ21toIQ(iq_numb); break; case t_iq22: iq_united = _IQ22toIQ(iq_numb); break; case t_iq23: iq_united = _IQ23toIQ(iq_numb); break; case t_iq24: iq_united = _IQ24toIQ(iq_numb); break; case t_iq25: iq_united = _IQ25toIQ(iq_numb); break; case t_iq26: iq_united = _IQ26toIQ(iq_numb); break; case t_iq27: iq_united = _IQ27toIQ(iq_numb); break; case t_iq28: iq_united = _IQ28toIQ(iq_numb); break; case t_iq29: iq_united = _IQ29toIQ(iq_numb); break; case t_iq30: iq_united = _IQ30toIQ(iq_numb); break; } // приведение общего IQ к запрашиваемому switch(var->return_type) { case t_iq_none: iq_final = (long)_IQtoF(iq_united); break; case t_iq1: iq_final = _IQtoIQ1(iq_united); break; case t_iq2: iq_final = _IQtoIQ2(iq_united); break; case t_iq3: iq_final = _IQtoIQ3(iq_united); break; case t_iq4: iq_final = _IQtoIQ4(iq_united); break; case t_iq5: iq_final = _IQtoIQ5(iq_united); break; case t_iq6: iq_final = _IQtoIQ6(iq_united); break; case t_iq7: iq_final = _IQtoIQ7(iq_united); break; case t_iq8: iq_final = _IQtoIQ8(iq_united); break; case t_iq9: iq_final = _IQtoIQ9(iq_united); break; case t_iq10: iq_final = _IQtoIQ10(iq_united); break; case t_iq11: iq_final = _IQtoIQ11(iq_united); break; case t_iq12: iq_final = _IQtoIQ12(iq_united); break; case t_iq13: iq_final = _IQtoIQ13(iq_united); break; case t_iq14: iq_final = _IQtoIQ14(iq_united); break; case t_iq15: iq_final = _IQtoIQ15(iq_united); break; case t_iq16: iq_final = _IQtoIQ16(iq_united); break; case t_iq17: iq_final = _IQtoIQ17(iq_united); break; case t_iq18: iq_final = _IQtoIQ18(iq_united); break; case t_iq19: iq_final = _IQtoIQ19(iq_united); break; case t_iq20: iq_final = _IQtoIQ20(iq_united); break; case t_iq21: iq_final = _IQtoIQ21(iq_united); break; case t_iq22: iq_final = _IQtoIQ22(iq_united); break; case t_iq23: iq_final = _IQtoIQ23(iq_united); break; case t_iq24: iq_final = _IQtoIQ24(iq_united); break; case t_iq25: iq_final = _IQtoIQ25(iq_united); break; case t_iq26: iq_final = _IQtoIQ26(iq_united); break; case t_iq27: iq_final = _IQtoIQ27(iq_united); break; case t_iq28: iq_final = _IQtoIQ28(iq_united); break; case t_iq29: iq_final = _IQtoIQ29(iq_united); break; case t_iq30: iq_final = _IQtoIQ30(iq_united); break; } *ret_var = iq_final; return 0; } static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var) { if (!var || !int_var || !float_var || !var->Ptr) return 1; // ошибка: null указатель char *addr = var->Ptr; unsigned long addr_val = (unsigned long)addr; switch (var->ptr_type) { case pt_int8: // 8 бит case pt_uint8: // выравнивание не нужно для 8 бит *int_var = *((volatile char *)addr); break; case pt_int16: // 16 бит (int) case pt_uint16: if (addr_val & 0x1) // проверка выравнивания по 2 байтам return 2; // ошибка выравнивания *int_var = *((volatile int *)addr); break; case pt_int32: // 32 бит (long) case pt_uint32: if (addr_val & 0x3) // проверка выравнивания по 4 байтам return 3; // ошибка выравнивания *int_var = *((volatile long *)addr); break; // case pt_int64: // 64 бит (long long) // case pt_uint64: // if (addr_val & 0x7) // проверка выравнивания по 8 байтам // return 2; // ошибка выравнивания // // Тут просто читаем, но long long может не поместиться в *int_var // // Можно заменить логику под 64-битное чтение при необходимости // *int_var = *((volatile long long *)addr); // break; case pt_float: // float (4 байта) if (addr_val & 0x3) // проверка выравнивания по 4 байтам return 4; // ошибка выравнивания *float_var = *((volatile float *)addr); break; default: return 1; // неподдерживаемый тип // для указателей и массивов не поддерживается чтение // case pt_ptr_int8: // case pt_ptr_int16: // case pt_ptr_int32: // case pt_ptr_uint8: // case pt_ptr_uint16: // case pt_ptr_uint32: // case pt_arr_int8: // case pt_arr_int16: // case pt_arr_int32: // case pt_arr_uint8: // case pt_arr_uint16: // case pt_arr_uint32: } return 0; // успех }