From 04a9d989fb382cddd2e8de8ec2d25f154bce7937 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 13 Oct 2026 14:13:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20TESTLAMP,=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA?= =?UTF-8?q?=20CAN=20=D0=B8=20=D1=80=D0=B0=D1=81=D1=87=D1=91=D1=82=20=D1=84?= =?UTF-8?q?=D0=B0=D0=B7=D0=BD=D1=8B=D1=85=20=D1=82=D0=BE=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Сохранить состояние TESTLAMP при кратких провалах входа и исключить повторный вход Timer1 во время передачи индикации. Явно сбрасывать служебный обмен CAN при запуске и выбирать соседнюю фазу по локальному индексу канала АЦП. Сохранить текущую последовательность DATA/CLK и проверочные варианты таймингов, добавить поведенческие тесты и обновить образ прошивки с картой памяти. --- .../A_delay_before_clock_fall/kanal.c | 358 +++++ .../B_delay_after_clock_fall/kanal.c | 358 +++++ Bin/IndicatorTimingCompare/README.txt | 37 + Bin/TestLampFix/README.txt | 48 + Bin/TestLampFix/rebuild.py | 54 + Bin/UKSSTMS320F28335.hex | Bin 32246 -> 32272 bytes Source/Internal/ecan.c | 28 + Source/Internal/kanal.c | 12 +- Source/Internal/measure.c | 4 +- Source/Internal/peripher.c | 4 +- Source/Internal/pulto.c | 4 +- UKSSTMS320F28335.map | 1286 ++++++++--------- tests/current_measure/model.inc | 90 ++ tests/current_measure/run_test.py | 44 + tests/testlamp/model.inc | 122 ++ tests/testlamp/run_test.py | 46 + tests/ump_can_init/model.inc | 87 ++ tests/ump_can_init/run_test.py | 56 + 18 files changed, 1983 insertions(+), 655 deletions(-) create mode 100644 Bin/IndicatorTimingCompare/A_delay_before_clock_fall/kanal.c create mode 100644 Bin/IndicatorTimingCompare/B_delay_after_clock_fall/kanal.c create mode 100644 Bin/IndicatorTimingCompare/README.txt create mode 100644 Bin/TestLampFix/README.txt create mode 100644 Bin/TestLampFix/rebuild.py create mode 100644 tests/current_measure/model.inc create mode 100644 tests/current_measure/run_test.py create mode 100644 tests/testlamp/model.inc create mode 100644 tests/testlamp/run_test.py create mode 100644 tests/ump_can_init/model.inc create mode 100644 tests/ump_can_init/run_test.py diff --git a/Bin/IndicatorTimingCompare/A_delay_before_clock_fall/kanal.c b/Bin/IndicatorTimingCompare/A_delay_before_clock_fall/kanal.c new file mode 100644 index 0000000..60e7201 --- /dev/null +++ b/Bin/IndicatorTimingCompare/A_delay_before_clock_fall/kanal.c @@ -0,0 +1,358 @@ +/* Последовательный вывод данных канала индикации. Русские пояснения сохранены в UTF-8. */ +/* Подключает "DSP2833x_Device.h": поставляемое TI описание Device для семейства C2833x. */ +#include "DSP2833x_Device.h" // DSP281x Headerfile Include File +/* Подключает "DSP2833x_SWPrioritizedIsrLevels.h": поставляемое TI описание SWPrioritizedIsrLevels для семейства C2833x. */ +#include "DSP2833x_SWPrioritizedIsrLevels.h" +/* Подключает "filter_bat2.h": накопительный фильтр измерительных каналов. */ +#include "filter_bat2.h" +/* Подключает "measure.h": обработка датчиков, вычисление величин и миллисекундный такт системы. */ +#include "measure.h" + +/* Подключает "RS485.h": приём и передача SCI-A/SCI-B, упаковка команд и FIFO первого порта. */ +#include "RS485.h" +/* Подключает "message.h": обработка Modbus, заводские параметры и сохранение настроек. */ +#include "message.h" +/* Подключает "kanal.h": последовательный вывод данных канала индикации. */ +#include "kanal.h" +/* Подключает "pulto.h": обмен и индикация пульта. */ +#include "pulto.h" +/* Подключает "package.h": адреса устройств, типы плат и псевдонимы технологических регистров. */ +#include "package.h" +/* Подключает "tools.h": настройка внешней памяти и служебные задержки. */ +#include "tools.h" + +/* Подключает "peripher.h": перемычки режима платы, дискретные входы и выходы. */ +#include "peripher.h" + +/* Объявляет digits — данные digits. Начальное значение задаётся справа от знака равенства. */ +int digits[16] = {63,6,91,79,102,109,125,7,127,111,64,0,0,0,121,0}; +/* Объявляет readr — данные readr. Начальное значение задаётся справа от знака равенства. */ +int readr[5] = {0x08,0x0C,0x10,0x00,0x04}; + +/* Ограничивает настройки таймингов компилятором TI C2000; модель на ПК не использует эти директивы. */ +#if defined(__TI_COMPILER_VERSION__) +/* Сохраняет отдельный вызов переключения CLOCK: встраивание при -O3 сокращало удержание DATA после фронта. */ +#pragma FUNC_CANNOT_INLINE(DCLK) +/* Возвращает генерацию DCLK как в образе от 06.10.2026: уровень 1 и приоритет скорости 3 сохраняют прежнюю последовательность инструкций GPIO. */ +#pragma FUNCTION_OPTIONS(DCLK, "--opt_level=1 --opt_for_speed=3") +/* Сохраняет отдельный вызов переключения DATA, чтобы длительность импульсов не зависела от встраивания в передатчик. */ +#pragma FUNC_CANNOT_INLINE(DOUT) +/* Возвращает генерацию DOUT с прежними параметрами -O1 и --opt_for_speed=3; значения взяты из старой конфигурации CCS. */ +#pragma FUNCTION_OPTIONS(DOUT, "--opt_level=1 --opt_for_speed=3") +/* Не позволяет встроить разделитель пакетов в цикл передачи и изменить интервалы между переключениями линий. */ +#pragma FUNC_CANNOT_INLINE(RESET) +/* Сохраняет прежнюю последовательность вызовов GPIO и задержек разделителя, используя настройки старого образа. */ +#pragma FUNCTION_OPTIONS(RESET, "--opt_level=1 --opt_for_speed=3") +/* Сохраняет отдельный вызов передачи бита; протокол использует порядок и интервалы фронтов CLOCK и DATA. */ +#pragma FUNC_CANNOT_INLINE(SENDBIT) +/* Возвращает передаче бита настройки старого образа -O1 и --opt_for_speed=3, оставляя остальной проект на -O3. */ +#pragma FUNCTION_OPTIONS(SENDBIT, "--opt_level=1 --opt_for_speed=3") +/* Завершает блок настроек TI, не изменяя формат пакетов и существующие счётчики задержек. */ +#endif + +/* Начинает функцию DCLK; назначение модуля — последовательный вывод данных канала индикации. */ +void DCLK(int x) +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Проверяет if(x) GpioDataRegs.GPASET.bit.GPIO6=1; последующий оператор выполняется только при истинном условии. */ + if(x) GpioDataRegs.GPASET.bit.GPIO6=1; + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else GpioDataRegs.GPACLEAR.bit.GPIO6=1; +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} + +/* Начинает функцию DOUT; назначение модуля — последовательный вывод данных канала индикации. */ +void DOUT(int x) +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Проверяет if(x) GpioDataRegs.GPASET.bit.GPIO8=1; последующий оператор выполняется только при истинном условии. */ + if(x) GpioDataRegs.GPASET.bit.GPIO8=1; + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else GpioDataRegs.GPACLEAR.bit.GPIO8=1; +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} + +/* Условие компиляции CLKMULT==1: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==1 +/* Задаёт POWS0 = 0L; данные POWS0. */ +#define POWS0 0L +/* Задаёт POWS1 = 10L; данные POWS1. */ +#define POWS1 10L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Условие компиляции CLKMULT==2: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==2 +/* Задаёт POWS0 = 0L; данные POWS0. */ +#define POWS0 0L +/* Задаёт POWS1 = 30L; данные POWS1. */ +#define POWS1 30L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Условие компиляции CLKMULT==3: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==3 +/* Задаёт POWS0 = 1L; данные POWS0. */ +#define POWS0 1L +/* Задаёт POWS1 = 50L; данные POWS1. */ +#define POWS1 50L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Условие компиляции CLKMULT==4: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==4 +/* Задаёт POWS0 = 2L; данные POWS0. */ +#define POWS0 2L +/* Задаёт POWS1 = 60L; данные POWS1. */ +#define POWS1 60L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Условие компиляции CLKMULT==5: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==5 +/* Задаёт POWS0 = 4L; данные POWS0. */ +#define POWS0 4L +/* Задаёт POWS1 = 80L; данные POWS1. */ +#define POWS1 80L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif + +/* Начинает функцию RESET; назначение модуля — последовательный вывод данных канала индикации. */ +void RESET() +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Вызывает DCLK с аргументами (0) в текущей последовательности операций. */ + DCLK(0); +/* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS1>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS1); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif + /* Вызывает DOUT с аргументами (1) в текущей последовательности операций. */ + DOUT(1); +/* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS1>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS1); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif + /* Вызывает DOUT с аргументами (0) в текущей последовательности операций. */ + DOUT(0); +/* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS1>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS1); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} + +/* Начинает функцию SENDBIT; назначение модуля — последовательный вывод данных канала индикации. */ +void SENDBIT(int x) +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Выставляет передаваемый бит DATA до подъёма CLOCK, сохраняя его на протяжении высокого уровня такта. */ + DOUT(x); DCLK(1); +/* Условие компиляции POWS0>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS0>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS0) в текущей последовательности операций. */ + DSP28x_usDelay(POWS0); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif + /* Вариант A: задержка перед спадом CLOCK продлевает высокий уровень при действительном DATA; POWS0+1 — прежний счётчик циклов TI, не микросекунды. */ + DSP28x_usDelay(POWS0+1); + /* Опускает CLOCK при ещё действительном DATA, чтобы сохранить передаваемый бит на отрицательном фронте такта. */ + DCLK(0); + /* Сбрасывает DATA после спада CLOCK; в варианте A дополнительной задержки между спадом и сбросом нет. */ + DOUT(0); +/* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS1>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS1); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} + +/* Начинает функцию kanal_Send; назначение модуля — последовательный вывод данных канала индикации. */ +void kanal_Send(int adr, long dat, int dot) +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Объявляет Word — слово; data — данные; aliq_part — данные aliq_part; dg — данные dg. */ + long Word,data,aliq_part,dg[4]; + /* Объявляет i — данные i; j — данные j; bit — представление регистра отдельными битовыми полями; byt — данные byt; addr — данные addr. Начальное значение задаётся справа от знака равенства. */ + int i,j,bit,byt,addr,sgn=0,punkt=0,aliq_len=0,full_len, isdot=0; + + /* Проверяет if(adr>1); последующий оператор выполняется только при истинном условии. */ + if(adr>1) // Лампочки + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает Word значением dat; слово. */ + Word =dat; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else + + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Проверяет if(dat<0) sgn=1; последующий оператор выполняется только при истинном условии. */ + if(dat<0) sgn=1; + /* Записывает data значением labs(dat); данные. */ + data = labs(dat); + + /* Проверяет if(dot>=0 и dot<4) isdot = 1; последующий оператор выполняется только при истинном условии. */ + if(dot>=0 && dot<4) isdot = 1; + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else dot=0; + + /* Записывает aliq_part значением data; данные aliq_part. */ + aliq_part = data; + /* Цикл for(i=0;i0). */ + while(dat>0) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Делит dat значением 10; данные dat. */ + aliq_len++; dat/=10; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Записывает dat значением data; данные dat. */ + dat = data; + + /* Записывает full_len значением aliq_len+sgn; данные full_len. */ + full_len = aliq_len+sgn; + /* Проверяет if(full_len==0) full_len=1; последующий оператор выполняется только при истинном условии. */ + if(full_len==0) full_len=1; + /* Увеличивает full_len значением dot; данные full_len. */ + full_len += dot; + + /* Цикл for(i=0; i<(full_len-4);i++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for(i=0; i<(full_len-4);i++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Начинает цикл с проверкой условия после тела: первый проход выполняется всегда. */ + dot--; dat/=10; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + /* Проверяет if(dot<0) dot=0; последующий оператор выполняется только при истинном условии. */ + if(dot<0) dot=0; + /* Записывает punkt значением 1<0;i--); задаёт начальное значение, условие продолжения и шаг перебора. */ + for(i=3;i>0;i--) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Проверяет if((dg[i]==0) и (i!=dot)); последующий оператор выполняется только при истинном условии. */ + if((dg[i]==0)&&(i!=dot)) + /* Записывает dg[i] значением 0xF; данные dg. */ + dg[i]=0xF; // Это значит пусто + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else break; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Проверяет if(sgn); последующий оператор выполняется только при истинном условии. */ + if(sgn) + /* Цикл for(i=1;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for(i=1;i<4;i++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Проверяет if( (dg[i]==0xF) или (i==3)); последующий оператор выполняется только при истинном условии. */ + if( (dg[i]==0xF)||(i==3)) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает dg[i] значением 0xA; данные dg. */ + dg[i]=0xA; // Это значит минус + /* Прерывает ближайший цикл или ветвь switch и продолжает после него. */ + break; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } } + + /* Цикл for(i=0;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for(i=0;i<4;i++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает dg[i] значением digits[dg[i]]; данные dg. */ + dg[i] = digits[dg[i]]; + /* Проверяет if((punkt>>i)&1) dg[i]+= 128; последующий оператор выполняется только при истинном условии. */ + if((punkt>>i)&1) dg[i]+= 128; + + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Записывает Word значением ((dg[0] ) & 0x000000FF) | ((dg[1]<<8 ) & 0x0000FF00) |; слово. */ + Word = ((dg[0] ) & 0x000000FF) | ((dg[1]<<8 ) & 0x0000FF00) | + /* Продолжает список аргументов, полей или выражение ((dg[2]<<16) & 0x00FF0000) | ((dg[3]<<24) & 0xFF000000);; порядок элементов сохраняется. */ + ((dg[2]<<16) & 0x00FF0000) | ((dg[3]<<24) & 0xFF000000); + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Записывает addr значением readr[adr]; данные addr. */ + addr = readr[adr]; + + /* Цикл for (i=0;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for (i=0;i<4;i++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Проверяет if(addr>0x10) break; последующий оператор выполняется только при истинном условии. */ + if(addr>0x10) break; + + /* Цикл for (j=0;j<8;j++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for (j=0;j<8;j++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает bit значением Word & 1; Word >>= 1; представление регистра отдельными битовыми полями. */ + bit = Word & 1; Word >>= 1; + /* Вызывает SENDBIT с аргументами (bit) в текущей последовательности операций. */ + SENDBIT(bit); + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Записывает byt значением addr; данные byt. */ + byt = addr; + /* Цикл for (j=0;j<6;j++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for (j=0;j<6;j++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает bit значением byt & 1; byt >>= 1; представление регистра отдельными битовыми полями. */ + bit = byt & 1; byt >>= 1; + /* Вызывает SENDBIT с аргументами (bit) в текущей последовательности операций. */ + SENDBIT(bit); + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + /* Изменяет счётчик в выражении addr++; на один для следующего шага. */ + addr++; + + /* Вызывает RESET с аргументами () в текущей последовательности операций. */ + RESET(); + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} diff --git a/Bin/IndicatorTimingCompare/B_delay_after_clock_fall/kanal.c b/Bin/IndicatorTimingCompare/B_delay_after_clock_fall/kanal.c new file mode 100644 index 0000000..b89eedb --- /dev/null +++ b/Bin/IndicatorTimingCompare/B_delay_after_clock_fall/kanal.c @@ -0,0 +1,358 @@ +/* Последовательный вывод данных канала индикации. Русские пояснения сохранены в UTF-8. */ +/* Подключает "DSP2833x_Device.h": поставляемое TI описание Device для семейства C2833x. */ +#include "DSP2833x_Device.h" // DSP281x Headerfile Include File +/* Подключает "DSP2833x_SWPrioritizedIsrLevels.h": поставляемое TI описание SWPrioritizedIsrLevels для семейства C2833x. */ +#include "DSP2833x_SWPrioritizedIsrLevels.h" +/* Подключает "filter_bat2.h": накопительный фильтр измерительных каналов. */ +#include "filter_bat2.h" +/* Подключает "measure.h": обработка датчиков, вычисление величин и миллисекундный такт системы. */ +#include "measure.h" + +/* Подключает "RS485.h": приём и передача SCI-A/SCI-B, упаковка команд и FIFO первого порта. */ +#include "RS485.h" +/* Подключает "message.h": обработка Modbus, заводские параметры и сохранение настроек. */ +#include "message.h" +/* Подключает "kanal.h": последовательный вывод данных канала индикации. */ +#include "kanal.h" +/* Подключает "pulto.h": обмен и индикация пульта. */ +#include "pulto.h" +/* Подключает "package.h": адреса устройств, типы плат и псевдонимы технологических регистров. */ +#include "package.h" +/* Подключает "tools.h": настройка внешней памяти и служебные задержки. */ +#include "tools.h" + +/* Подключает "peripher.h": перемычки режима платы, дискретные входы и выходы. */ +#include "peripher.h" + +/* Объявляет digits — данные digits. Начальное значение задаётся справа от знака равенства. */ +int digits[16] = {63,6,91,79,102,109,125,7,127,111,64,0,0,0,121,0}; +/* Объявляет readr — данные readr. Начальное значение задаётся справа от знака равенства. */ +int readr[5] = {0x08,0x0C,0x10,0x00,0x04}; + +/* Ограничивает настройки таймингов компилятором TI C2000; модель на ПК не использует эти директивы. */ +#if defined(__TI_COMPILER_VERSION__) +/* Сохраняет отдельный вызов переключения CLOCK: встраивание при -O3 сокращало удержание DATA после фронта. */ +#pragma FUNC_CANNOT_INLINE(DCLK) +/* Возвращает генерацию DCLK как в образе от 06.10.2026: уровень 1 и приоритет скорости 3 сохраняют прежнюю последовательность инструкций GPIO. */ +#pragma FUNCTION_OPTIONS(DCLK, "--opt_level=1 --opt_for_speed=3") +/* Сохраняет отдельный вызов переключения DATA, чтобы длительность импульсов не зависела от встраивания в передатчик. */ +#pragma FUNC_CANNOT_INLINE(DOUT) +/* Возвращает генерацию DOUT с прежними параметрами -O1 и --opt_for_speed=3; значения взяты из старой конфигурации CCS. */ +#pragma FUNCTION_OPTIONS(DOUT, "--opt_level=1 --opt_for_speed=3") +/* Не позволяет встроить разделитель пакетов в цикл передачи и изменить интервалы между переключениями линий. */ +#pragma FUNC_CANNOT_INLINE(RESET) +/* Сохраняет прежнюю последовательность вызовов GPIO и задержек разделителя, используя настройки старого образа. */ +#pragma FUNCTION_OPTIONS(RESET, "--opt_level=1 --opt_for_speed=3") +/* Сохраняет отдельный вызов передачи бита; протокол использует порядок и интервалы фронтов CLOCK и DATA. */ +#pragma FUNC_CANNOT_INLINE(SENDBIT) +/* Возвращает передаче бита настройки старого образа -O1 и --opt_for_speed=3, оставляя остальной проект на -O3. */ +#pragma FUNCTION_OPTIONS(SENDBIT, "--opt_level=1 --opt_for_speed=3") +/* Завершает блок настроек TI, не изменяя формат пакетов и существующие счётчики задержек. */ +#endif + +/* Начинает функцию DCLK; назначение модуля — последовательный вывод данных канала индикации. */ +void DCLK(int x) +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Проверяет if(x) GpioDataRegs.GPASET.bit.GPIO6=1; последующий оператор выполняется только при истинном условии. */ + if(x) GpioDataRegs.GPASET.bit.GPIO6=1; + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else GpioDataRegs.GPACLEAR.bit.GPIO6=1; +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} + +/* Начинает функцию DOUT; назначение модуля — последовательный вывод данных канала индикации. */ +void DOUT(int x) +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Проверяет if(x) GpioDataRegs.GPASET.bit.GPIO8=1; последующий оператор выполняется только при истинном условии. */ + if(x) GpioDataRegs.GPASET.bit.GPIO8=1; + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else GpioDataRegs.GPACLEAR.bit.GPIO8=1; +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} + +/* Условие компиляции CLKMULT==1: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==1 +/* Задаёт POWS0 = 0L; данные POWS0. */ +#define POWS0 0L +/* Задаёт POWS1 = 10L; данные POWS1. */ +#define POWS1 10L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Условие компиляции CLKMULT==2: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==2 +/* Задаёт POWS0 = 0L; данные POWS0. */ +#define POWS0 0L +/* Задаёт POWS1 = 30L; данные POWS1. */ +#define POWS1 30L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Условие компиляции CLKMULT==3: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==3 +/* Задаёт POWS0 = 1L; данные POWS0. */ +#define POWS0 1L +/* Задаёт POWS1 = 50L; данные POWS1. */ +#define POWS1 50L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Условие компиляции CLKMULT==4: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==4 +/* Задаёт POWS0 = 2L; данные POWS0. */ +#define POWS0 2L +/* Задаёт POWS1 = 60L; данные POWS1. */ +#define POWS1 60L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Условие компиляции CLKMULT==5: выбранный блок включается в текущий вариант прошивки. */ +#if CLKMULT==5 +/* Задаёт POWS0 = 4L; данные POWS0. */ +#define POWS0 4L +/* Задаёт POWS1 = 80L; данные POWS1. */ +#define POWS1 80L +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif + +/* Начинает функцию RESET; назначение модуля — последовательный вывод данных канала индикации. */ +void RESET() +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Вызывает DCLK с аргументами (0) в текущей последовательности операций. */ + DCLK(0); +/* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS1>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS1); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif + /* Вызывает DOUT с аргументами (1) в текущей последовательности операций. */ + DOUT(1); +/* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS1>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS1); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif + /* Вызывает DOUT с аргументами (0) в текущей последовательности операций. */ + DOUT(0); +/* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS1>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS1); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} + +/* Начинает функцию SENDBIT; назначение модуля — последовательный вывод данных канала индикации. */ +void SENDBIT(int x) +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Выставляет передаваемый бит DATA до подъёма CLOCK, сохраняя его на протяжении высокого уровня такта. */ + DOUT(x); DCLK(1); +/* Условие компиляции POWS0>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS0>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS0) в текущей последовательности операций. */ + DSP28x_usDelay(POWS0); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif + /* Опускает CLOCK при ещё действительном DATA, чтобы сохранить передаваемый бит на отрицательном фронте такта. */ + DCLK(0); + /* Вариант B: задержка между DCLK(0) и DOUT(0) удерживает DATA после спада CLOCK; POWS0+1 — прежний счётчик циклов TI, не микросекунды. */ + DSP28x_usDelay(POWS0+1); + /* Сбрасывает DATA после завершения паузы удержания, возвращая линию к нулю перед следующим битом. */ + DOUT(0); +/* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ +#if POWS1>0 + /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS1); +/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ +#endif +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} + +/* Начинает функцию kanal_Send; назначение модуля — последовательный вывод данных канала индикации. */ +void kanal_Send(int adr, long dat, int dot) +/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ +{ + /* Объявляет Word — слово; data — данные; aliq_part — данные aliq_part; dg — данные dg. */ + long Word,data,aliq_part,dg[4]; + /* Объявляет i — данные i; j — данные j; bit — представление регистра отдельными битовыми полями; byt — данные byt; addr — данные addr. Начальное значение задаётся справа от знака равенства. */ + int i,j,bit,byt,addr,sgn=0,punkt=0,aliq_len=0,full_len, isdot=0; + + /* Проверяет if(adr>1); последующий оператор выполняется только при истинном условии. */ + if(adr>1) // Лампочки + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает Word значением dat; слово. */ + Word =dat; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else + + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Проверяет if(dat<0) sgn=1; последующий оператор выполняется только при истинном условии. */ + if(dat<0) sgn=1; + /* Записывает data значением labs(dat); данные. */ + data = labs(dat); + + /* Проверяет if(dot>=0 и dot<4) isdot = 1; последующий оператор выполняется только при истинном условии. */ + if(dot>=0 && dot<4) isdot = 1; + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else dot=0; + + /* Записывает aliq_part значением data; данные aliq_part. */ + aliq_part = data; + /* Цикл for(i=0;i0). */ + while(dat>0) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Делит dat значением 10; данные dat. */ + aliq_len++; dat/=10; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Записывает dat значением data; данные dat. */ + dat = data; + + /* Записывает full_len значением aliq_len+sgn; данные full_len. */ + full_len = aliq_len+sgn; + /* Проверяет if(full_len==0) full_len=1; последующий оператор выполняется только при истинном условии. */ + if(full_len==0) full_len=1; + /* Увеличивает full_len значением dot; данные full_len. */ + full_len += dot; + + /* Цикл for(i=0; i<(full_len-4);i++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for(i=0; i<(full_len-4);i++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Начинает цикл с проверкой условия после тела: первый проход выполняется всегда. */ + dot--; dat/=10; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + /* Проверяет if(dot<0) dot=0; последующий оператор выполняется только при истинном условии. */ + if(dot<0) dot=0; + /* Записывает punkt значением 1<0;i--); задаёт начальное значение, условие продолжения и шаг перебора. */ + for(i=3;i>0;i--) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Проверяет if((dg[i]==0) и (i!=dot)); последующий оператор выполняется только при истинном условии. */ + if((dg[i]==0)&&(i!=dot)) + /* Записывает dg[i] значением 0xF; данные dg. */ + dg[i]=0xF; // Это значит пусто + /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ + else break; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Проверяет if(sgn); последующий оператор выполняется только при истинном условии. */ + if(sgn) + /* Цикл for(i=1;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for(i=1;i<4;i++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Проверяет if( (dg[i]==0xF) или (i==3)); последующий оператор выполняется только при истинном условии. */ + if( (dg[i]==0xF)||(i==3)) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает dg[i] значением 0xA; данные dg. */ + dg[i]=0xA; // Это значит минус + /* Прерывает ближайший цикл или ветвь switch и продолжает после него. */ + break; + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } } + + /* Цикл for(i=0;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for(i=0;i<4;i++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает dg[i] значением digits[dg[i]]; данные dg. */ + dg[i] = digits[dg[i]]; + /* Проверяет if((punkt>>i)&1) dg[i]+= 128; последующий оператор выполняется только при истинном условии. */ + if((punkt>>i)&1) dg[i]+= 128; + + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Записывает Word значением ((dg[0] ) & 0x000000FF) | ((dg[1]<<8 ) & 0x0000FF00) |; слово. */ + Word = ((dg[0] ) & 0x000000FF) | ((dg[1]<<8 ) & 0x0000FF00) | + /* Продолжает список аргументов, полей или выражение ((dg[2]<<16) & 0x00FF0000) | ((dg[3]<<24) & 0xFF000000);; порядок элементов сохраняется. */ + ((dg[2]<<16) & 0x00FF0000) | ((dg[3]<<24) & 0xFF000000); + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Записывает addr значением readr[adr]; данные addr. */ + addr = readr[adr]; + + /* Цикл for (i=0;i<4;i++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for (i=0;i<4;i++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Проверяет if(addr>0x10) break; последующий оператор выполняется только при истинном условии. */ + if(addr>0x10) break; + + /* Цикл for (j=0;j<8;j++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for (j=0;j<8;j++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает bit значением Word & 1; Word >>= 1; представление регистра отдельными битовыми полями. */ + bit = Word & 1; Word >>= 1; + /* Вызывает SENDBIT с аргументами (bit) в текущей последовательности операций. */ + SENDBIT(bit); + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + + /* Записывает byt значением addr; данные byt. */ + byt = addr; + /* Цикл for (j=0;j<6;j++); задаёт начальное значение, условие продолжения и шаг перебора. */ + for (j=0;j<6;j++) + /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ + { + /* Записывает bit значением byt & 1; byt >>= 1; представление регистра отдельными битовыми полями. */ + bit = byt & 1; byt >>= 1; + /* Вызывает SENDBIT с аргументами (bit) в текущей последовательности операций. */ + SENDBIT(bit); + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } + /* Изменяет счётчик в выражении addr++; на один для следующего шага. */ + addr++; + + /* Вызывает RESET с аргументами () в текущей последовательности операций. */ + RESET(); + /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + } +/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ +} diff --git a/Bin/IndicatorTimingCompare/README.txt b/Bin/IndicatorTimingCompare/README.txt new file mode 100644 index 0000000..a735ffc --- /dev/null +++ b/Bin/IndicatorTimingCompare/README.txt @@ -0,0 +1,37 @@ +Бальзам-167: два проверочных варианта задержки индикации +Дата сборки: 12.10.2026. + +A_delay_before_clock_fall +BIN: UKSSTMS320F28335_A_delay_before_clock_fall_fa20ed0+.bin +Дополнительная задержка стоит ПЕРЕД спадом CLOCK. +Последовательность: DSP28x_usDelay(POWS0+1); DCLK(0); DOUT(0). +Назначение: продлить высокий уровень CLOCK при действительном DATA. +Размер: 32246 байт. Запас до области параметров AT25256B: 262 байта. +SHA-256: C28337E35996AED330E22BC014EF9D15D06C9A1F5CFCCCE27EAD75FB1AC565F9 + +B_delay_after_clock_fall +BIN: UKSSTMS320F28335_B_delay_after_clock_fall_fa20ed0+.bin +Дополнительная задержка стоит ПОСЛЕ спада CLOCK, МЕЖДУ DCLK(0) и DOUT(0). +Последовательность: DCLK(0); DSP28x_usDelay(POWS0+1); DOUT(0). +Назначение: удержать DATA после спада CLOCK перед сбросом линии данных. +Размер: 32248 байт. Запас до области параметров AT25256B: 260 байт. +SHA-256: 1ABA3835FFA39649E9922E107B6DBAAA2605F7C4ED80631D583973EFC2DEC215 + +В каждом варианте только одна дополнительная задержка POWS0+1. +В обоих вариантах DATA сохраняется до спада CLOCK и сбрасывается после него. +Общие условные задержки POWS0 и POWS1 и разделитель RESET сохранены. +При CLKMULT=2 значения POWS0+1=1 и POWS1=30 являются аргументами +цикловой функции TI DSP28x_usDelay, а не длительностями в микросекундах. + +Оба варианта полностью собраны TI C2000 22.6.0.LTS из текущего проекта. +Базовый коммит: fa20ed085bdca15fec47c79b72f50525653e103d; сборки помечены dirty. +Для каждого варианта при компиляции подставлен отдельный kanal.c, +сохранённый рядом с его BIN. Основной Source/Internal/kanal.c при подготовке +этой пары не изменялся. Общие параметры компиляции и прочие модули одинаковы; +паспорта также содержат собственное время сборки каждого варианта. + +Проверено: полный цикл компиляции и линковки, структура SCI8 и предел EEPROM, +соответствие итогового BIN кандидату hex2000, расположение задержек в машинном +коде SENDBIT, передача 0 и 1 на обоих фронтах в модели логических уровней, +одинаковый код DCLK/DOUT между вариантами и прежний код разделителя RESET. +Физические длительности сигналов и отсутствие строба требуют проверки на плате. diff --git a/Bin/TestLampFix/README.txt b/Bin/TestLampFix/README.txt new file mode 100644 index 0000000..5878697 --- /dev/null +++ b/Bin/TestLampFix/README.txt @@ -0,0 +1,48 @@ +Бальзам-167: проверочная прошивка с исправлением TESTLAMP +Сборка: 13.10.2026, 11:00:35 (Москва, UTC+3). + +Готовый образ: +UKSSTMS320F28335_testlamp_fix_fa20ed0+.bin +Размер: 32272 байта. Запас до параметров AT25256B: 236 байт. +SHA-256: bfe4c3c9b55bb5022f38f254929f893e5eaab57ef3d3fa31771a6b6f97f877a4 +Паспорт: UKSSTMS320F28335_testlamp_fix_fa20ed0+.bin.manifest.json +Архив этой сборки: fa20ed08+_2026-10-13_11-00-35_UTC+3. + +Исправления: +1. В get_Buttons для dsk_EPLT накопительный фильтр получает предыдущее + значение bTestLamp вместо постоянного нуля. Раньше даже один низкий + отсчёт GPIO26 при удержании кнопки сразу отключал тест, а следующий + высокий отсчёт мог снова его включить. Это переключало пакеты ламп + и семисегментных индикаторов между рабочим и тестовым режимами. + Порог 1000 по-прежнему измеряется опросами главного цикла. +2. cpu_timer1_isr_PULT ограничивает IER маской MINT13 и исключает собственный + Timer1 (INT13). Прежнее IER |= MINT13 включало дополнительные источники + вместо ограничения приоритетов и могло разрешить повторный вход Timer1. + Вложенная передача больше не может перемешать DATA/CLK, счётчик каналов + и фазу яркости. В машинном коде перед EINT проверено AND IER, #0x0139. + +Штатная тестовая последовательность what_is сохранена: цифры меняются +и тестовая маска ламп переключается каждые 500 тактов Timer1 (0,5 секунды). +Это исправление относится к частому нерегулярному мерцанию поверх теста. +Порядок уровней и задержек SENDBIT/RESET взят из текущего kanal.c проекта; +для этой сборки он не изменялся. В образ вошли уже имевшиеся правки +ecan.c, measure.c и kanal.c. + +Проверено: +- настоящие get_Buttons, er_anal, what_is и обработчик пульта в хостовой + модели при O3; короткие провалы входа при удержании TESTLAMP; +- тестовые пакеты ламп и цифр при уже включённой рабочей лампе; +- отсутствие повторного входа ISR, отпускание и удалённая команда теста; +- сохранение обычного PWM: шесть включённых тактов из десяти; +- возвращение каждой старой ошибки отдельно вызывает провал теста; +- полная компиляция и линковка TI C2000 22.6.0.LTS, O3, COFF, FPU32; +- SCI8, четыре RAM-блока, границы AT25256B и совпадение BIN с кандидатом; +- UTF-8 и русские пояснения к изменённому и добавленному коду. + +Повторная проверка: python tests/testlamp/run_test.py +Повторная сборка: python Bin/TestLampFix/rebuild.py + +На физической плате эта прошивка пока не проверена. Для проверки повторить +сценарий пользователя: включённые рабочие лампы, нажатие и удержание TESTLAMP, +затем отпускание. Штатные изменения теста раз в 0,5 секунды сохраняются; +быстрых переключений между тестовыми и рабочими показаниями быть не должно. diff --git a/Bin/TestLampFix/rebuild.py b/Bin/TestLampFix/rebuild.py new file mode 100644 index 0000000..fc919eb --- /dev/null +++ b/Bin/TestLampFix/rebuild.py @@ -0,0 +1,54 @@ +"""Полностью собирает прошивку с исправлением TESTLAMP и проверяет загрузочный BIN.""" +from pathlib import Path # Разрешает исходники, общие библиотеки и выходные файлы относительно проекта. +import json # Читает идентификатор фактически подготовленной сборки из её паспорта. +import os # Передаёт Git локальное исключение владельца репозитория без изменения глобальных настроек. +import subprocess # Запускает инструменты TI и проверку образа напрямую, без shell-подстановок. +import sys # Использует тот же Python для подготовки паспорта и штатной упаковки прошивки. + +root = Path(__file__).resolve().parents[2] # Получает корень независимо от каталога запуска скрипта. +out = root / "Bin/TestLampFix" # Изолирует новые результаты от ранее собранных и проверяемых образов. +obj, gen = out / "obj", out / "generated" # Разделяет объекты полной сборки и генерируемый паспорт. +for directory in (out, obj, gen): # Создаёт только каталоги этой сборки, сохраняя остальные артефакты. + directory.mkdir(parents=True, exist_ok=True) # Поддерживает повторную сборку без удаления файлов проекта. +ti = Path("C:/ti/ccs1230/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS") # Повторяет установленную версию компилятора из настроек CCS. +templates = root.parent / "newProject/templates" # Использует общие библиотеки и инструменты штатного проекта. +protocol = templates / "c/set-protocol" # Задаёт общую реализацию протокола УМП и порт C28x. +name = "UKSSTMS320F28335_testlamp_fix" # Отличает образ с исправлением TESTLAMP от других вариантов прошивки. +environment = dict(os.environ) # Сохраняет все существующие настройки дочерних инструментов. +git_option = int(environment.get("GIT_CONFIG_COUNT", "0")) # Добавляет локальное исключение после уже переданных параметров Git. +environment["GIT_CONFIG_COUNT"] = str(git_option + 2) # Добавляет два временных исключения владельца только для дочерних процессов сборки. +for index, repository in enumerate((root, templates), start=git_option): # Ограничивает исключения исходным проектом и его штатным репозиторием общих библиотек. + environment["GIT_CONFIG_KEY_" + str(index)] = "safe.directory" # Разрешает генератору паспорта чтение одного известного пользовательского репозитория. + environment["GIT_CONFIG_VALUE_" + str(index)] = repository.as_posix() # Использует прямые слеши, необходимые Git для сравнения safe.directory на Windows. + +def run(args): # Останавливает сборку при сбое компиляции, линковки или проверки образа. + result = subprocess.run([str(arg) for arg in args], cwd=root, env=environment, capture_output=True) # Передаёт каждый параметр отдельно и собирает диагностику инструмента. + output = (result.stdout + result.stderr).decode("utf-8", errors="replace") # Сохраняет вывод в UTF-8 даже при другой кодировке установленного инструмента. + log.write(output) # Добавляет диагностику текущего шага в общий журнал сборки. + log.flush() # Делает промежуточные результаты доступными до завершения всей сборки. + if result.returncode: # Запрещает продолжать упаковку после неуспешного шага. + raise RuntimeError(output) # Возвращает причину сбоя вместе с диагностикой инструмента. + return output # Позволяет вывести итог успешно пройденной проверки образа. + +with (out / "build.log").open("w", encoding="utf-8") as log: # Создаёт журнал только этой сборки и закрывает его при любом результате. + run([sys.executable, root / "UKSSTMS320F28335/prepare_identity.py", "--project", root / "UKSSTMS320F28335", "--templates", templates, "--output", gen]) # Формирует паспорт текущего коммита, правок и времени до компиляции. + metadata = json.loads((gen / "firmware_identity.json").read_text(encoding="utf-8")) # Читает фактический результат получения состояния обоих репозиториев. + assert metadata["source"]["commit"] and metadata["templates"]["commit"], "Не удалось получить коммиты для паспорта прошивки" # Не выдаёт проверочный образ с неизвестным происхождением исходников. + includes = [root / "UKSSTMS320F28335", root / "Source/Internal/Include", root / "Source/External/v120/DSP2833x_headers/include", root / "Source/External/v120/DSP2833x_common/include", protocol, protocol / "ports/tms320f28335", templates / "c/firmware-info/include", gen, ti / "include"] # Повторяет каталоги штатной сборки, подставляя собственный паспорт. + flags = ["-v28", "-ml", "-mt", "--float_support=fpu32", "-O3", "--opt_for_speed=0", "--define=_DEBUG", "--define=LARGE_MODEL", "-g", "--diag_warning=225", "--display_error_number", "--gen_func_subsections=on", "--abi=coffabi"] # Сохраняет C28x, модель large, FPU32, COFF и оптимизацию размера O3 из текущей конфигурации CCS. + flags += ["--include_path=" + str(path) for path in includes] # Передаёт пути компилятору отдельными аргументами без shell-экранирования. + common = root / "Source/External/v120/DSP2833x_common/source" # Выбирает используемый проектом комплект TI v120. + external = ["DSP2833x_ADC_cal.asm", "DSP2833x_Adc.c", "DSP2833x_CpuTimers.c", "DSP2833x_PieCtrl.c", "DSP2833x_SWPrioritizedDefaultIsr.c", "DSP2833x_SWPrioritizedPieVect.c", "DSP2833x_SysCtrl.c", "DSP2833x_Xintf.c", "DSP2833x_usDelay.asm"] # Повторяет штатный набор внешних модулей и цикловую задержку TI. + sources = [common / item for item in external] + [root / "Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c"] + sorted((root / "Source/Internal").glob("*.c")) # Включает все текущие исходники, в том числе имеющиеся пользовательские изменения. + for source in sources: # Полностью компилирует проект, исключая использование старых объектов CCS. + run([ti / "bin/cl2000.exe", *flags, "--obj_directory=" + str(obj), source]) # Проверяет production-код настоящим компилятором C28x. + objects = [obj / (source.stem + ".obj") for source in sources] # Передаёт линкеру только объекты завершённой текущей компиляции. + run([ti / "bin/cl2000.exe", "-v28", "-ml", "-mt", "--float_support=fpu32", "--abi=coffabi", "-z", "--map_file=" + str(out / (name + ".map")), "--stack_size=0x3f0", "--warn_sections", "-i" + str(ti / "lib"), "-i" + str(root), "-i" + str(protocol), "-i" + str(ti / "include"), "--reread_libs", "--display_error_number", "--entry_point=_c_int00", "--rom_model", "--output_file=" + str(out / (name + ".out")), root / "F28335.cmd", root / "Source/External/v120/DSP2833x_headers/cmd/DSP2833x_Headers_nonBIOS.cmd", *objects, root / "Libraries/rts2800_fpu32.lib", "-lrts2800_fpu32.lib", "-llibc.a"]) # Линкует со штатной картой памяти; 0x3f0 слов стека повторяет существующие проверочные сборки. + run([ti / "bin/hex2000.exe", "--diag_wrap=off", "--boot", "--sci8", "--binary", "-o", out / (name + ".candidate"), out / (name + ".out")]) # Формирует кандидат загрузочного образа SCI8 перед проверкой границ EEPROM. + print(run([sys.executable, root / "tests/gas167/check_image.py", out / (name + ".candidate"), "--eeprom", "AT25256B"]).strip()) # Проверяет точку входа, RAM-блоки и отсутствие пересечения с параметрами AT25256B. + print(run([sys.executable, templates / "c/firmware-info/tools/c2000_postbuild.py", "--compiler", ti, "--build-dir", out, "--artifact", name, "--metadata", gen / "firmware_identity.json", "--output", out]).strip()) # Создаёт стандартный BIN, манифест и контрольную сумму без публикации в соседний проект. + build_id = json.loads((gen / "firmware_identity.json").read_text(encoding="utf-8"))["build_id"] # Получает идентификатор именно этой полной сборки. + bin_path = out / (name + "_" + build_id + ".bin") # Выбирает готовый образ по его фактическому паспорту. + print(run([sys.executable, root / "tests/gas167/check_image.py", bin_path, "--eeprom", "AT25256B"]).strip()) # Повторяет проверку загрузочной структуры на выдаваемом BIN. + assert bin_path.read_bytes() == (out / (name + ".candidate")).read_bytes(), "Итоговый BIN отличается от проверенного кандидата" # Исключает выдачу другого образа после штатной упаковки. +print("READY:", bin_path) # Указывает точный файл прошивки, успешно прошедший все этапы. diff --git a/Bin/UKSSTMS320F28335.hex b/Bin/UKSSTMS320F28335.hex index 9fd3d046d3483c8b3ec268dd7d768340def88a0a..325c8ed61d776edcae363ae576c828b1935e8cd6 100644 GIT binary patch delta 3595 zcmb7`dr(tX8o%AT&BBz6A5ZYOb&<}$MeM{aG-H=a%Hfx`~h0rvq5SLQ2 z1R{2b3rTth)oi}ay`5Z_WW@jE%5VbLfojHXw3lyGKHt$kj!_Dca|sLD25BO`YORubV_2?D77Sf3%XWeuE|0~l z$Zoj~Um{ld8L;RVXt08q7OVvOv1@?v_pPMlyW z=PLhn524}-_o;VaH`hq1OQLkfMk8us3>6cPg}t!;#f9p%yYoCJnCh_`Ds~i?u`{At zBdQtr5+6&f!{bPN$TIozt9>cO^)HNFak$meKOo_Y6Vz+}hioENliM(hjov1Z(&q-f1RhHiT zXwiRQ(@Q%ATe9ReJ~nvkEwElY$*?yL6N!7I$Ll@lipeO}msK+plp*Cvb0x!u5uJN( zX>wzjfv;U^3=!mk_N9WX?OGzp&zcqsQaZFqkX_vi1-ZMyMUW573j|rwDiLINw^)#2 z_4vBUNM%mj|2=!cK+OiQsAlV%DmDhmI(%5((=G!lHri_N(ou4q1=X0HwH;$fM=p9l zz^t{8qGFhRNaJm zset9Ba6~r=Q8hRmh6^|XwUQixhgCa z>&V%#zyzHoNy+tTo5s*~i&>dZX_aOgdRS5fo$H&k%YL!1SMs`GC+^|)b*VO-u!&~u zo0Ky2gFP+B;d7G_Ly)D~OmItZIWqJkxZc^8CQCEQ(H*-p_=QgcTJTT$3JWBceZ@*B zS4PA@xhEnV%Ht9HAxRaHp?Jm`A32F}0db02NuO&kV;wt4QdG8suA_`4q%mp(K1Cix zosmv+T$c&LDxWk)`@)G0MF%SBSruC*>M&AjG$K;lPtj^ewL~pdi`Aaz9n@CyYG>@4 zZBA*4JdZ}AK3vhUREcT=$c5Nw^0(-5kG4T>`+|`!XT>A4iX)yzr{fH}fsC&DJ#Hh> zF&W-*r&VmBNHnEH)QrpG&+hpn#Y|*0!^V;KVnQ9_PM2KSPfRi1P65y^S#Zt}k!#vOMH`t7| zbd3f>EQ}^JrsdeU+?GnN6E2jV#5%6eROwb}_}t-F#r1qF%#aOCtm7&h7tFAat#2{z6a;94Rs~n~ke0(<&77k_OD9#P zd}M}8QO~Wd=XWtpN|Nqk6VWFh#&^j5P31 zt=*oO+u{5i%%CD!>o34bdT*Fit+J`u10wG_SQ)N}10tU~K1xQjot9mWvJsooDc%3jmxt!ht=UcEj2;0bs z&9D0LiOl~mYPPkCJJQ{B#fUTMyhJr0V3S0Z5d?0NJawBc!*`w&3o;JjRPs&6RaGIx z@YDs_gt4NXZmXoc;bk1)f_WYDI+@N4QsmfV6I|{TZ4}xc5wEO3ubcf+xOk)CfTp`q z^;+Rd22WcvvivZfCWaRt;CfP!y^_qnpe5s5T7_D_!?}Kj%_ZSm_v0RG`_>jL)pKRS z4x30;P7J=jlUB`dV<~Af7ymTMO1JmJk;dk#`C!V=4a3=_Hdl`)$+x+I^Zui1 zM>zOLw_`V4($*c(Fy#IYA^sNaTn&}}vK z@gEagte@-(#lD|(Eq?m`-R@Me1tLWaqg_MKJ$;INFT8~W=O6ZHvhbH#M+k*covD%w z`GW?&M6BoXO_Zv{R{4d)qa#bpSbAuEU&{GJ&1kk3CpEQJG;L?t5mLS<72hV8_T)I# zy-&?xYV!=gdK`&(IoK*;`A- zZAwTeYKYI_FP`fB8~aQrkwu#V_$uFF9CAp|g(1BDY&bbsv@8;bGWOvb{Jr1iU^NDB55bim+rXHX0mGQ;Yc7)-~@0P;QRBmLfe;s3)oVCgFxTB zb_&}3fH)uvc->lx&{0sHO)vwUMQ8t4e`bFsKZVUb0NS9>4WJSjo7ew4*sP)tq2)j_ zkO!0i&&DgEZ~VOeVWlwHp{M_t@AL>7Q=#q(>;mdw@Ho&5+@Ckmvk8B#TmxR*0=xlK z0U>56_(=?~@CyJIeiZt1=BBSzmt0T#hL+@x~PJ-`%H2?#o0PBG?ARWj8 UwgTILoxm`#3wR0m9e~h(0lQgOWB>pF delta 3722 zcmb7HeNa60MM~Lk#>ZKPFHo<4vxH_f5XtZb!g8}=$R$5jQ%z6_P2^hyiRGwPkm3(GWsIjk zx=%=o$!GW?`PNZPg1K#y8}~zqWq2B8xgBQ~qIPm;e4LwdXErL&<%5suSW6l<{`?jBF$ zVXb>A?S>Bb4&o>F(NoDpUp*aX2rYZX)ioq24(w%ar7@ z+*{zHily5jK^4yY(gy2P@6%~8q)Li8Zz=3QV&WIbx0sEEcP~x+8I7LUD)JV(Z4t6U z;0_^IUBPl6djfDZPk1-eWy(8zW6M1Y&-ypq4q($6_#B99k;Io@#zIdQfhc=Rw zc74rqUw8T55mw_B=($i~z3cq~<1a*#8J*0L(%1I}b8$q`62J-3lv+3YWiakq3n^{# z)V1^xEnM;cfx5t%fFOF>dLv*L!|dsTvaAh}R}5Ktv!ZC5Nv5A=lIDsWkc7t4Jctjir$aCpx}N$%(&T8G4Tj0nu{|+4gAT%v zlar)jT!J^u2=hgw7lxgulm$99pKh`iOkKv%0qdvX`BJ6x2}{&klGS{tuC|XXw=}8q7@fLFh7y((vCnrp`HJ89i`7D3E4rPrEmJHrxs!i6Jkc*gaAcx? z(q~vO*p3-9v7H$mhwaAbC~S{K@1R#f88e*@S`%V!QMv&NC*r4K+Z&&t)>KP|_Yehn=-4}I8Satx>~&^=Y_!GXIB9(v>q)(r zHl@_ZTqHfSKAq7rMNLY5Auui$yyjN;J*{&$bYz>aIf!;Q7VLY6?loq!Tp0AuO{Fp5 zk+9NrOIO1Imh*+p3C%PSeCBQSaWu*dl1ipZxT=Z{;W`akkIze@81#X}nq`SLKD*w? zw_;^Fr7h<>%|S%Os z@!Na@MeqLUrSEW~jHE)k0&XS+GEeK^VUn7j0S`7VxTl6>D)gkJn)04?M)N-5k_fxf zN+IZjpl9P6AZ)2YuCmF+9s8kb>6=Owu81X}0fb5nSXQk*%YaffG{1bFZi4lxTXE;xsZpx_ zb9{uu(MJX_=es+*Tb*(AOWQ~fLSdR;yra?0AgN*uOqHzC8B1s8I1A)!j&}93)w&%s@N59WV=Wvb@2tUJhTrdXgTt zZe8I=>0#KqVkX$L4!E2>$8s64aODnKXYE~CPvtB4BJl)AVe_gudLGQH&eAK^m9NJ$ z9T1-rg-+X$ zvjN@pSxzi2apZ`p8MAf{4mPe8)?1IRO`$>x-_4!o^$5QY@Lgj(0!R_dA#=Pw52Ie7 z|2PaU5Z(|>SG(zBQG%U0pSDN9-1Jel|~KDSWoOG?|v7D7_qe$`QnP&Qj47)r{`Mm}P9 z5`Gz3@8p@8;J0nYf4Dq8Fr|q5)xNkh<)SvJH%mv8Ya8~}u3@=OII(dN=Gi|tuJSOR zW=1Hpd_=HE1B*7LPx=3~y2#&GHX28TmleF;4YS_cG~}-OX1|QMW%A(-m*u%`mGpKR zemIrE&24_do3JfNIb30yCBqyABJOsGD4@bj_yu(J@w~{ zy+j%KsbCVb`MA|{dklm7CG9kL4A`YuzFAIN%W|K<`JJl^)phtRl1NI(wu>$JFW`@& z*hWYNVmG2w0P6S^=|jX+?8hJy5h;ia#2Um##Getn?4*!Lv7>UJF`qzJJWaS(ABQHB7-aYPlO22qb_Mz~ZE M(u(vH!j2&1e-mht)c^nh diff --git a/Source/Internal/ecan.c b/Source/Internal/ecan.c index d79fd3f..e755fbf 100644 --- a/Source/Internal/ecan.c +++ b/Source/Internal/ecan.c @@ -75,6 +75,31 @@ static unsigned int ump_can_waiting; /* Объявляет ump_can_sent_at — время последней передачи фрагмента ответа CAN. */ static unsigned long ump_can_sent_at; +/* Сбрасывает служебный обмен до включения CAN: загрузка COFF не гарантирует обнуление неинициализированной RAM. */ +static void ump_can_init(void) +/* Начинает сброс состояния; InitCan вызывается при запрещённых глобальных прерываниях. */ +{ + /* Убирает остаточный запрос, чтобы главный цикл не обрабатывал команду из RAM предыдущего запуска. */ + ump_can_pending = 0; + /* Сбрасывает идентификатор и функцию запроса; действительные значения поступят из CANa_handler. */ + ump_can_tag = 0; + /* Сбрасывает адрес запрошенного регистра до приёма новой команды. */ + ump_can_address = 0; + /* Сбрасывает прежнее значение записи или число запрошенных слов. */ + ump_can_value = 0; + /* Нулевая длина запрещает отправку старого буфера; новый запрос заполнит все доступные для передачи слова. */ + ump_can_length = 0; + /* Начинает следующий подготовленный ответ с первого слова, исключая продолжение старого фрагмента. */ + ump_can_index = 0; + /* Убирает прежний идентификатор ответа и код ошибки до подготовки новой команды. */ + ump_can_reply_tag = 0; + /* Отменяет ожидание подтверждения старой передачи, которая после включения ещё не запускалась. */ + ump_can_waiting = 0; + /* Сбрасывает отметку тайм-аута в тактах Timer1; новый фрагмент установит актуальное время отправки. */ + ump_can_sent_at = 0; +/* Завершает сброс управляющих полей; содержимое буфера недоступно при нулевой длине ответа. */ +} + /* Настраивает eCAN, скорость, почтовые ящики и маршрутизацию прерываний для выбранного режима платы. */ void InitCan(int Port, int DevNum) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ @@ -92,6 +117,9 @@ void InitCan(int Port, int DevNum) /* Объявляет id — данные id. Начальное значение задаётся справа от знака равенства. */ long id = 0x80BA0000; + /* Обнуляет состояние служебного обмена до настройки mailbox и разрешения прерываний CAN. */ + ump_can_init(); + /* Изменяет счётчик в выражении DevNum--; на один для следующего шага. */ DevNum--; /* Проверяет if(DevNum<0)DevNum=0; последующий оператор выполняется только при истинном условии. */ diff --git a/Source/Internal/kanal.c b/Source/Internal/kanal.c index c18b8dc..c303a69 100644 --- a/Source/Internal/kanal.c +++ b/Source/Internal/kanal.c @@ -148,7 +148,7 @@ void RESET() void SENDBIT(int x) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { - /* Выставляет передаваемый бит DATA до подъёма CLOCK, чтобы данные присутствовали на линии на протяжении импульса такта. */ + /* Вызывает DOUT с аргументами (x); DCLK(1) в текущей последовательности операций. */ DOUT(x); DCLK(1); /* Условие компиляции POWS0>0: выбранный блок включается в текущий вариант прошивки. */ #if POWS0>0 @@ -156,12 +156,12 @@ void SENDBIT(int x) DSP28x_usDelay(POWS0); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ #endif - /* Удерживает CLOCK высоким при действительном DATA; POWS0+1 сохраняет прежний аргумент цикловой задержки TI из SENDBIT, а не задаёт число микросекунд. */ - DSP28x_usDelay(POWS0+1); - /* Сначала опускает CLOCK при ещё действительном DATA; восстанавливает прежний порядок пользователя и сохраняет бит для приёмника, считывающего по спаду. */ - DCLK(0); - /* Сбрасывает DATA только после спада CLOCK, чтобы завершающий фронт такта не считывал принудительный ноль вместо единичного бита. */ + /* Вызывает DOUT с аргументами (0) в текущей последовательности операций. */ DOUT(0); + /* Вызывает DSP28x_usDelay с аргументами (POWS0+1) в текущей последовательности операций. */ + DSP28x_usDelay(POWS0+1); + /* Вызывает DCLK с аргументами (0) в текущей последовательности операций. */ + DCLK(0); /* Условие компиляции POWS1>0: выбранный блок включается в текущий вариант прошивки. */ #if POWS1>0 /* Вызывает DSP28x_usDelay с аргументами (POWS1) в текущей последовательности операций. */ diff --git a/Source/Internal/measure.c b/Source/Internal/measure.c index 781907c..5c3ee24 100644 --- a/Source/Internal/measure.c +++ b/Source/Internal/measure.c @@ -829,8 +829,8 @@ void Current_count(int chan) /* Записывает sens значением pow_addr + chan; данные sens. */ sens = pow_addr + chan; - /* Записывает pair значением sens_pair[chan]; данные pair. */ - pair = sens_pair[chan]; + /* Младший бит локального канала АЦП выбирает соседнюю фазу (0 <-> 1, 2 <-> 3); sens_pair хранит глобальные номера датчиков со смещением pow_addr и не подходит для индексации lev_count. */ + pair = chan ^ 1; /* Записывает ist значением !(chan & 1); данные ist. */ ist = !(chan & 1); /* Записывает feed значением (chan >>1); данные feed. */ diff --git a/Source/Internal/peripher.c b/Source/Internal/peripher.c index 7b2ddc2..28f534f 100644 --- a/Source/Internal/peripher.c +++ b/Source/Internal/peripher.c @@ -405,8 +405,8 @@ void get_Buttons() if(Desk==dsk_EPLT) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { - /* Записывает bTestLamp значением er_anal(GpioDataRegs.GPADAT.bit.GPIO26, &INcount0, 1000, 0); данные bTestLamp. */ - bTestLamp = er_anal(GpioDataRegs.GPADAT.bit.GPIO26, &INcount0, 1000, 0); + /* Сохраняет предыдущее состояние TESTLAMP, пока накопитель INcount0 не достигнет одного из порогов; 1000 — число опросов главного цикла, а не миллисекунды. Краткий провал GPIO26 больше не переключает передачу с тестовых масок на рабочие. */ + bTestLamp = er_anal(GpioDataRegs.GPADAT.bit.GPIO26, &INcount0, 1000, bTestLamp); /* Проверяет if(GpioDataRegs.GPADAT.bit.GPIO27) butt +=0x0001; последующий оператор выполняется только при истинном условии. */ if(GpioDataRegs.GPADAT.bit.GPIO27) butt +=0x0001; diff --git a/Source/Internal/pulto.c b/Source/Internal/pulto.c index e880d61..f2ee6a3 100644 --- a/Source/Internal/pulto.c +++ b/Source/Internal/pulto.c @@ -75,8 +75,8 @@ interrupt void cpu_timer1_isr_PULT(void) EALLOW; /* Изменяет счётчик в выражении CpuTimer1.InterruptCount++; на один для следующего шага. */ CpuTimer1.InterruptCount++; - /* Устанавливает биты IER значением MINT13; регистр разрешения прерываний ядра C28x. */ - IER |= MINT13; // Set "global" priority + /* Оставляет только ранее разрешённые источники более высокого приоритета по маске TI MINT13 и запрещает повторный Timer1 через M_INT13 (бит 12 IER); вложенная передача не должна перемешивать фронты DATA/CLK и менять фазу яркости. IRET восстановит маску вызывающего кода. */ + IER &= (MINT13 & ~M_INT13); /* Разрешение маскируемых прерываний ядра. */ EINT; /* Закрытие доступа к защищённым регистрам периферии. */ diff --git a/UKSSTMS320F28335.map b/UKSSTMS320F28335.map index 453404f..583ba78 100644 --- a/UKSSTMS320F28335.map +++ b/UKSSTMS320F28335.map @@ -1,10 +1,10 @@ ****************************************************************************** TMS320C2000 Linker PC v22.6.0 ****************************************************************************** ->> Linked Mon Oct 12 18:16:05 2026 +>> Linked Tue Oct 13 14:10:06 2026 OUTPUT FILE NAME: -ENTRY POINT SYMBOL: "_c_int00" address: 0000a8cd +ENTRY POINT SYMBOL: "_c_int00" address: 0000a8d9 MEMORY CONFIGURATION @@ -13,7 +13,7 @@ MEMORY CONFIGURATION ---------------------- -------- --------- -------- -------- ---- -------- PAGE 0: ZONE0 00004000 00001000 00000000 00001000 RWIX - RAML0 00008000 00004000 00003afd 00000503 RWIX + RAML0 00008000 00004000 00003b0a 000004f6 RWIX RAML4 0000c000 00001000 000003e6 00000c1a RWIX ZONE6 00100000 00100000 00000000 00100000 RWIX FLASHH 00300000 00008000 00000000 00008000 RWIX @@ -126,12 +126,12 @@ section page origin length input sections .pinit 0 00008000 00000000 UNINITIALIZED -.text 0 00008000 00003afd - 00008000 0000025a measure.obj (.text:_Current_count) - 0000825a 000001dd ADC.obj (.text:_adc_isr) - 00008437 000001a7 measure.obj (.text:_Temper_count) - 000085de 000001a6 main.obj (.text:_main) - 00008784 000001a3 peripher.obj (.text:_get_Buttons) +.text 0 00008000 00003b0a + 00008000 00000257 measure.obj (.text:_Current_count) + 00008257 000001dd ADC.obj (.text:_adc_isr) + 00008434 000001a7 measure.obj (.text:_Temper_count) + 000085db 000001a6 peripher.obj (.text:_get_Buttons) + 00008781 000001a6 main.obj (.text:_main) 00008927 0000018d ADC.obj (.text:_setup_adc) 00008ab4 00000184 measure.obj (.text:_cpu_timer1_isr_SENS) 00008c38 0000015f RS485.obj (.text:_RS_RX_Handler) @@ -144,214 +144,214 @@ section page origin length input sections 000094a1 000000f9 measure.obj (.text:_Power_count) 0000959a 000000ec message.obj (.text:_Default_params) 00009686 000000e5 RS485.obj (.text:_setup_uart) - 0000976b 000000b3 log_to_mem.obj (.text:_ump_log_read) - 0000981e 000000ae measure.obj (.text:_calc_sensor_koef) - 000098cc 000000ac ecan.obj (.text:_InitCan) - 00009978 000000a8 ecan.obj (.text:_UMP_CAN_service) - 00009a20 0000009d message.obj (.text:_ReceiveCommandModbus3) - 00009abd 0000009c peripher.obj (.text:_select_tpl_canal) - 00009b59 00000097 bios.obj (.text:_upload) - 00009bf0 00000094 measure.obj (.text:_Init_packMask) - 00009c84 00000092 RS485.obj (.text:_RS_FifoTx) - 00009d16 0000008c message.obj (.text:_receive_ump) - 00009da2 0000008a log_to_mem.obj (.text:_ump_capture) - 00009e2c 00000088 rts2800_fpu32.lib : fs_div.obj (.text) - 00009eb4 00000085 DSP2833x_SysCtrl.obj (.text:_InitPeripheralClocks) - 00009f39 00000084 bios.obj (.text:_extendbios) - 00009fbd 00000001 bios.obj (.text:_init) - 00009fbe 00000083 shared_ump.obj (.text:_ump_rtu_encode) - 0000a041 00000082 DSP2833x_SysCtrl.obj (.text:_InitPll) - 0000a0c3 00000078 bios.obj (.text:_peek) - 0000a13b 00000072 ecan.obj (.text:_Handlai) - 0000a1ad 00000071 shared_ump.obj (.text:_ump_validate) - 0000a21e 00000070 log_to_mem.obj (.text:_ump_log_write) - 0000a28e 0000006e RS485.obj (.text:_RS_TX_Handler) - 0000a2fc 00000069 DAC.obj (.text:_Load_protection_prepare) - 0000a365 00000062 measure.obj (.text:_Init_sensors_more) - 0000a3c7 00000059 DSP2833x_Xintf.obj (.text:_InitXintf16Gpio) - 0000a420 00000057 bios.obj (.text:_get_command) - 0000a477 00000050 message.obj (.text:_ReceiveCommandModbus6) - 0000a4c7 0000004f RS485.obj (.text:_RS_FifoStart) - 0000a516 0000004e DAC.obj (.text:_anal_output) - 0000a564 0000004e DAC.obj (.text:_load_start) - 0000a5b2 0000004d shared_ump.obj (.text:_ump_prepare) - 0000a5ff 0000004b RS485.obj (.text:_RS_Send) - 0000a64a 0000004a ecan.obj (.text:_CANa_handler) - 0000a694 00000049 RS485.obj (.text:_RS_FifoAbort) - 0000a6dd 00000049 bios.obj (.text:_load) - 0000a726 00000048 ecan.obj (.text:_CAN_send) - 0000a76e 00000047 bios.obj (.text:_initload) - 0000a7b5 00000046 RS485.obj (.text:_RSA_RX_Handler) - 0000a7fb 00000046 RS485.obj (.text:_RSA_TX_Handler) - 0000a841 00000046 RS485.obj (.text:_RSB_RX_Handler) - 0000a887 00000046 RS485.obj (.text:_RSB_TX_Handler) - 0000a8cd 00000046 rts2800_fpu32.lib : boot.obj (.text) - 0000a913 00000042 log_to_mem.obj (.text:_ump_log_can) - 0000a955 00000041 spise2p.obj (.text:_Seeprom_read) - 0000a996 00000041 spise2p.obj (.text:_Seeprom_write) - 0000a9d7 00000041 RS485.obj (.text:_setup_arr_cmd_length) - 0000aa18 00000040 message.obj (.text:_Load_params) - 0000aa58 0000003e RS485.obj (.text:_RS_SetLineSpeed) - 0000aa96 0000003e tools.obj (.text:_init_zone7) - 0000aad4 0000003b DSP2833x_CpuTimers.obj (.text:_InitCpuTimers) - 0000ab0f 0000003b DAC.obj (.text:_Load_voltage_can) - 0000ab4a 0000003b shared_ump.obj (.text:_ump_can_fragment) - 0000ab85 0000003a bios.obj (.text:_poke) - 0000abbf 00000039 spise2p.obj (.text:_cpu_timer2_isr) - 0000abf8 00000038 message.obj (.text:_SendCommandModbus4) - 0000ac30 00000038 shared_ump.obj (.text:_ump_tms28335_fragment) - 0000ac68 00000037 RS485.obj (.text:_RS_BSend) - 0000ac9f 00000001 bios.obj (.text:_run) - 0000aca0 00000037 message.obj (.text:_ReceiveAnswerModbus4) - 0000acd7 00000033 bios.obj (.text:_Answer) - 0000ad0a 00000033 message.obj (.text:_modbus_exception) - 0000ad3d 00000033 log_to_mem.obj (.text:_ump_word) - 0000ad70 00000032 spise2p.obj (.text:_SPISE2P_DRV_init) - 0000ada2 00000032 peripher.obj (.text:_unsetup_leds_line) - 0000add4 00000031 DAC.obj (.text:_dSEND) - 0000ae05 0000002f RS485.obj (.text:_RS_FifoTick1ms) - 0000ae34 0000002e filter_bat2.obj (.text:_filterbat) - 0000ae62 0000002e log_to_mem.obj (.text:_ump_log_io) - 0000ae90 0000002d RS485.obj (.text:_RS_SetLineMode) - 0000aebd 0000002d main.obj (.text:_timer_Init) - 0000aeea 0000002c crc16.obj (.text:_get_crc_16b) - 0000af16 0000002b ecan.obj (.text:_CANa_reset_err) - 0000af41 0000002a rts2800_fpu32.lib : l_div.obj (.text) - 0000af6b 00000029 spise2p.obj (.text:_InitSeeprom) - 0000af94 00000027 crc16.obj (.text:_get_crc16) - 0000afbb 00000024 message.obj (.text:_Save_params) - 0000afdf 00000024 DAC.obj (.text:_load_stop) - 0000b003 00000024 peripher.obj (.text:_select_tpl_255) - 0000b027 00000022 peripher.obj (.text:_setup_leds_line) - 0000b049 00000021 DSP2833x_CpuTimers.obj (.text:_ConfigCpuTimer) - 0000b06a 00000020 DAC.obj (.text:_Setup_DAC_time) - 0000b08a 00000020 rts2800_fpu32.lib : sqrt.obj (.text) - 0000b0aa 0000001f DSP2833x_PieCtrl.obj (.text:_InitPieCtrl) - 0000b0c9 0000001f measure.obj (.text:_reset_errs) - 0000b0e8 0000001e DAC.obj (.text:_Load_control_init) - 0000b106 0000001d log_to_mem.obj (.text:_ump_log_init) - 0000b123 0000001d shared_ump.obj (.text:_ump_tms28335_prepare) - 0000b140 0000001d pulto.obj (.text:_what_is) - 0000b15d 0000001c DAC.obj (.text:_Init_DAC) - 0000b179 0000001c measure.obj (.text:_im_calc) - 0000b195 0000001c shared_ump.obj (.text:_ump_crc) - 0000b1b1 0000001c shared_ump.obj (.text:_ump_tms28335_capture) - 0000b1cd 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ADCINT_ISR) - 0000b1e8 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH1_ISR) - 0000b203 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH2_ISR) - 0000b21e 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH3_ISR) - 0000b239 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH4_ISR) - 0000b254 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH5_ISR) - 0000b26f 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH6_ISR) - 0000b28a 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN0INTA_ISR) - 0000b2a5 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN0INTB_ISR) - 0000b2c0 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN1INTA_ISR) - 0000b2db 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN1INTB_ISR) - 0000b2f6 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP1_INT_ISR) - 0000b311 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP2_INT_ISR) - 0000b32c 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP3_INT_ISR) - 0000b347 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP4_INT_ISR) - 0000b362 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP5_INT_ISR) - 0000b37d 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP6_INT_ISR) - 0000b398 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM1_INT_ISR) - 0000b3b3 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM1_TZINT_ISR) - 0000b3ce 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM2_INT_ISR) - 0000b3e9 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM2_TZINT_ISR) - 0000b404 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM3_INT_ISR) - 0000b41f 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM3_TZINT_ISR) - 0000b43a 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM4_INT_ISR) - 0000b455 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM4_TZINT_ISR) - 0000b470 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM5_INT_ISR) - 0000b48b 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM5_TZINT_ISR) - 0000b4a6 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM6_INT_ISR) - 0000b4c1 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM6_TZINT_ISR) - 0000b4dc 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EQEP1_INT_ISR) - 0000b4f7 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EQEP2_INT_ISR) - 0000b512 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_I2CINT1A_ISR) - 0000b52d 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_I2CINT2A_ISR) - 0000b548 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_LUF_ISR) - 0000b563 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_LVF_ISR) - 0000b57e 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MRINTA_ISR) - 0000b599 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MRINTB_ISR) - 0000b5b4 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MXINTA_ISR) - 0000b5cf 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MXINTB_ISR) - 0000b5ea 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTA_ISR) - 0000b605 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTB_ISR) - 0000b620 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTC_ISR) - 0000b63b 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTA_ISR) - 0000b656 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTB_ISR) - 0000b671 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTC_ISR) - 0000b68c 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SEQ1INT_ISR) - 0000b6a7 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SEQ2INT_ISR) - 0000b6c2 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SPIRXINTA_ISR) - 0000b6dd 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SPITXINTA_ISR) - 0000b6f8 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_TINT0_ISR) - 0000b713 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_WAKEINT_ISR) - 0000b72e 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT3_ISR) - 0000b749 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT4_ISR) - 0000b764 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT5_ISR) - 0000b77f 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT6_ISR) - 0000b79a 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT7_ISR) - 0000b7b5 0000001b rts2800_fpu32.lib : args_main.obj (.text) - 0000b7d0 0000001a RS485.obj (.text:_RS_SetBitMode) - 0000b7ea 0000001a RS485.obj (.text:_create_uart_vars) - 0000b804 00000019 DSP2833x_Adc.obj (.text:_InitAdc) - 0000b81d 00000019 DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT1_ISR) - 0000b836 00000019 DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT2_ISR) - 0000b84f 00000019 rts2800_fpu32.lib : exit.obj (.text) - 0000b868 00000019 : prolog.obj (.text) - 0000b881 00000018 log_to_mem.obj (.text:_ump_log_tick) - 0000b899 00000017 log_to_mem.obj (.text:_clear_mem) - 0000b8b0 00000016 DSP2833x_SysCtrl.obj (.text:_ServiceDog) - 0000b8c6 00000014 bios.obj (.text:__getbyte) - 0000b8da 00000014 measure.obj (.text:_er_anal) - 0000b8ee 00000014 log_to_mem.obj (.text:_ump_outputs) - 0000b902 00000013 kanal.obj (.text:_RESET) - 0000b915 00000013 RS485.obj (.text:_RS_FifoWait) - 0000b928 00000013 log_to_mem.obj (.text:_ump_inputs) - 0000b93b 00000012 crc16.obj (.text:_get_crc_16) - 0000b94d 00000011 kanal.obj (.text:_SENDBIT) - 0000b95e 00000010 tools.obj (.text:_pause_us) - 0000b96e 00000010 shared_ump.obj (.text:_read_word) - 0000b97e 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DATALOG_ISR) - 0000b98b 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT13_ISR) - 0000b998 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT14_ISR) - 0000b9a5 0000000d DSP2833x_SWPrioritizedPieVect.obj (.text:_InitPieVectTable) - 0000b9b2 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_RTOSINT_ISR) - 0000b9bf 0000000c kanal.obj (.text:_DCLK) - 0000b9cb 0000000c kanal.obj (.text:_DOUT) - 0000b9d7 0000000c rts2800_fpu32.lib : epilog.obj (.text) - 0000b9e3 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EMUINT_ISR) - 0000b9ee 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ILLEGAL_ISR) - 0000b9f9 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_NMI_ISR) - 0000ba04 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER10_ISR) - 0000ba0f 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER11_ISR) - 0000ba1a 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER12_ISR) - 0000ba25 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER1_ISR) - 0000ba30 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER2_ISR) - 0000ba3b 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER3_ISR) - 0000ba46 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER4_ISR) - 0000ba51 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER5_ISR) - 0000ba5c 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER6_ISR) - 0000ba67 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER7_ISR) - 0000ba72 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER8_ISR) - 0000ba7d 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER9_ISR) - 0000ba88 0000000b log_to_mem.obj (.text:_ump_log_rs) - 0000ba93 0000000b rts2800_fpu32.lib : u_div.obj (.text) - 0000ba9e 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT_NOTUSED_ISR) - 0000baa8 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_PIE_RESERVED) - 0000bab2 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_rsvd_ISR) - 0000babc 00000009 DSP2833x_PieCtrl.obj (.text:_EnableInterrupts) - 0000bac5 00000009 DSP2833x_SysCtrl.obj (.text:_InitSysCtrl) - 0000bace 00000009 rts2800_fpu32.lib : _lock.obj (.text) - 0000bad7 00000008 DSP2833x_SysCtrl.obj (.text:_DisableDog) - 0000badf 00000007 rts2800_fpu32.lib : memset.obj (.text) - 0000bae6 00000005 spise2p.obj (.text:_SPISE2P_DRV_csclr) - 0000baeb 00000005 spise2p.obj (.text:_SPISE2P_DRV_csset) - 0000baf0 00000005 cntrl_adr.obj (.text:_set_cntrl_addr) - 0000baf5 00000004 DSP2833x_usDelay.obj (.text) - 0000baf9 00000003 shared_ump.obj (.text:_write_word) - 0000bafc 00000001 bios.obj (.text:_tflash) + 0000976b 000000b8 ecan.obj (.text:_InitCan) + 00009823 000000b3 log_to_mem.obj (.text:_ump_log_read) + 000098d6 000000ae measure.obj (.text:_calc_sensor_koef) + 00009984 000000a8 ecan.obj (.text:_UMP_CAN_service) + 00009a2c 0000009d message.obj (.text:_ReceiveCommandModbus3) + 00009ac9 0000009c peripher.obj (.text:_select_tpl_canal) + 00009b65 00000097 bios.obj (.text:_upload) + 00009bfc 00000094 measure.obj (.text:_Init_packMask) + 00009c90 00000092 RS485.obj (.text:_RS_FifoTx) + 00009d22 0000008c message.obj (.text:_receive_ump) + 00009dae 0000008a log_to_mem.obj (.text:_ump_capture) + 00009e38 00000088 rts2800_fpu32.lib : fs_div.obj (.text) + 00009ec0 00000085 DSP2833x_SysCtrl.obj (.text:_InitPeripheralClocks) + 00009f45 00000084 bios.obj (.text:_extendbios) + 00009fc9 00000001 bios.obj (.text:_init) + 00009fca 00000083 shared_ump.obj (.text:_ump_rtu_encode) + 0000a04d 00000082 DSP2833x_SysCtrl.obj (.text:_InitPll) + 0000a0cf 00000078 bios.obj (.text:_peek) + 0000a147 00000072 ecan.obj (.text:_Handlai) + 0000a1b9 00000071 shared_ump.obj (.text:_ump_validate) + 0000a22a 00000070 log_to_mem.obj (.text:_ump_log_write) + 0000a29a 0000006e RS485.obj (.text:_RS_TX_Handler) + 0000a308 00000069 DAC.obj (.text:_Load_protection_prepare) + 0000a371 00000062 measure.obj (.text:_Init_sensors_more) + 0000a3d3 00000059 DSP2833x_Xintf.obj (.text:_InitXintf16Gpio) + 0000a42c 00000057 bios.obj (.text:_get_command) + 0000a483 00000050 message.obj (.text:_ReceiveCommandModbus6) + 0000a4d3 0000004f RS485.obj (.text:_RS_FifoStart) + 0000a522 0000004e DAC.obj (.text:_anal_output) + 0000a570 0000004e DAC.obj (.text:_load_start) + 0000a5be 0000004d shared_ump.obj (.text:_ump_prepare) + 0000a60b 0000004b RS485.obj (.text:_RS_Send) + 0000a656 0000004a ecan.obj (.text:_CANa_handler) + 0000a6a0 00000049 RS485.obj (.text:_RS_FifoAbort) + 0000a6e9 00000049 bios.obj (.text:_load) + 0000a732 00000048 ecan.obj (.text:_CAN_send) + 0000a77a 00000047 bios.obj (.text:_initload) + 0000a7c1 00000046 RS485.obj (.text:_RSA_RX_Handler) + 0000a807 00000046 RS485.obj (.text:_RSA_TX_Handler) + 0000a84d 00000046 RS485.obj (.text:_RSB_RX_Handler) + 0000a893 00000046 RS485.obj (.text:_RSB_TX_Handler) + 0000a8d9 00000046 rts2800_fpu32.lib : boot.obj (.text) + 0000a91f 00000042 log_to_mem.obj (.text:_ump_log_can) + 0000a961 00000041 spise2p.obj (.text:_Seeprom_read) + 0000a9a2 00000041 spise2p.obj (.text:_Seeprom_write) + 0000a9e3 00000041 RS485.obj (.text:_setup_arr_cmd_length) + 0000aa24 00000040 message.obj (.text:_Load_params) + 0000aa64 0000003e RS485.obj (.text:_RS_SetLineSpeed) + 0000aaa2 0000003e tools.obj (.text:_init_zone7) + 0000aae0 0000003b DSP2833x_CpuTimers.obj (.text:_InitCpuTimers) + 0000ab1b 0000003b DAC.obj (.text:_Load_voltage_can) + 0000ab56 0000003b shared_ump.obj (.text:_ump_can_fragment) + 0000ab91 0000003a bios.obj (.text:_poke) + 0000abcb 00000039 spise2p.obj (.text:_cpu_timer2_isr) + 0000ac04 00000038 message.obj (.text:_SendCommandModbus4) + 0000ac3c 00000038 shared_ump.obj (.text:_ump_tms28335_fragment) + 0000ac74 00000037 RS485.obj (.text:_RS_BSend) + 0000acab 00000001 bios.obj (.text:_run) + 0000acac 00000037 message.obj (.text:_ReceiveAnswerModbus4) + 0000ace3 00000033 bios.obj (.text:_Answer) + 0000ad16 00000033 message.obj (.text:_modbus_exception) + 0000ad49 00000033 log_to_mem.obj (.text:_ump_word) + 0000ad7c 00000032 spise2p.obj (.text:_SPISE2P_DRV_init) + 0000adae 00000032 peripher.obj (.text:_unsetup_leds_line) + 0000ade0 00000031 DAC.obj (.text:_dSEND) + 0000ae11 0000002f RS485.obj (.text:_RS_FifoTick1ms) + 0000ae40 0000002e filter_bat2.obj (.text:_filterbat) + 0000ae6e 0000002e log_to_mem.obj (.text:_ump_log_io) + 0000ae9c 0000002d RS485.obj (.text:_RS_SetLineMode) + 0000aec9 0000002d main.obj (.text:_timer_Init) + 0000aef6 0000002c crc16.obj (.text:_get_crc_16b) + 0000af22 0000002b ecan.obj (.text:_CANa_reset_err) + 0000af4d 0000002a rts2800_fpu32.lib : l_div.obj (.text) + 0000af77 00000029 spise2p.obj (.text:_InitSeeprom) + 0000afa0 00000027 crc16.obj (.text:_get_crc16) + 0000afc7 00000024 message.obj (.text:_Save_params) + 0000afeb 00000024 DAC.obj (.text:_load_stop) + 0000b00f 00000024 peripher.obj (.text:_select_tpl_255) + 0000b033 00000022 peripher.obj (.text:_setup_leds_line) + 0000b055 00000021 DSP2833x_CpuTimers.obj (.text:_ConfigCpuTimer) + 0000b076 00000020 DAC.obj (.text:_Setup_DAC_time) + 0000b096 00000020 rts2800_fpu32.lib : sqrt.obj (.text) + 0000b0b6 0000001f DSP2833x_PieCtrl.obj (.text:_InitPieCtrl) + 0000b0d5 0000001f measure.obj (.text:_reset_errs) + 0000b0f4 0000001e DAC.obj (.text:_Load_control_init) + 0000b112 0000001d log_to_mem.obj (.text:_ump_log_init) + 0000b12f 0000001d shared_ump.obj (.text:_ump_tms28335_prepare) + 0000b14c 0000001d pulto.obj (.text:_what_is) + 0000b169 0000001c DAC.obj (.text:_Init_DAC) + 0000b185 0000001c measure.obj (.text:_im_calc) + 0000b1a1 0000001c shared_ump.obj (.text:_ump_crc) + 0000b1bd 0000001c shared_ump.obj (.text:_ump_tms28335_capture) + 0000b1d9 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ADCINT_ISR) + 0000b1f4 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH1_ISR) + 0000b20f 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH2_ISR) + 0000b22a 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH3_ISR) + 0000b245 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH4_ISR) + 0000b260 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH5_ISR) + 0000b27b 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH6_ISR) + 0000b296 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN0INTA_ISR) + 0000b2b1 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN0INTB_ISR) + 0000b2cc 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN1INTA_ISR) + 0000b2e7 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN1INTB_ISR) + 0000b302 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP1_INT_ISR) + 0000b31d 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP2_INT_ISR) + 0000b338 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP3_INT_ISR) + 0000b353 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP4_INT_ISR) + 0000b36e 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP5_INT_ISR) + 0000b389 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP6_INT_ISR) + 0000b3a4 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM1_INT_ISR) + 0000b3bf 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM1_TZINT_ISR) + 0000b3da 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM2_INT_ISR) + 0000b3f5 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM2_TZINT_ISR) + 0000b410 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM3_INT_ISR) + 0000b42b 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM3_TZINT_ISR) + 0000b446 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM4_INT_ISR) + 0000b461 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM4_TZINT_ISR) + 0000b47c 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM5_INT_ISR) + 0000b497 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM5_TZINT_ISR) + 0000b4b2 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM6_INT_ISR) + 0000b4cd 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM6_TZINT_ISR) + 0000b4e8 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EQEP1_INT_ISR) + 0000b503 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EQEP2_INT_ISR) + 0000b51e 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_I2CINT1A_ISR) + 0000b539 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_I2CINT2A_ISR) + 0000b554 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_LUF_ISR) + 0000b56f 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_LVF_ISR) + 0000b58a 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MRINTA_ISR) + 0000b5a5 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MRINTB_ISR) + 0000b5c0 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MXINTA_ISR) + 0000b5db 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MXINTB_ISR) + 0000b5f6 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTA_ISR) + 0000b611 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTB_ISR) + 0000b62c 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTC_ISR) + 0000b647 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTA_ISR) + 0000b662 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTB_ISR) + 0000b67d 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTC_ISR) + 0000b698 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SEQ1INT_ISR) + 0000b6b3 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SEQ2INT_ISR) + 0000b6ce 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SPIRXINTA_ISR) + 0000b6e9 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SPITXINTA_ISR) + 0000b704 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_TINT0_ISR) + 0000b71f 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_WAKEINT_ISR) + 0000b73a 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT3_ISR) + 0000b755 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT4_ISR) + 0000b770 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT5_ISR) + 0000b78b 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT6_ISR) + 0000b7a6 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT7_ISR) + 0000b7c1 0000001b rts2800_fpu32.lib : args_main.obj (.text) + 0000b7dc 0000001a RS485.obj (.text:_RS_SetBitMode) + 0000b7f6 0000001a RS485.obj (.text:_create_uart_vars) + 0000b810 00000019 DSP2833x_Adc.obj (.text:_InitAdc) + 0000b829 00000019 DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT1_ISR) + 0000b842 00000019 DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT2_ISR) + 0000b85b 00000019 rts2800_fpu32.lib : exit.obj (.text) + 0000b874 00000019 : prolog.obj (.text) + 0000b88d 00000018 log_to_mem.obj (.text:_ump_log_tick) + 0000b8a5 00000017 log_to_mem.obj (.text:_clear_mem) + 0000b8bc 00000016 DSP2833x_SysCtrl.obj (.text:_ServiceDog) + 0000b8d2 00000014 bios.obj (.text:__getbyte) + 0000b8e6 00000014 measure.obj (.text:_er_anal) + 0000b8fa 00000014 log_to_mem.obj (.text:_ump_outputs) + 0000b90e 00000013 kanal.obj (.text:_RESET) + 0000b921 00000013 RS485.obj (.text:_RS_FifoWait) + 0000b934 00000013 log_to_mem.obj (.text:_ump_inputs) + 0000b947 00000012 kanal.obj (.text:_SENDBIT) + 0000b959 00000012 crc16.obj (.text:_get_crc_16) + 0000b96b 00000010 tools.obj (.text:_pause_us) + 0000b97b 00000010 shared_ump.obj (.text:_read_word) + 0000b98b 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DATALOG_ISR) + 0000b998 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT13_ISR) + 0000b9a5 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT14_ISR) + 0000b9b2 0000000d DSP2833x_SWPrioritizedPieVect.obj (.text:_InitPieVectTable) + 0000b9bf 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_RTOSINT_ISR) + 0000b9cc 0000000c kanal.obj (.text:_DCLK) + 0000b9d8 0000000c kanal.obj (.text:_DOUT) + 0000b9e4 0000000c rts2800_fpu32.lib : epilog.obj (.text) + 0000b9f0 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EMUINT_ISR) + 0000b9fb 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ILLEGAL_ISR) + 0000ba06 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_NMI_ISR) + 0000ba11 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER10_ISR) + 0000ba1c 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER11_ISR) + 0000ba27 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER12_ISR) + 0000ba32 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER1_ISR) + 0000ba3d 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER2_ISR) + 0000ba48 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER3_ISR) + 0000ba53 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER4_ISR) + 0000ba5e 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER5_ISR) + 0000ba69 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER6_ISR) + 0000ba74 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER7_ISR) + 0000ba7f 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER8_ISR) + 0000ba8a 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER9_ISR) + 0000ba95 0000000b log_to_mem.obj (.text:_ump_log_rs) + 0000baa0 0000000b rts2800_fpu32.lib : u_div.obj (.text) + 0000baab 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT_NOTUSED_ISR) + 0000bab5 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_PIE_RESERVED) + 0000babf 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_rsvd_ISR) + 0000bac9 00000009 DSP2833x_PieCtrl.obj (.text:_EnableInterrupts) + 0000bad2 00000009 DSP2833x_SysCtrl.obj (.text:_InitSysCtrl) + 0000badb 00000009 rts2800_fpu32.lib : _lock.obj (.text) + 0000bae4 00000008 DSP2833x_SysCtrl.obj (.text:_DisableDog) + 0000baec 00000007 rts2800_fpu32.lib : memset.obj (.text) + 0000baf3 00000005 spise2p.obj (.text:_SPISE2P_DRV_csclr) + 0000baf8 00000005 spise2p.obj (.text:_SPISE2P_DRV_csset) + 0000bafd 00000005 cntrl_adr.obj (.text:_set_cntrl_addr) + 0000bb02 00000004 DSP2833x_usDelay.obj (.text) + 0000bb06 00000003 shared_ump.obj (.text:_write_word) + 0000bb09 00000001 bios.obj (.text:_tflash) ramfuncs 0 0000c000 00000000 UNINITIALIZED @@ -658,25 +658,25 @@ MODULE SUMMARY K:\git_project\Balsam_167_periph\Debug\Source\Internal\ log_to_mem.obj 718 52 64034 - measure.obj 2458 87 1212 + measure.obj 2455 87 1212 RS485.obj 1688 8 1878 message.obj 875 82 446 - peripher.obj 972 32 16 + peripher.obj 975 32 16 ADC.obj 874 13 74 DAC.obj 843 0 24 - ecan.obj 643 28 148 + ecan.obj 655 28 148 bios.obj 766 4 1 spise2p.obj 578 71 28 crc16.obj 101 259 256 shared_ump.obj 540 24 0 main.obj 467 0 5 pulto.obj 352 17 10 - kanal.obj 327 27 21 + kanal.obj 328 27 21 tools.obj 78 0 0 filter_bat2.obj 46 0 0 cntrl_adr.obj 5 11 4 +--+--------------------------------------+-------+------------------+--------------------+ - Total: 12331 715 68157 + Total: 12344 715 68157 K:/git_project/Balsam_167_periph/Libraries/rts2800_fpu32.lib fs_div.obj 136 0 0 @@ -696,7 +696,7 @@ MODULE SUMMARY Stack: 0 0 1008 +--+--------------------------------------+-------+------------------+--------------------+ - Grand Total: 15108 995 71883 + Grand Total: 15121 995 71883 GLOBAL DATA SYMBOLS: SORTED BY DATA PAGE @@ -941,15 +941,15 @@ GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name page address name ---- ------- ---- 0 00008000 .text -0 0000b84f C$$EXIT -0 00009e2c FS$$DIV -0 0000af41 L$$DIV -0 0000af50 L$$MOD -0 0000ba93 U$$DIV -0 0000ba98 U$$MOD -0 0000af5e UL$$DIV -0 0000af65 UL$$MOD -0 0000b1cd _ADCINT_ISR +0 0000b85b C$$EXIT +0 00009e38 FS$$DIV +0 0000af4d L$$DIV +0 0000af5c L$$MOD +0 0000baa0 U$$DIV +0 0000baa5 U$$MOD +0 0000af6a UL$$DIV +0 0000af71 UL$$MOD +0 0000b1d9 _ADCINT_ISR 0 00380080 _ADC_cal 1 0000df06 _ADC_table 0 0000c39c _ADDR_ANSWER @@ -957,10 +957,10 @@ page address name 0 0000c39d _ADDR_TERMINAL 1 00000b00 _AdcMirror 1 00007100 _AdcRegs -0 0000acd7 _Answer -0 0000a726 _CAN_send -0 0000a64a _CANa_handler -0 0000af16 _CANa_reset_err +0 0000ace3 _Answer +0 0000a732 _CAN_send +0 0000a656 _CANa_handler +0 0000af22 _CANa_reset_err 1 0000de3d _CNTRL_ADDR 0 0000c39e _CNTRL_ADDR_UNIVERSAL 1 0000dfb5 _COUNT_DISCHARGE @@ -970,7 +970,7 @@ page address name 1 0000dd03 _CanGO 1 0000dd02 _CanPowse 1 0000e000 _CanTimeOutErrorTR -0 0000b049 _ConfigCpuTimer +0 0000b055 _ConfigCpuTimer 1 0000df9c _CpuTimer0 1 00000c00 _CpuTimer0Regs 1 0000dfa4 _CpuTimer1 @@ -981,34 +981,34 @@ page address name 1 00000ae0 _CsmRegs 1 0000dd12 _Curr_Edge 0 00008000 _Current_count -0 0000b97e _DATALOG_ISR -0 0000b9bf _DCLK -0 0000b1e8 _DINTCH1_ISR -0 0000b203 _DINTCH2_ISR -0 0000b21e _DINTCH3_ISR -0 0000b239 _DINTCH4_ISR -0 0000b254 _DINTCH5_ISR -0 0000b26f _DINTCH6_ISR +0 0000b98b _DATALOG_ISR +0 0000b9cc _DCLK +0 0000b1f4 _DINTCH1_ISR +0 0000b20f _DINTCH2_ISR +0 0000b22a _DINTCH3_ISR +0 0000b245 _DINTCH4_ISR +0 0000b260 _DINTCH5_ISR +0 0000b27b _DINTCH6_ISR 1 0000dabc _DIR_GPIO32 1 0000dabd _DIR_GPIO48 -0 0000b9cb _DOUT -0 0000baf5 _DSP28x_usDelay +0 0000b9d8 _DOUT +0 0000bb02 _DSP28x_usDelay 0 0000959a _Default_params 1 0000dab1 _Desk 1 00000880 _DevEmuRegs 1 0000dabe _DigErr -0 0000bad7 _DisableDog +0 0000bae4 _DisableDog 1 00001000 _DmaRegs -0 0000b28a _ECAN0INTA_ISR -0 0000b2a5 _ECAN0INTB_ISR -0 0000b2c0 _ECAN1INTA_ISR -0 0000b2db _ECAN1INTB_ISR -0 0000b2f6 _ECAP1_INT_ISR -0 0000b311 _ECAP2_INT_ISR -0 0000b32c _ECAP3_INT_ISR -0 0000b347 _ECAP4_INT_ISR -0 0000b362 _ECAP5_INT_ISR -0 0000b37d _ECAP6_INT_ISR +0 0000b296 _ECAN0INTA_ISR +0 0000b2b1 _ECAN0INTB_ISR +0 0000b2cc _ECAN1INTA_ISR +0 0000b2e7 _ECAN1INTB_ISR +0 0000b302 _ECAP1_INT_ISR +0 0000b31d _ECAP2_INT_ISR +0 0000b338 _ECAP3_INT_ISR +0 0000b353 _ECAP4_INT_ISR +0 0000b36e _ECAP5_INT_ISR +0 0000b389 _ECAP6_INT_ISR 1 00006040 _ECanaLAMRegs 1 000060c0 _ECanaMOTORegs 1 00006080 _ECanaMOTSRegs @@ -1030,30 +1030,30 @@ abs 00007ffe _EEPROM_PARAMS_END_BYTE abs 00007efc _EEPROM_PARAMS_START_BYTE abs 00003f7e _EEPROM_PARAMS_START_WORD abs 00008000 _EEPROM_TOTAL_BYTES -0 0000b9e3 _EMUINT_ISR -0 0000b398 _EPWM1_INT_ISR -0 0000b3b3 _EPWM1_TZINT_ISR -0 0000b3ce _EPWM2_INT_ISR -0 0000b3e9 _EPWM2_TZINT_ISR -0 0000b404 _EPWM3_INT_ISR -0 0000b41f _EPWM3_TZINT_ISR -0 0000b43a _EPWM4_INT_ISR -0 0000b455 _EPWM4_TZINT_ISR -0 0000b470 _EPWM5_INT_ISR -0 0000b48b _EPWM5_TZINT_ISR -0 0000b4a6 _EPWM6_INT_ISR -0 0000b4c1 _EPWM6_TZINT_ISR +0 0000b9f0 _EMUINT_ISR +0 0000b3a4 _EPWM1_INT_ISR +0 0000b3bf _EPWM1_TZINT_ISR +0 0000b3da _EPWM2_INT_ISR +0 0000b3f5 _EPWM2_TZINT_ISR +0 0000b410 _EPWM3_INT_ISR +0 0000b42b _EPWM3_TZINT_ISR +0 0000b446 _EPWM4_INT_ISR +0 0000b461 _EPWM4_TZINT_ISR +0 0000b47c _EPWM5_INT_ISR +0 0000b497 _EPWM5_TZINT_ISR +0 0000b4b2 _EPWM6_INT_ISR +0 0000b4cd _EPWM6_TZINT_ISR 1 00006800 _EPwm1Regs 1 00006840 _EPwm2Regs 1 00006880 _EPwm3Regs 1 000068c0 _EPwm4Regs 1 00006900 _EPwm5Regs 1 00006940 _EPwm6Regs -0 0000b4dc _EQEP1_INT_ISR -0 0000b4f7 _EQEP2_INT_ISR +0 0000b4e8 _EQEP1_INT_ISR +0 0000b503 _EQEP2_INT_ISR 1 00006b00 _EQep1Regs 1 00006b40 _EQep2Regs -0 0000babc _EnableInterrupts +0 0000bac9 _EnableInterrupts 1 0000e00a _ErrorCount 1 0000dfb7 _FILTER_CLIP 1 00000a80 _FlashRegs @@ -1061,31 +1061,31 @@ abs 00008000 _EEPROM_TOTAL_BYTES 1 00006fc0 _GpioDataRegs 1 00006fe0 _GpioIntRegs 1 0000dc7e _HSPCLK -0 0000a13b _Handlai -0 0000b512 _I2CINT1A_ISR -0 0000b52d _I2CINT2A_ISR +0 0000a147 _Handlai +0 0000b51e _I2CINT1A_ISR +0 0000b539 _I2CINT2A_ISR 1 00007900 _I2caRegs -0 0000b9ee _ILLEGAL_ISR +0 0000b9fb _ILLEGAL_ISR 1 0000deba _IMPowse -0 0000b98b _INT13_ISR -0 0000b998 _INT14_ISR -0 0000ba9e _INT_NOTUSED_ISR +0 0000b998 _INT13_ISR +0 0000b9a5 _INT14_ISR +0 0000baab _INT_NOTUSED_ISR 1 0000dab8 _INcount0 1 0000dab9 _INcount1 -0 0000b804 _InitAdc -0 000098cc _InitCan -0 0000aad4 _InitCpuTimers -0 00009eb4 _InitPeripheralClocks -0 0000b0aa _InitPieCtrl -0 0000b9a5 _InitPieVectTable -0 0000a041 _InitPll -0 0000af6b _InitSeeprom -0 0000bac5 _InitSysCtrl -0 0000a3c7 _InitXintf16Gpio -0 0000b15d _Init_DAC -0 00009bf0 _Init_packMask +0 0000b810 _InitAdc +0 0000976b _InitCan +0 0000aae0 _InitCpuTimers +0 00009ec0 _InitPeripheralClocks +0 0000b0b6 _InitPieCtrl +0 0000b9b2 _InitPieVectTable +0 0000a04d _InitPll +0 0000af77 _InitSeeprom +0 0000bad2 _InitSysCtrl +0 0000a3d3 _InitXintf16Gpio +0 0000b169 _Init_DAC +0 00009bfc _Init_packMask 0 00009036 _Init_sensors -0 0000a365 _Init_sensors_more +0 0000a371 _Init_sensors_more 1 0000dd1e _K100 1 0000dd20 _K_50 1 0000dd22 _K_T1 @@ -1093,118 +1093,118 @@ abs 00008000 _EEPROM_TOTAL_BYTES 1 0000dab6 _Kalibro 1 0000dab5 _Kurrent 1 0000dc7c _LSPCLK -0 0000b548 _LUF_ISR -0 0000b563 _LVF_ISR -0 0000b0e8 _Load_control_init -0 0000aa18 _Load_params -0 0000a2fc _Load_protection_prepare +0 0000b554 _LUF_ISR +0 0000b56f _LVF_ISR +0 0000b0f4 _Load_control_init +0 0000aa24 _Load_params +0 0000a308 _Load_protection_prepare 0 00008d97 _Load_runner -0 0000ab0f _Load_voltage_can +0 0000ab1b _Load_voltage_can 1 0000dea0 _Log 1 0000e032 _Lonely -0 0000b57e _MRINTA_ISR -0 0000b599 _MRINTB_ISR +0 0000b58a _MRINTA_ISR +0 0000b5a5 _MRINTB_ISR 1 0000daba _MUX_GPIO32 1 0000dabb _MUX_GPIO48 -0 0000b5b4 _MXINTA_ISR -0 0000b5cf _MXINTB_ISR +0 0000b5c0 _MXINTA_ISR +0 0000b5db _MXINTB_ISR 1 0000d730 _Maska 1 00005000 _McbspaRegs 1 00005040 _McbspbRegs 1 0000e00c _MessageReceivedCount 1 0000e00e _MessageTransivedCount 1 0000dab0 _Mode -0 0000b9f9 _NMI_ISR +0 0000ba06 _NMI_ISR 1 0000dab7 _Owen -0 0000baa8 _PIE_RESERVED +0 0000bab5 _PIE_RESERVED 1 00380090 _PartIdRegs 1 00000ce0 _PieCtrlRegs 1 00000d00 _PieVectTable 0 0000c274 _PieVectTableInit 0 000094a1 _Power_count 1 0000dd04 _READY -0 0000b902 _RESET -0 0000a7b5 _RSA_RX_Handler -0 0000a7fb _RSA_TX_Handler -0 0000a841 _RSB_RX_Handler -0 0000a887 _RSB_TX_Handler -0 0000ac68 _RS_BSend -0 0000ae05 _RS_FifoTick1ms -0 0000b915 _RS_FifoWait +0 0000b90e _RESET +0 0000a7c1 _RSA_RX_Handler +0 0000a807 _RSA_TX_Handler +0 0000a84d _RSB_RX_Handler +0 0000a893 _RSB_TX_Handler +0 0000ac74 _RS_BSend +0 0000ae11 _RS_FifoTick1ms +0 0000b921 _RS_FifoWait 1 0000dec0 _RS_Len 0 00008c38 _RS_RX_Handler -0 0000a5ff _RS_Send -0 0000b7d0 _RS_SetBitMode -0 0000ae90 _RS_SetLineMode -0 0000aa58 _RS_SetLineSpeed -0 0000a28e _RS_TX_Handler -0 0000b9b2 _RTOSINT_ISR +0 0000a60b _RS_Send +0 0000b7dc _RS_SetBitMode +0 0000ae9c _RS_SetLineMode +0 0000aa64 _RS_SetLineSpeed +0 0000a29a _RS_TX_Handler +0 0000b9bf _RTOSINT_ISR 0 0000c000 _RamfuncsLoadEnd 0 0000c000 _RamfuncsLoadStart 0 0000c000 _RamfuncsRunStart -0 0000aca0 _ReceiveAnswerModbus4 -0 00009a20 _ReceiveCommandModbus3 -0 0000a477 _ReceiveCommandModbus6 -0 0000b5ea _SCIRXINTA_ISR -0 0000b605 _SCIRXINTB_ISR -0 0000b620 _SCIRXINTC_ISR -0 0000b63b _SCITXINTA_ISR -0 0000b656 _SCITXINTB_ISR -0 0000b671 _SCITXINTC_ISR -0 0000b94d _SENDBIT -0 0000b68c _SEQ1INT_ISR -0 0000b6a7 _SEQ2INT_ISR -0 0000b6c2 _SPIRXINTA_ISR -0 0000bae6 _SPISE2P_DRV_csclr -0 0000baeb _SPISE2P_DRV_csset -0 0000ad70 _SPISE2P_DRV_init +0 0000acac _ReceiveAnswerModbus4 +0 00009a2c _ReceiveCommandModbus3 +0 0000a483 _ReceiveCommandModbus6 +0 0000b5f6 _SCIRXINTA_ISR +0 0000b611 _SCIRXINTB_ISR +0 0000b62c _SCIRXINTC_ISR +0 0000b647 _SCITXINTA_ISR +0 0000b662 _SCITXINTB_ISR +0 0000b67d _SCITXINTC_ISR +0 0000b947 _SENDBIT +0 0000b698 _SEQ1INT_ISR +0 0000b6b3 _SEQ2INT_ISR +0 0000b6ce _SPIRXINTA_ISR +0 0000baf3 _SPISE2P_DRV_csclr +0 0000baf8 _SPISE2P_DRV_csset +0 0000ad7c _SPISE2P_DRV_init 0 0000915f _SPISE2P_DRV_tick -0 0000b6dd _SPITXINTA_ISR +0 0000b6e9 _SPITXINTA_ISR 1 0000dc7a _SYSCLKOUT -0 0000afbb _Save_params +0 0000afc7 _Save_params 1 00007050 _SciaRegs 1 00007750 _ScibRegs 1 00007770 _ScicRegs -0 0000a955 _Seeprom_read -0 0000a996 _Seeprom_write -0 0000abf8 _SendCommandModbus4 -0 0000b8b0 _ServiceDog -0 0000b06a _Setup_DAC_time +0 0000a961 _Seeprom_read +0 0000a9a2 _Seeprom_write +0 0000ac04 _SendCommandModbus4 +0 0000b8bc _ServiceDog +0 0000b076 _Setup_DAC_time 1 00007040 _SpiaRegs 1 00007010 _SysCtrlRegs -0 0000b6f8 _TINT0_ISR +0 0000b704 _TINT0_ISR 1 0000dd05 _TPL_CANS -0 00008437 _Temper_count +0 00008434 _Temper_count 1 0000dab2 _TermoAD 1 0000dab3 _TermoRS 1 0000dab4 _TermoSW 1 0000e010 _TestMbox1 1 0000e012 _TestMbox2 1 0000e014 _TestMbox3 -0 00009978 _UMP_CAN_service -0 0000ba04 _USER10_ISR -0 0000ba0f _USER11_ISR -0 0000ba1a _USER12_ISR -0 0000ba25 _USER1_ISR -0 0000ba30 _USER2_ISR -0 0000ba3b _USER3_ISR -0 0000ba46 _USER4_ISR -0 0000ba51 _USER5_ISR -0 0000ba5c _USER6_ISR -0 0000ba67 _USER7_ISR -0 0000ba72 _USER8_ISR -0 0000ba7d _USER9_ISR +0 00009984 _UMP_CAN_service +0 0000ba11 _USER10_ISR +0 0000ba1c _USER11_ISR +0 0000ba27 _USER12_ISR +0 0000ba32 _USER1_ISR +0 0000ba3d _USER2_ISR +0 0000ba48 _USER3_ISR +0 0000ba53 _USER4_ISR +0 0000ba5e _USER5_ISR +0 0000ba69 _USER6_ISR +0 0000ba74 _USER7_ISR +0 0000ba7f _USER8_ISR +0 0000ba8a _USER9_ISR 1 0000dfbc _WAKE -0 0000b713 _WAKEINT_ISR +0 0000b71f _WAKEINT_ISR 1 0000dfbe _WAKE_TIME 1 0000deb8 _WAKEpowse -0 0000b81d _XINT1_ISR -0 0000b836 _XINT2_ISR -0 0000b72e _XINT3_ISR -0 0000b749 _XINT4_ISR -0 0000b764 _XINT5_ISR -0 0000b77f _XINT6_ISR -0 0000b79a _XINT7_ISR +0 0000b829 _XINT1_ISR +0 0000b842 _XINT2_ISR +0 0000b73a _XINT3_ISR +0 0000b755 _XINT4_ISR +0 0000b770 _XINT5_ISR +0 0000b78b _XINT6_ISR +0 0000b7a6 _XINT7_ISR 1 00007070 _XIntruptRegs 1 00000b20 _XintfRegs 1 000007f0 __STACK_END @@ -1215,141 +1215,141 @@ abs ffffffff ___TI_prof_data_start abs ffffffff ___binit__ abs ffffffff ___c_args__ 0 0000c000 ___cinit__ -0 0000bafd ___etext__ +0 0000bb0a ___etext__ abs ffffffff ___pinit__ 0 00008000 ___text__ -0 0000b7b5 __args_main +0 0000b7c1 __args_main 1 0000e03c __cleanup_ptr 1 0000e03e __dtors_ptr 1 0000dffe __lock -0 0000bad6 __nop -0 0000bad2 __register_lock -0 0000bace __register_unlock +0 0000bae3 __nop +0 0000badf __register_lock +0 0000badb __register_unlock 1 00000400 __stack 1 0000dffc __unlock -0 0000b84f _abort +0 0000b85b _abort 1 0000d740 _adc_filter -0 0000825a _adc_isr +0 00008257 _adc_isr 1 0000ddbc _adc_table_lem -0 0000a8cd _c_int00 +0 0000a8d9 _c_int00 1 0000dd07 _cal_addr -0 0000981e _calc_sensor_koef +0 000098d6 _calc_sensor_koef 1 0000df80 _ccc 1 0000dd0b _chk -0 0000b899 _clear_mem +0 0000b8a5 _clear_mem 1 0000de3e _cntr_addr_c 1 0000de3f _cntr_addr_c_all 0 00008ef3 _cpu_timer1_isr_PULT 0 00008ab4 _cpu_timer1_isr_SENS -0 0000abbf _cpu_timer2_isr +0 0000abcb _cpu_timer2_isr 1 0000dac0 _crc_16_tab -0 0000b7ea _create_uart_vars -0 0000add4 _dSEND +0 0000b7f6 _create_uart_vars +0 0000ade0 _dSEND 1 0000dd28 _def_FILTERBAT 1 0000df40 _def_cal 1 0000d8f0 _digits 1 0000d710 _din_count -0 0000b9d7 _epilog_c28x_1 -0 0000b9db _epilog_c28x_2 -0 0000b8da _er_anal +0 0000b9e4 _epilog_c28x_1 +0 0000b9e8 _epilog_c28x_2 +0 0000b8e6 _er_anal 1 0000dd3a _err_count 1 0000e063 _errno -0 0000b851 _exit +0 0000b85d _exit 1 0000e034 _ext_diag 1 0000e040 _ext_temp -0 00009f39 _extendbios -0 0000ae34 _filterbat +0 00009f45 _extendbios +0 0000ae40 _filterbat 1 0000dc41 _flag_DEBUG 1 0000de8a _flog -0 00008784 _get_Buttons +0 000085db _get_Buttons 0 00009281 _get_Mode -0 0000a420 _get_command -0 0000af94 _get_crc16 -0 0000b93b _get_crc_16 -0 0000aeea _get_crc_16b -0 0000b179 _im_calc -0 00009fbd _init -0 0000aa96 _init_zone7 -0 0000a76e _initload +0 0000a42c _get_command +0 0000afa0 _get_crc16 +0 0000b959 _get_crc_16 +0 0000aef6 _get_crc_16b +0 0000b185 _im_calc +0 00009fc9 _init +0 0000aaa2 _init_zone7 +0 0000a77a _initload 1 0000e030 _isMask 1 0000e02a _isNumb 0 00009396 _kanal_Send 1 0000e050 _lev_count 1 0000dff0 _lev_quadr -0 0000a6dd _load +0 0000a6e9 _load 1 00200000 _logs_block 1 0000e05f _low_count -0 000085de _main -0 0000badf _memset +0 00008781 _main +0 0000baec _memset 1 0000dbc0 _modbus 1 0000de89 _never_write 1 0000de88 _no_write 1 0000dd13 _okay 1 0000d900 _out_filter 1 0000dc80 _param -0 0000b95e _pause_us -0 0000a0c3 _peek +0 0000b96b _pause_us +0 0000a0cf _peek 1 0000dd0a _period_blink 1 0000dea8 _period_dac 1 0000dd09 _period_ready -0 0000ab85 _poke +0 0000ab91 _poke 1 0000e018 _powK 1 0000dd08 _pow_addr 1 0000df22 _prev_ok -0 0000b868 _prolog_c28x_1 -0 0000b86c _prolog_c28x_2 -0 0000b874 _prolog_c28x_3 +0 0000b874 _prolog_c28x_1 +0 0000b878 _prolog_c28x_2 +0 0000b880 _prolog_c28x_3 1 0000e02b _quaLamp 1 0000e056 _readr -0 0000b0c9 _reset_errs +0 0000b0d5 _reset_errs 1 0000d040 _rs_a 1 0000d3c0 _rs_b -0 0000bab2 _rsvd_ISR -0 0000ac9f _run -0 0000b003 _select_tpl_255 -0 00009abd _select_tpl_canal +0 0000babf _rsvd_ISR +0 0000acab _run +0 0000b00f _select_tpl_255 +0 00009ac9 _select_tpl_canal 1 0000dc42 _sens_count 1 0000dfc0 _sens_pair 1 0000dfd8 _sens_type -0 0000baf0 _set_cntrl_addr +0 0000bafd _set_cntrl_addr 0 00008927 _setup_adc -0 0000a9d7 _setup_arr_cmd_length -0 0000b027 _setup_leds_line +0 0000a9e3 _setup_arr_cmd_length +0 0000b033 _setup_leds_line 0 00009686 _setup_uart 1 0000dd0c _sig -0 0000b08a _sqrt -0 0000bafc _tflash +0 0000b096 _sqrt +0 0000bb09 _tflash 1 0000dd0d _time_1_5sec 1 0000dd0f _time_3sec 1 0000dd0e _time_5msec 1 0000dd10 _time_5sec 1 0000dea9 _time_dac -0 0000aebd _timer_Init +0 0000aec9 _timer_Init 1 0000dd06 _tpl_cans -0 0000ab4a _ump_can_fragment -0 0000b195 _ump_crc -0 0000a913 _ump_log_can -0 0000b106 _ump_log_init -0 0000ae62 _ump_log_io -0 0000976b _ump_log_read -0 0000ba88 _ump_log_rs -0 0000b881 _ump_log_tick -0 0000a21e _ump_log_write -0 0000a5b2 _ump_prepare -0 00009fbe _ump_rtu_encode -0 0000b1b1 _ump_tms28335_capture -0 0000ac30 _ump_tms28335_fragment -0 0000b123 _ump_tms28335_prepare -0 0000a1ad _ump_validate -0 0000ada2 _unsetup_leds_line -0 00009b59 _upload +0 0000ab56 _ump_can_fragment +0 0000b1a1 _ump_crc +0 0000a91f _ump_log_can +0 0000b112 _ump_log_init +0 0000ae6e _ump_log_io +0 00009823 _ump_log_read +0 0000ba95 _ump_log_rs +0 0000b88d _ump_log_tick +0 0000a22a _ump_log_write +0 0000a5be _ump_prepare +0 00009fca _ump_rtu_encode +0 0000b1bd _ump_tms28335_capture +0 0000ac3c _ump_tms28335_fragment +0 0000b12f _ump_tms28335_prepare +0 0000a1b9 _ump_validate +0 0000adae _unsetup_leds_line +0 00009b65 _upload 1 0000e001 _wait -0 0000b140 _what_is +0 0000b14c _what_is 1 0000e048 _zer_count 1 0000de40 _zer_filter abs ffffffff binit 0 0000c000 cinit -0 0000bafd etext +0 0000bb0a etext abs ffffffff pinit @@ -1360,10 +1360,10 @@ page address name 0 00008000 .text 0 00008000 _Current_count 0 00008000 ___text__ -0 0000825a _adc_isr -0 00008437 _Temper_count -0 000085de _main -0 00008784 _get_Buttons +0 00008257 _adc_isr +0 00008434 _Temper_count +0 000085db _get_Buttons +0 00008781 _main 0 00008927 _setup_adc 0 00008ab4 _cpu_timer1_isr_SENS 0 00008c38 _RS_RX_Handler @@ -1376,212 +1376,212 @@ page address name 0 000094a1 _Power_count 0 0000959a _Default_params 0 00009686 _setup_uart -0 0000976b _ump_log_read -0 0000981e _calc_sensor_koef -0 000098cc _InitCan -0 00009978 _UMP_CAN_service -0 00009a20 _ReceiveCommandModbus3 -0 00009abd _select_tpl_canal -0 00009b59 _upload -0 00009bf0 _Init_packMask -0 00009e2c FS$$DIV -0 00009eb4 _InitPeripheralClocks -0 00009f39 _extendbios -0 00009fbd _init -0 00009fbe _ump_rtu_encode -0 0000a041 _InitPll -0 0000a0c3 _peek -0 0000a13b _Handlai -0 0000a1ad _ump_validate -0 0000a21e _ump_log_write -0 0000a28e _RS_TX_Handler -0 0000a2fc _Load_protection_prepare -0 0000a365 _Init_sensors_more -0 0000a3c7 _InitXintf16Gpio -0 0000a420 _get_command -0 0000a477 _ReceiveCommandModbus6 -0 0000a5b2 _ump_prepare -0 0000a5ff _RS_Send -0 0000a64a _CANa_handler -0 0000a6dd _load -0 0000a726 _CAN_send -0 0000a76e _initload -0 0000a7b5 _RSA_RX_Handler -0 0000a7fb _RSA_TX_Handler -0 0000a841 _RSB_RX_Handler -0 0000a887 _RSB_TX_Handler -0 0000a8cd _c_int00 -0 0000a913 _ump_log_can -0 0000a955 _Seeprom_read -0 0000a996 _Seeprom_write -0 0000a9d7 _setup_arr_cmd_length -0 0000aa18 _Load_params -0 0000aa58 _RS_SetLineSpeed -0 0000aa96 _init_zone7 -0 0000aad4 _InitCpuTimers -0 0000ab0f _Load_voltage_can -0 0000ab4a _ump_can_fragment -0 0000ab85 _poke -0 0000abbf _cpu_timer2_isr -0 0000abf8 _SendCommandModbus4 -0 0000ac30 _ump_tms28335_fragment -0 0000ac68 _RS_BSend -0 0000ac9f _run -0 0000aca0 _ReceiveAnswerModbus4 -0 0000acd7 _Answer -0 0000ad70 _SPISE2P_DRV_init -0 0000ada2 _unsetup_leds_line -0 0000add4 _dSEND -0 0000ae05 _RS_FifoTick1ms -0 0000ae34 _filterbat -0 0000ae62 _ump_log_io -0 0000ae90 _RS_SetLineMode -0 0000aebd _timer_Init -0 0000aeea _get_crc_16b -0 0000af16 _CANa_reset_err -0 0000af41 L$$DIV -0 0000af50 L$$MOD -0 0000af5e UL$$DIV -0 0000af65 UL$$MOD -0 0000af6b _InitSeeprom -0 0000af94 _get_crc16 -0 0000afbb _Save_params -0 0000b003 _select_tpl_255 -0 0000b027 _setup_leds_line -0 0000b049 _ConfigCpuTimer -0 0000b06a _Setup_DAC_time -0 0000b08a _sqrt -0 0000b0aa _InitPieCtrl -0 0000b0c9 _reset_errs -0 0000b0e8 _Load_control_init -0 0000b106 _ump_log_init -0 0000b123 _ump_tms28335_prepare -0 0000b140 _what_is -0 0000b15d _Init_DAC -0 0000b179 _im_calc -0 0000b195 _ump_crc -0 0000b1b1 _ump_tms28335_capture -0 0000b1cd _ADCINT_ISR -0 0000b1e8 _DINTCH1_ISR -0 0000b203 _DINTCH2_ISR -0 0000b21e _DINTCH3_ISR -0 0000b239 _DINTCH4_ISR -0 0000b254 _DINTCH5_ISR -0 0000b26f _DINTCH6_ISR -0 0000b28a _ECAN0INTA_ISR -0 0000b2a5 _ECAN0INTB_ISR -0 0000b2c0 _ECAN1INTA_ISR -0 0000b2db _ECAN1INTB_ISR -0 0000b2f6 _ECAP1_INT_ISR -0 0000b311 _ECAP2_INT_ISR -0 0000b32c _ECAP3_INT_ISR -0 0000b347 _ECAP4_INT_ISR -0 0000b362 _ECAP5_INT_ISR -0 0000b37d _ECAP6_INT_ISR -0 0000b398 _EPWM1_INT_ISR -0 0000b3b3 _EPWM1_TZINT_ISR -0 0000b3ce _EPWM2_INT_ISR -0 0000b3e9 _EPWM2_TZINT_ISR -0 0000b404 _EPWM3_INT_ISR -0 0000b41f _EPWM3_TZINT_ISR -0 0000b43a _EPWM4_INT_ISR -0 0000b455 _EPWM4_TZINT_ISR -0 0000b470 _EPWM5_INT_ISR -0 0000b48b _EPWM5_TZINT_ISR -0 0000b4a6 _EPWM6_INT_ISR -0 0000b4c1 _EPWM6_TZINT_ISR -0 0000b4dc _EQEP1_INT_ISR -0 0000b4f7 _EQEP2_INT_ISR -0 0000b512 _I2CINT1A_ISR -0 0000b52d _I2CINT2A_ISR -0 0000b548 _LUF_ISR -0 0000b563 _LVF_ISR -0 0000b57e _MRINTA_ISR -0 0000b599 _MRINTB_ISR -0 0000b5b4 _MXINTA_ISR -0 0000b5cf _MXINTB_ISR -0 0000b5ea _SCIRXINTA_ISR -0 0000b605 _SCIRXINTB_ISR -0 0000b620 _SCIRXINTC_ISR -0 0000b63b _SCITXINTA_ISR -0 0000b656 _SCITXINTB_ISR -0 0000b671 _SCITXINTC_ISR -0 0000b68c _SEQ1INT_ISR -0 0000b6a7 _SEQ2INT_ISR -0 0000b6c2 _SPIRXINTA_ISR -0 0000b6dd _SPITXINTA_ISR -0 0000b6f8 _TINT0_ISR -0 0000b713 _WAKEINT_ISR -0 0000b72e _XINT3_ISR -0 0000b749 _XINT4_ISR -0 0000b764 _XINT5_ISR -0 0000b77f _XINT6_ISR -0 0000b79a _XINT7_ISR -0 0000b7b5 __args_main -0 0000b7d0 _RS_SetBitMode -0 0000b7ea _create_uart_vars -0 0000b804 _InitAdc -0 0000b81d _XINT1_ISR -0 0000b836 _XINT2_ISR -0 0000b84f C$$EXIT -0 0000b84f _abort -0 0000b851 _exit -0 0000b868 _prolog_c28x_1 -0 0000b86c _prolog_c28x_2 -0 0000b874 _prolog_c28x_3 -0 0000b881 _ump_log_tick -0 0000b899 _clear_mem -0 0000b8b0 _ServiceDog -0 0000b8da _er_anal -0 0000b902 _RESET -0 0000b915 _RS_FifoWait -0 0000b93b _get_crc_16 -0 0000b94d _SENDBIT -0 0000b95e _pause_us -0 0000b97e _DATALOG_ISR -0 0000b98b _INT13_ISR -0 0000b998 _INT14_ISR -0 0000b9a5 _InitPieVectTable -0 0000b9b2 _RTOSINT_ISR -0 0000b9bf _DCLK -0 0000b9cb _DOUT -0 0000b9d7 _epilog_c28x_1 -0 0000b9db _epilog_c28x_2 -0 0000b9e3 _EMUINT_ISR -0 0000b9ee _ILLEGAL_ISR -0 0000b9f9 _NMI_ISR -0 0000ba04 _USER10_ISR -0 0000ba0f _USER11_ISR -0 0000ba1a _USER12_ISR -0 0000ba25 _USER1_ISR -0 0000ba30 _USER2_ISR -0 0000ba3b _USER3_ISR -0 0000ba46 _USER4_ISR -0 0000ba51 _USER5_ISR -0 0000ba5c _USER6_ISR -0 0000ba67 _USER7_ISR -0 0000ba72 _USER8_ISR -0 0000ba7d _USER9_ISR -0 0000ba88 _ump_log_rs -0 0000ba93 U$$DIV -0 0000ba98 U$$MOD -0 0000ba9e _INT_NOTUSED_ISR -0 0000baa8 _PIE_RESERVED -0 0000bab2 _rsvd_ISR -0 0000babc _EnableInterrupts -0 0000bac5 _InitSysCtrl -0 0000bace __register_unlock -0 0000bad2 __register_lock -0 0000bad6 __nop -0 0000bad7 _DisableDog -0 0000badf _memset -0 0000bae6 _SPISE2P_DRV_csclr -0 0000baeb _SPISE2P_DRV_csset -0 0000baf0 _set_cntrl_addr -0 0000baf5 _DSP28x_usDelay -0 0000bafc _tflash -0 0000bafd ___etext__ -0 0000bafd etext +0 0000976b _InitCan +0 00009823 _ump_log_read +0 000098d6 _calc_sensor_koef +0 00009984 _UMP_CAN_service +0 00009a2c _ReceiveCommandModbus3 +0 00009ac9 _select_tpl_canal +0 00009b65 _upload +0 00009bfc _Init_packMask +0 00009e38 FS$$DIV +0 00009ec0 _InitPeripheralClocks +0 00009f45 _extendbios +0 00009fc9 _init +0 00009fca _ump_rtu_encode +0 0000a04d _InitPll +0 0000a0cf _peek +0 0000a147 _Handlai +0 0000a1b9 _ump_validate +0 0000a22a _ump_log_write +0 0000a29a _RS_TX_Handler +0 0000a308 _Load_protection_prepare +0 0000a371 _Init_sensors_more +0 0000a3d3 _InitXintf16Gpio +0 0000a42c _get_command +0 0000a483 _ReceiveCommandModbus6 +0 0000a5be _ump_prepare +0 0000a60b _RS_Send +0 0000a656 _CANa_handler +0 0000a6e9 _load +0 0000a732 _CAN_send +0 0000a77a _initload +0 0000a7c1 _RSA_RX_Handler +0 0000a807 _RSA_TX_Handler +0 0000a84d _RSB_RX_Handler +0 0000a893 _RSB_TX_Handler +0 0000a8d9 _c_int00 +0 0000a91f _ump_log_can +0 0000a961 _Seeprom_read +0 0000a9a2 _Seeprom_write +0 0000a9e3 _setup_arr_cmd_length +0 0000aa24 _Load_params +0 0000aa64 _RS_SetLineSpeed +0 0000aaa2 _init_zone7 +0 0000aae0 _InitCpuTimers +0 0000ab1b _Load_voltage_can +0 0000ab56 _ump_can_fragment +0 0000ab91 _poke +0 0000abcb _cpu_timer2_isr +0 0000ac04 _SendCommandModbus4 +0 0000ac3c _ump_tms28335_fragment +0 0000ac74 _RS_BSend +0 0000acab _run +0 0000acac _ReceiveAnswerModbus4 +0 0000ace3 _Answer +0 0000ad7c _SPISE2P_DRV_init +0 0000adae _unsetup_leds_line +0 0000ade0 _dSEND +0 0000ae11 _RS_FifoTick1ms +0 0000ae40 _filterbat +0 0000ae6e _ump_log_io +0 0000ae9c _RS_SetLineMode +0 0000aec9 _timer_Init +0 0000aef6 _get_crc_16b +0 0000af22 _CANa_reset_err +0 0000af4d L$$DIV +0 0000af5c L$$MOD +0 0000af6a UL$$DIV +0 0000af71 UL$$MOD +0 0000af77 _InitSeeprom +0 0000afa0 _get_crc16 +0 0000afc7 _Save_params +0 0000b00f _select_tpl_255 +0 0000b033 _setup_leds_line +0 0000b055 _ConfigCpuTimer +0 0000b076 _Setup_DAC_time +0 0000b096 _sqrt +0 0000b0b6 _InitPieCtrl +0 0000b0d5 _reset_errs +0 0000b0f4 _Load_control_init +0 0000b112 _ump_log_init +0 0000b12f _ump_tms28335_prepare +0 0000b14c _what_is +0 0000b169 _Init_DAC +0 0000b185 _im_calc +0 0000b1a1 _ump_crc +0 0000b1bd _ump_tms28335_capture +0 0000b1d9 _ADCINT_ISR +0 0000b1f4 _DINTCH1_ISR +0 0000b20f _DINTCH2_ISR +0 0000b22a _DINTCH3_ISR +0 0000b245 _DINTCH4_ISR +0 0000b260 _DINTCH5_ISR +0 0000b27b _DINTCH6_ISR +0 0000b296 _ECAN0INTA_ISR +0 0000b2b1 _ECAN0INTB_ISR +0 0000b2cc _ECAN1INTA_ISR +0 0000b2e7 _ECAN1INTB_ISR +0 0000b302 _ECAP1_INT_ISR +0 0000b31d _ECAP2_INT_ISR +0 0000b338 _ECAP3_INT_ISR +0 0000b353 _ECAP4_INT_ISR +0 0000b36e _ECAP5_INT_ISR +0 0000b389 _ECAP6_INT_ISR +0 0000b3a4 _EPWM1_INT_ISR +0 0000b3bf _EPWM1_TZINT_ISR +0 0000b3da _EPWM2_INT_ISR +0 0000b3f5 _EPWM2_TZINT_ISR +0 0000b410 _EPWM3_INT_ISR +0 0000b42b _EPWM3_TZINT_ISR +0 0000b446 _EPWM4_INT_ISR +0 0000b461 _EPWM4_TZINT_ISR +0 0000b47c _EPWM5_INT_ISR +0 0000b497 _EPWM5_TZINT_ISR +0 0000b4b2 _EPWM6_INT_ISR +0 0000b4cd _EPWM6_TZINT_ISR +0 0000b4e8 _EQEP1_INT_ISR +0 0000b503 _EQEP2_INT_ISR +0 0000b51e _I2CINT1A_ISR +0 0000b539 _I2CINT2A_ISR +0 0000b554 _LUF_ISR +0 0000b56f _LVF_ISR +0 0000b58a _MRINTA_ISR +0 0000b5a5 _MRINTB_ISR +0 0000b5c0 _MXINTA_ISR +0 0000b5db _MXINTB_ISR +0 0000b5f6 _SCIRXINTA_ISR +0 0000b611 _SCIRXINTB_ISR +0 0000b62c _SCIRXINTC_ISR +0 0000b647 _SCITXINTA_ISR +0 0000b662 _SCITXINTB_ISR +0 0000b67d _SCITXINTC_ISR +0 0000b698 _SEQ1INT_ISR +0 0000b6b3 _SEQ2INT_ISR +0 0000b6ce _SPIRXINTA_ISR +0 0000b6e9 _SPITXINTA_ISR +0 0000b704 _TINT0_ISR +0 0000b71f _WAKEINT_ISR +0 0000b73a _XINT3_ISR +0 0000b755 _XINT4_ISR +0 0000b770 _XINT5_ISR +0 0000b78b _XINT6_ISR +0 0000b7a6 _XINT7_ISR +0 0000b7c1 __args_main +0 0000b7dc _RS_SetBitMode +0 0000b7f6 _create_uart_vars +0 0000b810 _InitAdc +0 0000b829 _XINT1_ISR +0 0000b842 _XINT2_ISR +0 0000b85b C$$EXIT +0 0000b85b _abort +0 0000b85d _exit +0 0000b874 _prolog_c28x_1 +0 0000b878 _prolog_c28x_2 +0 0000b880 _prolog_c28x_3 +0 0000b88d _ump_log_tick +0 0000b8a5 _clear_mem +0 0000b8bc _ServiceDog +0 0000b8e6 _er_anal +0 0000b90e _RESET +0 0000b921 _RS_FifoWait +0 0000b947 _SENDBIT +0 0000b959 _get_crc_16 +0 0000b96b _pause_us +0 0000b98b _DATALOG_ISR +0 0000b998 _INT13_ISR +0 0000b9a5 _INT14_ISR +0 0000b9b2 _InitPieVectTable +0 0000b9bf _RTOSINT_ISR +0 0000b9cc _DCLK +0 0000b9d8 _DOUT +0 0000b9e4 _epilog_c28x_1 +0 0000b9e8 _epilog_c28x_2 +0 0000b9f0 _EMUINT_ISR +0 0000b9fb _ILLEGAL_ISR +0 0000ba06 _NMI_ISR +0 0000ba11 _USER10_ISR +0 0000ba1c _USER11_ISR +0 0000ba27 _USER12_ISR +0 0000ba32 _USER1_ISR +0 0000ba3d _USER2_ISR +0 0000ba48 _USER3_ISR +0 0000ba53 _USER4_ISR +0 0000ba5e _USER5_ISR +0 0000ba69 _USER6_ISR +0 0000ba74 _USER7_ISR +0 0000ba7f _USER8_ISR +0 0000ba8a _USER9_ISR +0 0000ba95 _ump_log_rs +0 0000baa0 U$$DIV +0 0000baa5 U$$MOD +0 0000baab _INT_NOTUSED_ISR +0 0000bab5 _PIE_RESERVED +0 0000babf _rsvd_ISR +0 0000bac9 _EnableInterrupts +0 0000bad2 _InitSysCtrl +0 0000badb __register_unlock +0 0000badf __register_lock +0 0000bae3 __nop +0 0000bae4 _DisableDog +0 0000baec _memset +0 0000baf3 _SPISE2P_DRV_csclr +0 0000baf8 _SPISE2P_DRV_csset +0 0000bafd _set_cntrl_addr +0 0000bb02 _DSP28x_usDelay +0 0000bb09 _tflash +0 0000bb0a ___etext__ +0 0000bb0a etext 0 0000c000 _RamfuncsLoadEnd 0 0000c000 _RamfuncsLoadStart 0 0000c000 _RamfuncsRunStart diff --git a/tests/current_measure/model.inc b/tests/current_measure/model.inc new file mode 100644 index 0000000..1aa888c --- /dev/null +++ b/tests/current_measure/model.inc @@ -0,0 +1,90 @@ +/* Модель проверяет выбор фаз и диагностику на заданных установившихся RMS, а не точность аналогового тракта. */ +#include /* Даёт настоящим im_calc и Current_count вычисление квадратного корня. */ +#include /* Выводит имя сценария и конкретное условие при регрессии. */ +#include /* Обнуляет независимое состояние перед каждым сценарием. */ +#define interrupt /* Убирает аппаратный атрибут ISR из включаемого production-заголовка на хосте. */ +typedef float FILTERBAT; /* Заменяет состояние внешнего сглаживающего фильтра: его динамика не относится к выбору пар фаз. */ +#include "measure.h" /* Использует реальные ERROR, FLAG, частоту АЦП, маски ошибок и коды типов датчиков. */ +#include "package.h" /* Использует реальные типы плат, смещения COMM и адреса технологических регистров. */ +int modbus[129], Desk, pow_addr, Curr_Edge; /* Предоставляет штатное регистровое пространство и выбранную конфигурацию измерений. */ +int sens_type[24], sens_pair[24], lev_count[6], adc_table_lem[4]; /* Сохраняет production-размеры глобальных датчиков и локальных массивов двух трёхфазных вводов. */ +float lev_quadr[6], zer_count[4], powK[4]; /* Содержит RMS-накопители, нулевые уровни и коэффициенты физических каналов. */ +FILTERBAT out_filter[24], zer_filter[4]; /* Предоставляет ячейки фильтров по тем же индексам, что в Current_count. */ +unsigned int err_count[6], low_count[2], time_3sec; /* Сохраняет настоящие счётчики выдержки фазных ошибок и пониженного напряжения. */ +long WAKE, WAKE_TIME; /* Позволяет запускать диагностику после завершения начальной паузы прошивки. */ +FLAG chk, sig; /* Предоставляет реальные агрегированные диагностические флаги для reset_errs. */ +static int failures; /* Накапливает ошибки всех сценариев, чтобы мутация проверяла сразу передачу и диагностику. */ +static float filterbat(FILTERBAT *state, float value) /* Пропускает заданное значение через заглушку внешнего фильтра без изменения исследуемых RMS-накопителей. */ +{ /* Ограничивает заглушку сглаживания, используемую только вне проверяемого выбора пар. */ + (void)state; /* Состояние фильтра не влияет на сценарии с заданными установившимися RMS. */ + return value; /* Сохраняет нулевой уровень и амплитуду без дополнительной динамики. */ +} /* Завершает единственную заглушку математического окружения. */ +/* HANDLERS */ +static void check(int condition, const char *what, const char *scenario) /* Записывает конкретную регрессию, продолжая проверку остальных требований. */ +{ /* Начинает обработку одного ожидаемого поведения. */ + if (!condition) { /* Не засоряет вывод успешными отдельными сравнениями. */ + printf("FAIL %s: %s\n", what, scenario); /* Имена Modbus и Wry позволяют мутационному запуску различать два последствия ошибки. */ + failures++; /* Делает итоговый код завершения ненулевым при любой неудаче. */ + } /* Заканчивает регистрацию нарушенного условия. */ +} /* Завершает независимую проверку одного свойства. */ +static void run_case(int desk, int feed, int ignore, const char *name) /* Проверяет выбранный ввод; feed=-1 задаёт симметрию без перекоса. */ +{ /* Создаёт полностью независимый сценарий COMM или LOAD. */ + int targets[6] = {360, 360, 360, 360, 360, 360}; /* Задаёт симметрию выше порогов COMM200 и LOAD300; третьи фазы расположены в ячейках4 и5. */ + int i, tick, local, base, expected_wry, previous = failures; /* Хранит индексы каналов, адрес регистра и число ошибок до сценария. */ + memset(modbus, 0, sizeof(modbus)); /* Убирает старые данные и флаги, в том числе Bypas, между сценариями. */ + memset(err_count, 0, sizeof(err_count)); /* Начинает выдержку перекоса с нуля, чтобы проверить её реальное накопление. */ + memset(low_count, 0, sizeof(low_count)); /* Исключает влияние предыдущей проверки защиты LOAD по нижнему порогу. */ + memset(zer_count, 0, sizeof(zer_count)); /* Согласует средний уровень АЦП с нулевыми входными отсчётами. */ + memset(adc_table_lem, 0, sizeof(adc_table_lem)); /* Нулевые мгновенные отсчёты позволяют точно задать RMS через состояние фильтра. */ + Desk = desk; /* Выбирает настоящую ветку обработки полярности COMM или защиты LOAD. */ + pow_addr = desk == dsk_COMM ? TPL_POW * 2 + OWEN_DT : 0; /* Получает глобальное смещение16 для COMM из production-констант и нулевое для LOAD. */ + Curr_Edge = desk == dsk_COMM ? 200 : 300; /* Повторяет штатный порог включения контроля перекоса в единицах измеряемой величины. */ + time_3sec = 3 * ADC_FREQ; /* Сохраняет настоящую выдержку: три секунды при частоте из measure.h. */ + WAKE = WAKE_TIME = 0; /* Снимает стартовую блокировку диагностики и обновления измеренных значений. */ + chk.all = sig.all = 0; /* Убирает агрегированные флаги предыдущего сценария. */ + for (i = 0; i < 24; i++) { /* Готовит именно глобальную таблицу датчиков, на которой проявлялась ошибка COMM. */ + sens_pair[i] = i; /* Оставляет температурным позициям пары с самими собой, как Init_sensors. */ + sens_type[i] = VOLTAGE; /* Выбирает ветку напряжения, не затрагивая управление током нагрузки. */ + } /* Завершает подготовку глобального пространства датчиков. */ + for (i = 0; i < 4; i++) { /* Настраивает четыре физических канала двух вводов. */ + sens_pair[pow_addr + i] = pow_addr + (i ^ 1); /* Создаёт штатные глобальные пары; мутация ошибочно обратится к температурной области COMM. */ + sens_error[pow_addr + i].bit.Ignor = ignore; /* Проверяет как разрешённый Stop, так и штатное для COMM игнорирование остановки. */ + sens_hi_edge[pow_addr + i] = 1000; /* Не допускает посторонней защиты LOAD по верхнему порогу в этих фазных сценариях. */ + powK[i] = 1.0f; /* Нулевой отсчёт после вычитания нуля должен давать нулевое мгновенное значение. */ + } /* Завершает подготовку физических каналов и их диагностических режимов. */ + if (feed >= 0) { /* Задаёт перекос только одному вводу, сохраняя второй симметричным. */ + targets[feed * 2] = desk == dsk_COMM ? 250 : 500; /* Первая фаза превышает соответствующий порог включения диагностики. */ + targets[feed * 2 + 1] = desk == dsk_COMM ? 149 : 299; /* Вторая фаза ниже порога; историческая ошибка исключала её сравнение с первой. */ + targets[4 + feed] = desk == dsk_COMM ? 100 : 200; /* Третья фаза ниже первой на60%, выявляя неверное накопление общего счётчика. */ + } /* Завершает выбор контрольных RMS для одного перекошенного ввода. */ + for (tick = 0; tick < time_3sec + 2; tick++) { /* Даёт каждому физическому каналу пройти полную выдержку er_anal, включая проверку достижения порога. */ + for (i = 0; i < 6; i++) { /* Фиксирует установившиеся RMS отдельно от проверяемой логики пар и счётчиков. */ + float rms = targets[i] + 0.25f; /* Запас четверть единицы исключает случайную потерю единицы при округлении float в int. */ + lev_count[i] = targets[i]; /* Задаёт значения ещё не обработанных в текущем проходе каналов, как на установившемся сигнале. */ + lev_quadr[i] = rms * rms * ADC_FREQ / (ADC_FREQ - 1.0f); /* Компенсирует один шаг экспоненциального RMS-фильтра при нулевом мгновенном отсчёте. */ + } /* Завершает подготовку всех шести RMS без вмешательства в диагностические счётчики. */ + for (i = 0; i < 4; i++) Current_count(i); /* Повторяет реальный порядок вызовов из ADC.c, включая общий счётчик третьей фазы. */ + } /* Завершает выдержку на настоящей production-диагностике. */ + for (i = 0; i < 2; i++) { /* Проверяет оба ввода, в том числе отсутствие взаимного влияния их данных. */ + local = i * 2; /* Переводит номер ввода в первый из двух физических каналов. */ + base = 0x68 + i * 3; /* Адресует штатную тройку фаз:0x68–0x6A или0x6B–0x6D. */ + check(modbus[base] == targets[local] && modbus[base + 1] == targets[local + 1] && modbus[base + 2] == targets[4 + i], "Modbus phases", name); /* Требует передачу A/B/C без подмены первой фазы второй. */ + expected_wry = i == feed; /* Только выбранный перекошенный ввод должен получить диагностику Wry. */ + check(sens_error[pow_addr + local + 1].bit.Wry == expected_wry, "Wry phase B", name); /* Проверяет восстановление сравнения второй фазы с действительным максимумом. */ + check(sens_error[pow_addr + local].bit.Wry == expected_wry, "Wry phase C", name); /* Проверяет общий счётчик третьей фазы, который исторически чередовал увеличение и уменьшение. */ + check(sens_error[pow_addr + local + 1].bit.Stop == (expected_wry && !ignore), "Stop respects Ignor", name); /* Разделяет диагностику перекоса и разрешение остановки. */ + } /* Завершает проверки обоих вводов после выдержки. */ + if (failures == previous) printf("PASS %s\n", name); /* Показывает полное прохождение сценария только при выполнении всех ожиданий. */ +} /* Завершает один сценарий со сброшенным и затем выдержанным состоянием. */ +int main(void) /* Объединяет адресацию обоих вводов, два режима Ignor, симметрию и регрессию LOAD. */ +{ /* Запускает одинаковый набор сценариев для production и временной исторической мутации. */ + run_case(dsk_COMM, 0, 0, "COMM feed 1: 250/149/100, Ignor=0"); /* Проверяет первую тройку регистров и разрешённый Stop. */ + run_case(dsk_COMM, 1, 0, "COMM feed 2: 250/149/100, Ignor=0"); /* Проверяет вторую тройку без подмены данных между вводами. */ + run_case(dsk_COMM, 0, 1, "COMM feed 1: 250/149/100, Ignor=1"); /* Требует Wry при выключенной реакции Stop для первого ввода. */ + run_case(dsk_COMM, 1, 1, "COMM feed 2: 250/149/100, Ignor=1"); /* Требует такую же независимость Wry от Ignor на втором вводе. */ + run_case(dsk_COMM, -1, 0, "COMM symmetric: 360/360/360"); /* Исключает ложный перекос при симметрии выше порога диагностики. */ + run_case(dsk_LOAD, 0, 0, "LOAD feed 1: 500/299/200, pow_addr=0"); /* Проверяет сохранение штатных локальных пар LOAD и его порога300. */ + run_case(dsk_LOAD, 1, 0, "LOAD feed 2: 500/299/200, pow_addr=0"); /* Проверяет вторую пару LOAD при нулевом глобальном смещении. */ + run_case(dsk_LOAD, -1, 0, "LOAD symmetric: 360/360/360"); /* Исключает ложное срабатывание LOAD на симметрии выше его порога. */ + return failures ? 1 : 0; /* Сообщает вызывающему Python о любом нарушении проверяемого поведения. */ +} /* Завершает исполняемую модель без записи файлов или изменения прошивки. */ diff --git a/tests/current_measure/run_test.py b/tests/current_measure/run_test.py new file mode 100644 index 0000000..283e222 --- /dev/null +++ b/tests/current_measure/run_test.py @@ -0,0 +1,44 @@ +# Проверяет передачу фаз и диагностику на настоящих функциях measure.c без аппаратуры C28x. +import argparse # Принимает путь к компилятору хостовой модели, не привязывая тест к одной машине. +import os # Добавляет каталог компилятора в PATH для запуска его вспомогательных программ. +from pathlib import Path # Разрешает пути относительно теста независимо от рабочего каталога. +import re # Находит границы функций и единственное место исторической мутации. +import subprocess # Компилирует модель и проверяет коды завершения исполняемых проверок. +import tempfile # Размещает сгенерированный C и исполняемые файлы вне исходного дерева. + +ROOT = Path(__file__).resolve().parents[2] # Поднимается от tests/current_measure к корню репозитория. +SOURCE = ROOT / "Source/Internal/measure.c" # Выбирает текущую production-реализацию измерений. + +def extract(source, name): # Извлекает одну настоящую функцию, чтобы тест не содержал копию алгоритма. + match = re.search(r"(?:void|int|float)\s+" + name + r"\([^;{}]*\)\s*\{", source) # Отличает определение от прототипа и вызовов. + assert match is not None, name # Явно завершает тест, если production-функция исчезла или сменила форму. + end = source.index("{", match.start()) + 1 # Начинает подсчёт вложенности сразу после открывающей скобки. + depth = 1 # Учитывает уже найденный внешний блок функции. + while depth: # Читает определение целиком вместе с вложенными условиями. + depth += (source[end] == "{") - (source[end] == "}") # Находит соответствующую закрывающую скобку без обрезки вложенных блоков. + end += 1 # Включает последнюю обработанную скобку в извлекаемый диапазон. + return source[match.start():end] # Возвращает production-код без изменения его вычислений. + +parser = argparse.ArgumentParser(description="Проверка фаз COMM и LOAD на хосте") # Описывает назначение самостоятельного запуска. +parser.add_argument("--cc", required=True, help="Путь к GCC") # Позволяет выбрать доступный C-компилятор без изменения теста. +args = parser.parse_args() # Разбирает аргументы до создания временных файлов. +source = re.sub(r"/\*.*?\*/|//[^\n]*", "", SOURCE.read_text(encoding="utf-8"), flags=re.S) # Убирает комментарии с примерами скобок, сохраняя исполняемый код. +body = "\n".join(extract(source, name) for name in ("im_calc", "er_anal", "reset_errs", "Current_count")) # Включает реальные расчёты, накопление ошибки и запись диагностических флагов. +before, after = Path(__file__).with_name("model.inc").read_text(encoding="utf-8").split("/* HANDLERS */") # Вставляет production-функции между моделью окружения и сценариями. +legacy, replacements = re.subn(r"\bpair\s*=\s*chan\s*\^\s*1\s*;", "pair = sens_pair[chan];", body) # Возвращает старую ошибку только во временную мутационную сборку. +assert replacements == 1, "Не найдено единственное место выбора пары фаз" # Не допускает фиктивной мутационной проверки неизменённого кода. +environment = dict(os.environ) # Сохраняет окружение вызывающего процесса для компилятора. +environment["PATH"] = str(Path(args.cc).resolve().parent) + os.pathsep + environment.get("PATH", "") # Делает библиотеки и вспомогательные программы GCC доступными дочерним процессам. +with tempfile.TemporaryDirectory(prefix="current-measure-") as directory: # Автоматически удаляет только временные артефакты этого запуска. + for name, functions in (("production", body), ("legacy", legacy)): # Прогоняет одинаковые поведенческие сценарии на исправлении и исторической ошибке. + c_path = Path(directory) / (name + ".c") # Разделяет исходники двух сборок для однозначных диагностик компилятора. + exe_path = Path(directory) / (name + ".exe") # Даёт каждой модели собственный исполняемый файл. + c_path.write_text(before + functions + after, encoding="utf-8") # Сохраняет временный C с русскими пояснениями в UTF-8. + subprocess.run([args.cc, "-std=c99", "-O3", "-fno-strict-aliasing", "-Werror=implicit-function-declaration", "-I", str(ROOT / "Source/Internal/Include"), str(c_path), "-lm", "-o", str(exe_path)], check=True, env=environment) # Компилирует с O3; отключение alias-оптимизации сохраняет production-псевдонимы ERROR поверх Modbus на хосте. + result = subprocess.run([str(exe_path)], capture_output=True, text=True, env=environment, timeout=20) # Ограничивает зависание и сохраняет результат каждого поведенческого сценария. + if name == "production": # Исправленная реализация обязана пройти все проверки без исключений. + print(result.stdout, end="") # Показывает сценарии, успешно проверенные настоящими функциями прошивки. + assert result.returncode == 0, result.stdout + result.stderr # Возвращает сбой запуска при любой регрессии исправленного кода. + else: # Старая строка должна воспроизводимо ломать и значения фаз, и диагностику. + assert result.returncode == 1 and "FAIL Modbus" in result.stdout and "FAIL Wry" in result.stdout, result.stdout + result.stderr # Доказывает чувствительность теста к обоим последствиям именно этой ошибки. + print("PASS mutation: legacy pair rejected by Modbus and Wry checks") # Сообщает об ожидаемом провале временной сборки со старой строкой. diff --git a/tests/testlamp/model.inc b/tests/testlamp/model.inc new file mode 100644 index 0000000..5297137 --- /dev/null +++ b/tests/testlamp/model.inc @@ -0,0 +1,122 @@ +/* Проверяет удержание TESTLAMP и выбор пакетов при уже включённых рабочих лампах. */ +#include /* Выводит конкретные нарушенные условия и итог сценария. */ +#include /* Обнуляет регистровое пространство перед началом проверки. */ +#define interrupt /* Убирает аппаратный атрибут ISR при компиляции модели на ПК. */ +typedef float FILTERBAT; /* Позволяет подключить production-заголовок с интерфейсами фильтров. */ +#include "measure.h" /* Получает настоящие READY_FREQ, BLINK_TIME, CANPOWSE и maximum_bright. */ +#include "package.h" /* Получает настоящие адреса TESTLAMP, яркости, ламп и типов плат. */ +#include "DSP2833x_SWPrioritizedIsrLevels.h" /* Использует реальную вычисляемую маску приоритетов TI MINT13. */ +typedef union { /* Моделирует слово Modbus размером хостового int, сохраняя номера битов production-псевдонимов. */ + unsigned int all; /* Обеспечивает запись целого слова по тому же смещению массива. */ + struct { /* Размещает шестнадцать технологических битов в младшей части слова. */ + unsigned int bit0:1, bit1:1, bit2:1, bit3:1, bit4:1, bit5:1, bit6:1, bit7:1; /* Сохраняет позиции кнопок и команд 0..7. */ + unsigned int bit8:1, bit9:1, bitA:1, bitB:1, bitC:1, bitD:1, bitE:1, bitF:1; /* Сохраняет позиции повторителей входов и старших команд 8..15. */ + } bit; /* Предоставляет production-псевдонимам доступ к полям регистра. */ +} WORDE; /* Завершает хостовое представление одного регистра Modbus. */ +struct gpio_bits { /* Предоставляет входы всех ветвей настоящей get_Buttons, без моделирования электрических свойств. */ + unsigned GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11; /* Представляет дискретные входы нескольких типов плат. */ + unsigned GPIO20, GPIO21, GPIO22, GPIO23, GPIO24, GPIO25, GPIO26, GPIO27; /* Представляет перемычки и вход TESTLAMP GPIO26 пульта. */ + unsigned GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53; /* Представляет входы банка B, читаемые get_Buttons. */ +}; /* Завершает перечень моделируемых входов. */ +struct gpio_reg { struct gpio_bits bit; }; /* Даёт регистрам GPADAT и GPBDAT production-форму обращения. */ +static struct { struct gpio_reg GPADAT, GPBDAT; } GpioDataRegs; /* Хранит управляемые сценарием уровни входов. */ +static struct { unsigned long all; } DigErr; /* Принимает диагностическую маску посторонней ветви SHKF. */ +static struct { unsigned long InterruptCount; } CpuTimer1; /* Учитывает вызовы настоящего обработчика пульта. */ +int modbus[129], Desk; /* Предоставляет технологические регистры и выбирает ветвь пульта. */ +unsigned int INcount0, CanPowse, CanGO; /* Хранит production-накопитель кнопки и таймер выдачи CAN. */ +unsigned long isMask, Lonely; /* Хранит тестовую маску и возраст последней связи. */ +int isNumb, quaLamp = 6; /* Сохраняет тестовые цифры и число ламп из pulto.c. */ +static unsigned int IER, mask_at_eint, entry_mask, failures, sends, nested_entries, timer_pending; /* Отслеживает разрешения прерываний, пакетные вызовы и возможность вложенного Timer1. */ +static unsigned long lamp_word; /* Запоминает последний пакет шести сигнальных ламп канала 2. */ +static long digit_word; /* Сохраняет последнее значение одного из двух семисегментных индикаторов в текущем такте. */ +static int digit_dot, digit_sends; /* Запоминает режим форматирования цифр и наличие числового пакета в текущем такте. */ +#define M_INT13 0x1000U /* Повторяет бит 12 INT13 из DSP2833x_Device.h для модели регистра IER. */ +#define EALLOW ((void)0) /* Не моделирует защиту аппаратных регистров, поскольку она не влияет на рассматриваемые ветви. */ +#define EDIS ((void)0) /* Завершает заглушку защищённой записи. */ +#define EINT (mask_at_eint = IER) /* Снимает реально применённую маску в момент разрешения вложенных прерываний. */ +#define ServiceDog() ((void)0) /* Исключает аппаратный сторожевой таймер из проверки индикации. */ +#define toggle_ONLINE() ((void)0) /* Не моделирует электрический сигнал готовности ПЛИС. */ +#define toggle_RES_OUT_1() ((void)0) /* Исключает резервный GPIO из логики выбора TESTLAMP. */ +#define toggle_RES_OUT_2() ((void)0) /* Исключает второй резервный GPIO из пакетной проверки. */ +void cpu_timer1_isr_PULT(void); /* Позволяет заглушке передачи смоделировать повторное аппаратное событие Timer1. */ +static void kanal_Send(int adr, long dat, int dot) /* Записывает передаваемые данные, не подменяя проверяемый выбор режима. */ +{ /* Начинает обработку одного production-вызова передачи. */ + sends++; /* Позволяет обнаружить дополнительные вызовы передачи при повторном входе в ISR. */ + if (timer_pending && (IER & M_INT13)) { /* Моделирует новый такт Timer1 во время незаконченной передачи, только когда собственное прерывание ошибочно разрешено. */ + timer_pending = 0; /* Ограничивает искусственное событие одним вложенным вызовом. */ + nested_entries++; /* Регистрирует перемешивание обработки двух тактов. */ + cpu_timer1_isr_PULT(); /* Запускает настоящую production-функцию повторно при неверной маске. */ + } /* Завершает моделирование потенциального повторного входа. */ + if (adr == 2) lamp_word = (unsigned long)dat; /* Сохраняет именно канал сигнальных ламп, обновляемый в каждом такте. */ + if (adr < 2) { /* Записывает также передачу цифр, чтобы обнаружить переход семисегментного индикатора в рабочий режим при провале кнопки. */ + digit_word = dat; /* Сохраняет переданное production-функцией числовое значение. */ + digit_dot = dot; /* Различает тест четырёх одинаковых цифр и обычное форматирование измерений. */ + digit_sends++; /* Отмечает присутствие числового пакета в текущем такте. */ + } /* Завершает фиксацию передачи на семисегментный индикатор. */ +} /* Завершает заглушку аппаратной передачи. */ +/* HANDLERS */ +static void check(int condition, const char *name) /* Накапливает ошибки, позволяя проверить все последствия одного дефекта. */ +{ /* Начинает регистрацию одного требования. */ + if (!condition) { /* Выводит только нарушенные условия. */ + printf("FAIL %s\n", name); /* Даёт мутационному тесту устойчивое имя обнаруженного дефекта. */ + failures++; /* Делает код завершения ненулевым при любой регрессии. */ + } /* Завершает обработку ошибки. */ +} /* Завершает проверку одного требования. */ +static void tick(void) /* Моделирует сохранение и восстановление IER на границе аппаратного ISR. */ +{ /* Начинает один такт индикации. */ + IER = entry_mask; /* Возвращает исходные разрешения источников перед новым обработчиком. */ + sends = 0; /* Отделяет вызовы передачи текущего такта от предыдущих. */ + digit_sends = 0; /* Не принимает пакет предыдущего такта за обновление цифр в текущем. */ + cpu_timer1_isr_PULT(); /* Выполняет настоящий алгоритм выбора режима, PWM и пакетов. */ + check(mask_at_eint == (entry_mask & MINT13 & ~M_INT13), "interrupt mask"); /* Проверяет отсутствие собственного Timer1 и запрет включения ранее выключенных источников. */ + check(sends >= 1 && sends <= 2, "packet count"); /* Требует штатный объём одного такта: пакет ламп и не более одного пакета очередного индикатора. */ +} /* Завершает один такт индикации. */ +int main(void) /* Запускает на настоящих функциях сценарий рабочих ламп, теста с помехами и возврата в работу. */ +{ /* Начинает общий поведенческий сценарий. */ + int i, pwm_on = 0; /* Перебирает опросы и такты; считает включённые такты рабочего PWM за один полный период. */ + memset(modbus, 0, sizeof(modbus)); /* Убирает старые команды и состояния перед сценарием. */ + check(sizeof(WORDE) == sizeof(modbus[0]), "register layout"); /* Подтверждает корректность production-псевдонимов в хостовой модели. */ + Desk = dsk_EPLT; /* Выбирает реальную ветвь чтения TESTLAMP пульта. */ + modbus[2] = 1; /* Включает рабочую лампу до нажатия TESTLAMP, как в сообщении пользователя. */ + Bright[0] = maximum_bright; /* Задаёт уже включённой лампе постоянную яркость для обнаружения случайных провалов. */ + entry_mask = M_INT13 | (1U << 0) | (1U << 13); /* Разрешает Timer1, группу ADC и Timer2, проверяя также маскирование равного приоритета. */ + tick(); /* Получает первый рабочий пакет ламп. */ + check(lamp_word == 1, "normal lamp before test"); /* Подтверждает исходное постоянное свечение до нажатия. */ + GpioDataRegs.GPADAT.bit.GPIO26 = 1; /* Нажимает физическую кнопку активным высоким уровнем. */ + for (i = 0; i < 1001; i++) get_Buttons(); /* Проходит реальные 1000 накопительных опросов и следующий опрос фиксации порога. */ + check(bTestLamp == 1, "test activation"); /* Требует включения теста после полной выдержки. */ + for (i = 0; i < 600; i++) { /* Проверяет удержание более BLINK_TIME=500 тактов без подавления штатного медленного мигания. */ + unsigned long expected_mask; /* Сохраняет фазу теста перед очередным возмущением кнопки. */ + GpioDataRegs.GPADAT.bit.GPIO26 = 0; /* Вводит короткий провал входа на один опрос главного цикла. */ + get_Buttons(); /* Выполняет настоящий накопительный фильтр и публикацию кнопки. */ + check(bTestLamp == 1, "held test"); /* Проверяет сохранение TESTLAMP вместо мгновенного возврата рабочих масок. */ + timer_pending = 1; /* Допускает новый аппаратный такт во время передачи для проверки запрета повторного входа. */ + tick(); /* Формирует тестовый пакет при кратком провале физического входа. */ + expected_mask = isMask; /* Получает ожидаемую медленную фазу из настоящей what_is. */ + check(lamp_word == expected_mask, "test packet during input glitch"); /* Исключает рабочую маску уже горящих ламп из тестового потока. */ + check(!digit_sends || (digit_word == isNumb && digit_dot == 4), "test digit packet during input glitch"); /* Требует сохранения тестового значения и формата цифр во время помехи кнопки. */ + check(nested_entries == 0, "nested transmission"); /* Требует единственного владельца DATA/CLK на протяжении передачи. */ + timer_pending = 0; /* Убирает смоделированное событие после завершения текущего такта. */ + GpioDataRegs.GPADAT.bit.GPIO26 = 1; /* Возвращает уровень удерживаемой кнопки. */ + get_Buttons(); /* Восстанавливает насыщенный накопитель без смены тестового режима. */ + } /* Завершает серию коротких помех при удержании. */ + check(isNumb == 1111 && isMask == 0xFFFFFFFFUL, "slow test sequence"); /* После 600 миллисекунд требует единственного штатного шага what_is с периодом 500 тактов, а не ускоренного строба. */ + GpioDataRegs.GPADAT.bit.GPIO26 = 0; /* Отпускает физическую кнопку на длительное время. */ + for (i = 0; i < 1001; i++) get_Buttons(); /* Даёт накопителю полностью разрядиться и зафиксировать отпускание. */ + check(bTestLamp == 0, "test release"); /* Проверяет, что сохранение состояния не залипает в TESTLAMP. */ + tick(); /* Возвращает передачу рабочей маски после отпускания. */ + check(lamp_word == 1, "normal lamp after test"); /* Восстанавливает уже включённую до теста лампу. */ + cTestLamp = 1; /* Включает независимую удалённую команду теста через production-регистр. */ + tick(); /* Проверяет приоритет удалённого TESTLAMP при отпущенной физической кнопке. */ + check(lamp_word == isMask, "remote test"); /* Требует тестовую маску для обоих источников команды. */ + cTestLamp = 0; /* Завершает удалённый тест перед проверкой рабочего PWM. */ + Bright[0] = 6; /* Устанавливает шесть включённых тактов из десяти в production-периоде яркости. */ + for (i = 0; i < 10; i++) { /* Проверяет один полный период PWM после выхода из теста. */ + tick(); /* Даёт настоящей функции вычислить текущую фазу яркости. */ + check(lamp_word == 0 || lamp_word == 1, "normal PWM packet"); /* Исключает оставшиеся тестовые биты из рабочей маски. */ + pwm_on += lamp_word == 1; /* Измеряет реальное число включённых тактов production-PWM. */ + } /* Завершает период обычной яркости. */ + check(pwm_on == 6, "normal PWM duty"); /* Подтверждает сохранение заданной яркости 6/10 после выхода из теста. */ + printf("%s TESTLAMP: held input glitches, single ISR, normal lamps, release, remote command\n", failures ? "FAIL" : "PASS"); /* Выводит проверенные свойства без заявления о физическом испытании платы. */ + return failures ? 1 : 0; /* Возвращает результат всех поведенческих требований. */ +} /* Завершает хостовую проверку. */ diff --git a/tests/testlamp/run_test.py b/tests/testlamp/run_test.py new file mode 100644 index 0000000..6670c6d --- /dev/null +++ b/tests/testlamp/run_test.py @@ -0,0 +1,46 @@ +"""Проверяет TESTLAMP на настоящих функциях прошивки без подключения платы.""" +import argparse # Позволяет использовать доступный GCC для модели аппаратного окружения. +import os # Передаёт компилятору PATH с его вспомогательными программами и библиотеками. +from pathlib import Path # Разрешает исходники и модель относительно каталога этого теста. +import re # Извлекает функции, убирая комментарии, которые могут содержать примеры скобок. +import subprocess # Компилирует и запускает независимые проверки с контролем результата. +import tempfile # Удаляет только временные исходники и исполняемые файлы данного запуска. + +ROOT = Path(__file__).resolve().parents[2] # Получает корень репозитория из расположения tests/testlamp. + +def source(name): # Читает production-модуль без изменения исходного файла. + return re.sub(r"/\*.*?\*/|//[^\n]*", "", (ROOT / "Source/Internal" / name).read_text(encoding="utf-8"), flags=re.S) # Убирает комментарии перед разбором вложенных блоков. + +def function(text, name): # Выбирает определение функции вместо копии её алгоритма в тесте. + match = re.search(r"(?:interrupt\s+)?(?:void|int)\s+" + name + r"\([^;{}]*\)\s*\{", text) # Отличает тело функции от прототипов и вызовов. + assert match is not None, name # Завершает проверку, если проверяемая production-функция исчезла. + end, depth = match.end(), 1 # Учитывает найденную открывающую скобку внешнего блока. + while depth: # Читает все вложенные ветви до конца определения. + depth += (text[end] == "{") - (text[end] == "}") # Находит парную закрывающую скобку. + end += 1 # Включает текущий символ в извлекаемый фрагмент. + return text[match.start():end] # Сохраняет порядок операторов настоящей функции. + +parser = argparse.ArgumentParser(description=__doc__) # Объясняет назначение отдельного запуска проверки. +parser.add_argument("--cc", default="C:/msys64/mingw64/bin/gcc.exe", help="Путь к GCC") # Повторяет установленный в этом проекте хостовый компилятор. +args = parser.parse_args() # Разбирает параметры до формирования временных файлов. +button = function(source("peripher.c"), "get_Buttons") # Проверяет именно публикацию отфильтрованной кнопки в Modbus. +pult = source("pulto.c") # Берёт текущую обработку индикации, включая реальные ветви теста и яркости. +body = "\n".join((function(source("measure.c"), "er_anal"), button, function(pult, "what_is"), function(pult, "cpu_timer1_isr_PULT"))) # Собирает функции, участвующие в переключении режима и передаче масок. +before, after = Path(__file__).with_name("model.inc").read_text(encoding="utf-8").split("/* HANDLERS */") # Помещает production-функции между аппаратными заглушками и поведенческими сценариями. +old_button, count_button = re.subn(r"(er_anal\(GpioDataRegs\.GPADAT\.bit\.GPIO26,\s*&INcount0,\s*1000,\s*)bTestLamp(\))", r"\g<1>0\2", body) # Возвращает сброс фильтра при одном провале только во временную мутацию. +old_mask, count_mask = re.subn(r"IER\s*&=\s*\(MINT13\s*&\s*~M_INT13\);", "IER |= MINT13;", body) # Восстанавливает ошибочное разрешение прерываний в отдельном временном варианте. +assert count_button == count_mask == 1, "Не найдены единственные места исправлений TESTLAMP" # Не позволяет мутации незаметно проверять неизменённый код. +environment = dict(os.environ) # Сохраняет окружение основного процесса. +environment["PATH"] = str(Path(args.cc).resolve().parent) + os.pathsep + environment.get("PATH", "") # Делает DLL и вспомогательные программы GCC доступными дочерним процессам. +with tempfile.TemporaryDirectory(prefix="testlamp-") as directory: # Изолирует артефакты каждой проверки от дерева прошивки. + for name, functions, failure in (("production", body, None), ("old_button", old_button, "FAIL held test"), ("old_mask", old_mask, "FAIL interrupt mask")): # Проверяет исправление и чувствительность сценариев к каждой из двух старых ошибок. + c_path, exe_path = Path(directory) / (name + ".c"), Path(directory) / (name + ".exe") # Разделяет временные исходники и программы трёх вариантов. + c_path.write_text(before + functions + after, encoding="utf-8") # Сохраняет модель и русские пояснения в UTF-8. + subprocess.run([args.cc, "-std=c99", "-O3", "-fno-strict-aliasing", "-Werror=implicit-function-declaration", "-I", str(ROOT / "Source/Internal/Include"), "-I", str(ROOT / "Source/External/v120/DSP2833x_common/include"), str(c_path), "-o", str(exe_path)], env=environment, check=True) # Сохраняет адреса production-псевдонимов регистров и использует реальную таблицу приоритетов TI. + result = subprocess.run([str(exe_path)], env=environment, capture_output=True, text=True, timeout=20) # Ограничивает зависание и сохраняет конкретные нарушенные условия. + if failure is None: # Рабочая версия обязана пройти все сценарии. + print(result.stdout, end="") # Показывает результат поведенческих проверок текущей прошивки. + assert result.returncode == 0, result.stdout + result.stderr # Возвращает ошибку при любой регрессии TESTLAMP или рабочего режима. + else: # Старая ошибка должна воспроизводимо нарушить соответствующее требование. + assert result.returncode == 1 and failure in result.stdout, result.stdout + result.stderr # Доказывает, что тест действительно обнаруживает возвращённый дефект. + print("PASS mutation:", name, "rejected") # Сообщает об ожидаемом провале временного варианта со старой ошибкой. diff --git a/tests/ump_can_init/model.inc b/tests/ump_can_init/model.inc new file mode 100644 index 0000000..6251417 --- /dev/null +++ b/tests/ump_can_init/model.inc @@ -0,0 +1,87 @@ +#include /* Задаёт точные размеры регистров и слов протокола при исполнении модели на ПК. */ +#include "ump_tms28335.h" /* Подключает настоящий интерфейс проверки запросов и упаковки фрагментов CAN. */ +#define UMP_CAN_MAX_WORDS UMP_MAX_WORDS /* Повторяет максимальную длину ответа из рабочего заголовка адаптера. */ +#define UMP_CAN_MARKER UMP_MARKER /* Использует каноническую метку отличия служебного кадра от технологических данных. */ +#define ump_can_prepare ump_tms28335_prepare /* Сохраняет штатное соответствие имени адаптера канонической функции порта. */ +#define ANSWER_LEN 128U /* Моделирует границу штатных технологических регистров для компиляции настоящего Handlai. */ +#define dsk_LOAD 6 /* Повторяет номер платы нагрузки из package.h для компиляции технологической ветви Handlai; сценарии используют служебные кадры. */ +#define CHECK(condition) do { if (!(condition)) return __LINE__; } while (0) /* Сохраняет проверки при O3 и возвращает точное место регрессии вызывающему Python. */ + +struct MODEL_REG { uint32_t all; }; /* Моделирует атомарное 32-битное чтение и запись слова аппаратного регистра. */ +struct MODEL_MAILBOX { struct MODEL_REG MDL, MDH; struct { struct { unsigned int DLC; } bit; } MSGCTRL; }; /* Предоставляет реальные имена полей данных и длины кадра, читаемые рабочим кодом. */ +struct ECAN_MBOXES { struct MODEL_MAILBOX MBOX1, MBOX2; }; /* Отделяет входящий запрос в mailbox 1 от служебного ответа в mailbox 2. */ +static struct { struct MODEL_REG CANTA, CANAA, CANTRR, CANTRS; } ECanaRegs; /* Хранит подтверждения, отмену и факт запуска передачи для наблюдения сценарием. */ +static struct ECAN_MBOXES ECanaMboxes; /* Предоставляет обработчикам адресуемую память вместо физической периферии. */ +static struct { unsigned long InterruptCount; } CpuTimer1; /* Задаёт миллисекундное время, от которого сервис считает тайм-аут ожидания ответа. */ +static int modbus[ANSWER_LEN], Desk, Lonely; /* Обеспечивает зависимости технологической ветви Handlai, не исполняемой при служебном запросе. */ +static unsigned int model_reads, model_writes, model_unexpected, model_irq_mask; /* Позволяет отличить ложную команду, корректное чтение и несбалансированную блокировку IRQ. */ + +static unsigned int __disable_interrupts(void) { unsigned int saved = model_irq_mask; model_irq_mask = 1; return saved; } /* Имитирует сохранение предыдущей маски, чтобы вложенные вызовы оставались проверяемыми. */ +static void __restore_interrupts(unsigned int saved) { model_irq_mask = saved; } /* Возвращает исходную маску и позволяет сценарию обнаружить оставленную блокировку. */ +static void Load_voltage_can(unsigned int header, unsigned int a, unsigned int b, unsigned int c) { (void)header; (void)a; (void)b; (void)c; model_unexpected++; } /* Считает ошибочным попадание служебного запроса в обработку технологического напряжения. */ +static void ump_log_can(unsigned int header, unsigned int a, unsigned int b, unsigned int c) { (void)header; (void)a; (void)b; (void)c; model_unexpected++; } /* Обнаруживает лишнюю регистрацию служебного опроса как управляющего CAN-события. */ +static void led2_toggle(void) { model_unexpected++; } /* Отмечает проход по обычной ветви CAN вместо раннего возврата служебного запроса. */ +static unsigned int Load_protection_prepare(unsigned int fn, uint16_t address, uint16_t value, uint16_t *reply, unsigned int *error) { (void)fn; (void)address; (void)value; (void)reply; *error = 2; model_unexpected++; return 0; } /* Запросы теста адресуют журнал, поэтому попадание в карту защиты является ошибкой маршрутизации. */ +#if EEPROM_M95M02 /* Компилирует зависимости дополнительной ветви так же, как прошивка профиля M95M02. */ +static int gas167_contains(uint16_t address) { return address >= 0x5000U && address < 0x5080U; } /* Отделяет область GAS от проверяемого журнала, не копируя реализацию профиля. */ +static unsigned int gas167_prepare(unsigned int fn, uint16_t address, uint16_t value, int can, uint16_t *reply, unsigned int *error) { (void)fn; (void)address; (void)value; (void)can; (void)reply; *error = 2; model_unexpected++; return 0; } /* Делает неожиданное обращение к GAS наблюдаемой ошибкой в тесте запуска журнала. */ +#endif /* Завершает минимальные зависимости профиля, не подменяя проверку общей CAN-маршрутизации. */ +unsigned int ump_log_read(unsigned int address) { model_reads++; return 0x5500U + address - UMP_BASE; } /* Возвращает узнаваемые слова backend, чтобы ответ нельзя было спутать со старым содержимым RAM. */ +int ump_log_write(unsigned int address, unsigned int value) { (void)address; (void)value; model_writes++; return 1; } /* Регистрирует любую нежелательную запись, случайно возникшую из остаточного запроса. */ + +/* PRODUCTION_CAN */ + +static void model_reset_hardware(void) /* Очищает только модель периферии; управляющую RAM оставляет сценарию для воспроизведения холодного старта. */ +{ /* Начинает воспроизводимое состояние аппаратных mailbox после сброса контроллера. */ + ECanaRegs.CANTA.all = 0; ECanaRegs.CANAA.all = 0; ECanaRegs.CANTRR.all = 0; ECanaRegs.CANTRS.all = 0; /* Убирает подтверждения и запросы, которые аппаратный сброс не сохраняет вместе с RAM. */ + ECanaMboxes.MBOX2.MDL.all = 0; ECanaMboxes.MBOX2.MDH.all = 0; /* Обнуляет наблюдаемые данные ответа для обнаружения каждой новой передачи. */ + CpuTimer1.InterruptCount = 1000; model_reads = 0; model_writes = 0; model_unexpected = 0; model_irq_mask = 0; /* Задаёт миллисекундный такт и независимые счётчики нового сценария. */ +} /* Завершает аппаратный сброс без скрытой инициализации проверяемых переменных прошивки. */ + +static void model_poison_state(void) /* Воссоздаёт допустимые остатки RAM, ранее приводившие к ответу без входного запроса. */ +{ /* Начинает заполнение всех управляющих полей ненулевыми либо специально подобранными значениями. */ + ump_can_pending = 0; ump_can_tag = 0xA506U; ump_can_address = UMP_BASE; ump_can_value = 1; /* Сохраняет след прежней команды записи, но отмечает отсутствие нового принятого запроса. */ + ump_can_length = 2; ump_can_index = 0; ump_can_reply_tag = 0x0100U; ump_can_waiting = 0; ump_can_sent_at = 777; /* Представляет старый двухсловный ответ с token 1, который сервис ошибочно считает готовым. */ + ump_can_reply[0] = 0x1234U; ump_can_reply[1] = 0x5678U; /* Создаёт отличимый от backend payload для доказательства отправки именно остаточного буфера. */ +} /* Завершает заполнение состояния, которое настоящий сброс обязан обезвредить. */ + +static int model_first_request(unsigned int token) /* Проверяет весь первый ответ после сброса через настоящий приёмник, валидатор и упаковщик. */ +{ /* Начинает независимую транзакцию чтения 16 слов заголовка журнала. */ + unsigned int fragment; /* Перебирает восемь CAN-фрагментов, каждый из которых содержит два 16-битных слова. */ + ECanaMboxes.MBOX1.MDH.all = ((uint32_t)UMP_CAN_MARKER << 16) | ((uint32_t)token << 8) | 3U; /* Формирует служебную метку, новый token и штатную функцию чтения FC03. */ + ECanaMboxes.MBOX1.MDL.all = ((uint32_t)UMP_BASE << 16) | 16U; ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = 8; /* Запрашивает допустимый восьмибайтный кадр чтения полного 16-словного заголовка. */ + Handlai(&ECanaMboxes); /* Передаёт запрос настоящему разборщику mailbox без прямой установки поля pending. */ + CHECK(ump_can_pending == 1 && model_reads == 0 && model_writes == 0); /* Проверяет, что ISR только опубликовал запрос и не исполнил его вместо главного цикла. */ + for (fragment = 0; fragment < 8; fragment++) { /* Проверяет все фрагменты, включая последний, чтобы сброс счётчиков не скрывал укороченный ответ. */ + UMP_CAN_service(); /* Готовит снимок при первом вызове и далее отправляет по одному настоящему фрагменту. */ + CHECK(ECanaRegs.CANTRS.all == 4 && ump_can_waiting == 1); /* Требует запуска mailbox 2 и ожидания подтверждения именно отправленного кадра. */ + CHECK(ECanaMboxes.MBOX2.MDL.all == (((uint32_t)(0x5500U + fragment * 2U) << 16) | (0x5501U + fragment * 2U))); /* Сравнивает оба слова кадра с содержимым нового снимка, исключая остатки прежнего ответа. */ + CHECK(ECanaMboxes.MBOX2.MDH.all == (((uint32_t)(UMP_CAN_MARKER + fragment) << 16) | ((uint32_t)token << 8))); /* Проверяет порядок фрагментов, token текущего запроса и отсутствие кода ошибки. */ + ECanaRegs.CANTRS.all = 0; ECanaRegs.CANTA.all = 4; /* Имитирует окончание передачи и подтверждение только проверенного фрагмента аппаратурой CAN. */ + } /* Завершает передачу всех 16 запрошенных слов. */ + UMP_CAN_service(); ECanaRegs.CANTA.all = 0; /* Позволяет сервису принять последнее подтверждение; затем моделирует очистку W1C-регистра аппаратурой. */ + CHECK(ECanaRegs.CANTRS.all == 0 && ump_can_waiting == 0 && ump_can_pending == 0); /* Убеждается, что после последнего ACK не отправляется лишний либо старый фрагмент. */ + CHECK(model_reads == 16 && model_writes == 0 && model_unexpected == 0 && model_irq_mask == 0); /* Требует единственного согласованного снимка, отсутствия ложных команд и восстановленной маски IRQ. */ + return 0; /* Сообщает вызывающему сценарию о полном успешном ответе после инициализации. */ +} /* Завершает поведенческую проверку первой транзакции. */ + +#ifdef _WIN32 /* Экспортирует тест явно для загрузки MinGW DLL через ctypes в Windows. */ +__declspec(dllexport) /* Делает run_tests видимой снаружи библиотеки без таблицы экспорта проекта прошивки. */ +#endif /* На остальных платформах используется обычная видимость глобальной функции. */ +int run_tests(void) /* Возвращает ноль только при выполнении всех сценариев запуска и повторного сброса. */ +{ /* Начинает проверку реального дефекта до сброса и его устранения рабочим helper. */ + int result; /* Передаёт точную строку сбоя из сценария полной CAN-транзакции. */ + model_reset_hardware(); model_poison_state(); UMP_CAN_service(); /* Воспроизводит старое поведение на грязной RAM без вызова добавленного сброса. */ + CHECK(ECanaRegs.CANTRS.all == 4 && ECanaMboxes.MBOX2.MDL.all == 0x12345678UL && ump_can_pending == 0); /* Доказывает самопроизвольный ответ, чтобы тест не оказался нечувствителен к исходной регрессии. */ + model_reset_hardware(); model_poison_state(); ump_can_init(); /* Вызывает настоящий новый сброс при тех же остатках RAM и чистой периферии. */ + CHECK(ump_can_pending == 0 && ump_can_tag == 0 && ump_can_address == 0 && ump_can_value == 0); /* Проверяет, что старые параметры не смогут превратиться в ложную принятую команду. */ + CHECK(ump_can_length == 0 && ump_can_index == 0 && ump_can_reply_tag == 0 && ump_can_waiting == 0 && ump_can_sent_at == 0); /* Требует очистки всех управляющих полей незавершённой передачи и тайм-аута. */ + UMP_CAN_service(); UMP_CAN_service(); /* Даёт главному циклу повторно обработать состояние до появления первого запроса. */ + CHECK(ECanaRegs.CANTRS.all == 0 && ECanaRegs.CANTRR.all == 0 && model_reads == 0 && model_writes == 0); /* Запрещает ложную передачу, отмену несуществующего кадра и исполнение остаточной команды. */ + result = model_first_request(0x37U); if (result) return result; /* Проверяет приём и все фрагменты первого запроса после холодного запуска. */ + model_reset_hardware(); model_poison_state(); ump_can_waiting = 1; ump_can_pending = 1; /* Воспроизводит перезапуск во время передачи с ещё не обработанным старым запросом в RAM. */ + ump_can_init(); CpuTimer1.InterruptCount += 1000; UMP_CAN_service(); /* Проверяет сброс ожидания даже после истечения прежнего тайм-аута в 250 мс. */ + CHECK(ECanaRegs.CANTRS.all == 0 && ECanaRegs.CANTRR.all == 0 && ump_can_pending == 0 && ump_can_waiting == 0); /* Не допускает зависания в отмене старого mailbox либо исполнения устаревшего pending. */ + result = model_first_request(0x59U); if (result) return result; /* Доказывает, что после такого перезапуска новый token обслуживается полной последовательностью фрагментов. */ + return 0; /* Подтверждает исправление холодного старта без изменения алгоритма штатного CAN-ответа. */ +} /* Завершает экспортированную проверку регрессии для выбранного профиля EEPROM. */ diff --git a/tests/ump_can_init/run_test.py b/tests/ump_can_init/run_test.py new file mode 100644 index 0000000..8e59605 --- /dev/null +++ b/tests/ump_can_init/run_test.py @@ -0,0 +1,56 @@ +# Проверяет запуск служебного CAN на грязной RAM: использует рабочие обработчики и канонический упаковщик протокола. +import os # Читает пути общей библиотеки и компилятора, не меняя настройки проекта. +from pathlib import Path # Строит абсолютные пути независимо от каталога запуска проверки. +import re # Извлекает рабочие функции, не заменяя их алгоритмы копиями в модели. +import shutil # Находит доступный компилятор GCC по пользовательскому PATH. +import subprocess # Запускает компиляцию и отдельный процесс проверки с контролем кода завершения. +import sys # Повторно использует текущий Python для загрузки тестовой библиотеки. +import tempfile # Изолирует сгенерированный код и библиотеку от исходников и образов прошивки. + +root = Path(__file__).resolve().parents[2] # Находит корень репозитория по расположению постоянного теста. +templates = Path(os.environ.get("TEMPLATES_ROOT", root.parent / "newProject/SETGUI/third_party/templates")) # Повторяет настройку общей библиотеки существующих тестов УМП. +protocol = templates / "c/set-protocol" # Выбирает канонические проверку запросов и формат фрагментов CAN. +compiler = os.environ.get("CC") or shutil.which("gcc") or "C:/msys64/mingw64/bin/gcc.exe" # Поддерживает заданный CC и установленный в рабочем окружении MinGW. +environment = os.environ.copy() # Ограничивает изменение PATH процессами компилятора и модели. +environment["PATH"] = str(Path(compiler).resolve().parent) + os.pathsep + environment.get("PATH", "") # Делает доступными вспомогательные DLL выбранного компилятора в Windows. + +def function(text, name): # Возвращает полное тело указанной функции вместе с её рабочими комментариями. + match = re.search(r"^(?:static\s+)?(?:void|int)\s+" + re.escape(name) + r"\([^;{}]*\)", text, re.M) # Отличает определение функции от вызова и прототипа. + if not match: # Не позволяет тесту незаметно проверять устаревшую копию после переименования функции. + raise AssertionError(f"Не найдена рабочая функция {name}") # Завершает проверку с названием отсутствующей точки интеграции. + end = re.search(r"^}", text[match.end():], re.M) # Использует принятое в модуле размещение закрывающей скобки функции в первом столбце. + if not end: # Отвергает неполный фрагмент вместо генерации частично работающей модели. + raise AssertionError(f"Не найден конец функции {name}") # Указывает причину невозможности извлечения рабочего алгоритма. + return text[match.start():match.end() + end.end()] + "\n" # Сохраняет исходный порядок операторов для компиляции под O3. + +source = (root / "Source/Internal/ecan.c").read_text(encoding="utf-8") # Читает именно текущие исходники транспорта, включая новый сброс состояния. +startup = function(source, "InitCan") # Проверяет реальную связь сброса с аппаратной инициализацией, а не только отдельный helper. +startup_code = re.sub(r"/\*.*?\*/|//[^\n]*", "", startup, flags=re.S) # Удаляет комментарии, чтобы упоминания helper или регистров не выдавались за вызов. +assert len(re.findall(r"\bump_can_init\s*\(\s*\)\s*;", startup_code)) == 1, "InitCan должен один раз вызывать ump_can_init" # Требует выполнения нового сброса при каждом аппаратном запуске. +hardware_start = re.search(r"\b(?:EALLOW|GpioCtrlRegs|ECanaRegs|PieCtrlRegs|IER)\b", startup_code) # Находит первую настройку периферии или разрешение CAN-прерываний. +assert hardware_start and startup_code.index("ump_can_init()") < hardware_start.start(), "Сброс CAN должен предшествовать настройке периферии" # Не допускает окна прерывания с неочищенными полями обмена. +state_start = source.index("static volatile unsigned int ump_can_pending;") # Начинает извлечение общих между ISR и главным циклом переменных. +state_end = source.index("static unsigned long ump_can_sent_at;") + len("static unsigned long ump_can_sent_at;") # Ограничивает фрагмент управляющими полями и штатным буфером ответа. +state = source[state_start:state_end] # Использует объявления из рабочего модуля, чтобы тест замечал изменение состава состояния. +state = state.replace("static unsigned int ump_can_reply[", "static uint16_t ump_can_reply[") # Воспроизводит на ПК 16-битный unsigned int C28x именно в буфере слов CAN. +model = (Path(__file__).with_name("model.inc")).read_text(encoding="utf-8") # Читает аппаратную модель и поведенческие сценарии, сохраняемые рядом с запускателем. +body = state + "\n" + "".join(function(source, name) for name in ("ump_can_init", "Handlai", "UMP_CAN_service")) # Подставляет сброс, настоящий приём запроса и сервис отправки без изменений их логики. +assert model.count("/* PRODUCTION_CAN */") == 1, "Нужна единственная точка подключения рабочего кода" # Исключает пропуск или двойную компиляцию проверяемых функций. +model = model.replace("/* PRODUCTION_CAN */", body) # Встраивает текущие обработчики между аппаратной моделью и сценариями проверки. + +with tempfile.TemporaryDirectory(prefix="ump-can-init-") as directory: # Автоматически удаляет только временные результаты этой проверки. + build = Path(directory) # Фиксирует каталог файлов, не затрагивающих бинарные артефакты репозитория. + source_file = build / "can_init_test.c" # Выделяет общий сгенерированный исходник для обоих профилей EEPROM. + source_file.write_text(model, encoding="utf-8") # Сохраняет русские комментарии и извлечённые исходники без потери кодировки. + for profile in (0, 1): # Проверяет обе ветви маршрутизации CAN: AT25256B и M95M02. + library = build / (f"can_init_{profile}.dll" if os.name == "nt" else f"can_init_{profile}.so") # Разделяет библиотеки, чтобы профиль не подменял результат соседней сборки. + command = [compiler, "-O3", "-shared", "-Wall", "-Wextra", "-Werror", f"-DEEPROM_M95M02={profile}"] # Проверяет рабочий код с оптимизацией O3 и запрещает скрывать предупреждения модели. + command.append("-Wno-misleading-indentation") # Допускает существующие смешанные отступы Handlai без изменения проверяемого исходника TI. + if os.name != "nt": # Учитывает требования загрузки разделяемых библиотек ELF на Linux. + command.append("-fPIC") # Генерирует переносимые адреса только там, где они нужны формату библиотеки. + command += ["-I" + str(protocol / "ports/tms320f28335"), str(source_file)] # Передаёт модели официальные объявления порта C28x и текущий извлечённый код. + command += [str(protocol / "src/ump_protocol.c"), str(protocol / "ports/tms320f28335/ump_tms28335.c"), "-o", str(library)] # Линкует настоящие валидатор и упаковщик фрагментов вместо их заглушек. + subprocess.run(command, cwd=root, env=environment, check=True) # Прерывает проверку при ошибке любого профиля до объявления успешного результата. + runner = "import ctypes,sys; result=ctypes.CDLL(sys.argv[1]).run_tests(); print('PASS' if result==0 else f'FAIL: C line {result}'); sys.exit(bool(result))" # Возвращает строку неуспешной проверки C без зависимости от assert и режима NDEBUG. + subprocess.run([sys.executable, "-c", runner, str(library)], cwd=root, env=environment, check=True) # Освобождает DLL завершением дочернего процесса перед очисткой временного каталога Windows. + print(f"EEPROM_M95M02={profile}: холодный старт и первый запрос CAN проверены при -O3") # Показывает независимо подтверждённый результат каждого аппаратного профиля.