yanvasilij
Свой-
Постов
321 -
Зарегистрирован
-
Посещение
Весь контент yanvasilij
-
Снова вернулся к попыткам собрать статическую либу. Проблема так и не решилась. Достоверно выяснилось следующее: 1) Когда я добавляю syscalls.o в статическую библиотеку вместе со всем остальным, то при компиляции приложения с использованием этой либы вылазит ошибка: c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-abort.o): In function `abort': abort.c:(.text.abort+0xa): undefined reference to `_exit' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-sbrkr.o): In function `_sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-signalr.o): In function `_kill_r': signalr.c:(.text._kill_r+0xe): undefined reference to `_kill' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-signalr.o): In function `_getpid_r': signalr.c:(.text._getpid_r+0x0): undefined reference to `_getpid' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-writer.o): In function `_write_r': writer.c:(.text._write_r+0x10): undefined reference to `_write' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-closer.o): In function `_close_r': closer.c:(.text._close_r+0xc): undefined reference to `_close' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-fstatr.o): In function `_fstat_r': fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-isattyr.o): In function `_isatty_r': isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-lseekr.o): In function `_lseek_r': lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek' c:/program files (x86)/gnu tools arm embedded/4.9 2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-readr.o): In function `_read_r': readr.c:(.text._read_r+0x10): undefined reference to `_read' collect2.exe: error: ld returned 1 exit status Но все перечисленные функции реализованы в syscalls.c! Почему он их не видит?! 2) Когда я исключаю из библиотеки syscalls.o и приликовываю ее на этапе компиляции приложения вместе с библиотекой, все компилируется без ошибок и прекрасно работает. Компилирую arm-none-eabi-gcc, линкую либу arm-none-eabi-gcc-ar, линкую приложение arm-none-eabi-gcc. Флаги следующие: #common flags SET(COMMON_FLAGS "-mthumb") SET(COMMON_FLAGS "${COMMON_FLAGS} -Wall") SET(COMMON_FLAGS "${COMMON_FLAGS} -mcpu=cortex-m3") SET(COMMON_FLAGS "${COMMON_FLAGS} -mlittle-endian") #common compiler flags SET(COMMON_CFLAGS "-D USE_STDPERIPH_DRIVER") SET(COMMON_CFLAGS "${COMMON_CFLAGS} -D USE_STDPERIPH_DRIVER") SET(COMMON_CFLAGS "${COMMON_CFLAGS} -D STM32F429_439xx") #SET(COMMON_CFLAGS "${COMMON_CFLAGS} --specs=rdimon.specs") #SET(COMMON_CFLAGS "${COMMON_CFLAGS} -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group") #c-files compiler flags SET(CMAKE_C_FLAGS "${COMMON_FLAGS} ${COMMON_CFLAGS}" CACHE INTERNAL "c compiler flags") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") #cpp-files compiler flags SET(CMAKE_CXX_FLAGS "${COMMON_FLAGS} ${COMMON_CFLAGS}" CACHE INTERNAL "cxx compiler flags") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics") #linker flags SET(CMAKE_EXE_LINKER_FLAGS "${COMMON_FLAGS}" CACHE INTERNAL "exe link flags") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-section") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ./linkScript/STM32F407ZG_FLASH.ld")
-
Осциллограф на трансформаторе ethernet
yanvasilij ответил yanvasilij тема в Интерфейсы
Спасибо! Именно то, что мне нужно. На осциллографе, получается, мы видели только link-импульсы, короткие и редкие. Следовательно что-то неладное на стороне микросхемы PHY. Начали проверять - выяснилось непропай на ноге генератора тактовой частоты. Пропаяли - все заработало. -
Ну вот как указать, чтобы либа собиралась arm-none-eabi-gcc-ar?
-
Доброго времени суток! Ситуация такая. Компилирую проект через make полученный cmake. Когда мне нужен просто исполняемый файл(alf, hex и т.п.) или просто статическая библиотека проблем нет, но мне нужно получать одновременно и статическую библиотеку и hex. Как выяснилось линковка статических либ осуществляется arm-none-eabi-gcc-ar, а линковка исполняемого файла arm-none-eabi-gcc. Как же сделать так, чтобы на выходе получать и то и то?
-
Осциллограф на трансформаторе ethernet
yanvasilij ответил yanvasilij тема в Интерфейсы
Пробовали, не помогло. -
Осциллограф на трансформаторе ethernet
yanvasilij ответил yanvasilij тема в Интерфейсы
Микросхемы KSZ8721 и KSZ8863. Обе могут работать с этим трасформатором, но у нас работает только KSZ8863, а вот KSZ8721 почему то не хочет. Скажите можно ли проверять работу трасформатора осциллографа так, как это делаем мы? Если нужно могу полностью подключение выложить, но надо ли? -
Осциллограф на трансформаторе ethernet
yanvasilij опубликовал тема в Интерфейсы
Вопрос вероятно идиотский, но ответа самостоятельно я так и не нашел. Есть две схемы с одинаковыми трансформаторами, но с разными микросхемами PHY. Первая схема работает отлично, моргают светодиоды link, есть пинги и т.п. На второй схеме нет ни линка ни пинга. Начали тыкать осциллографом и дошли в итоге до следующего: после траснформатора на ногах TPTX и TPRX на работающей схеме наблюдаем активную цифровую движуху (при подключенном сетевом кабеле разумеется); а на второй схеме после того же трасформатора нет никакого движения. Чтобы проверить, где проблема в физике или в трасформаторе решили поднять микросхему физики и посмотреть на особняком стоящем трансформаторе сигналы при подключенном сетевом кабеле. Так вот сигналы так и не появились (на неработающей схеме). Корректна ли такая проверка? Схему подключения трансформатора привожу ниже. -
PHY драйвер для KSZ8863
yanvasilij ответил yanvasilij тема в ARM
Вообщем еще раз перепроверил - действительно пины перепутаны! Перепаял и все заработало - пинги есть, как свитч все прекрасно работает. Спасибо Вам огромное! -
PHY драйвер для KSZ8863
yanvasilij ответил yanvasilij тема в ARM
Вообщем есть у меня проект под eval c KSZ8721 со стеком RL TCPnet. На eval все пингуется и работает. Начал переносить все тоже самое на KSZ8863, разница там только в микросхеме физики и схеме ее подключения (используются другие "ремапные" ноги). Переделал инициализацию EMAK по аналогии с тем, что было для KSZ8721, вот что получилось (тут с подсветкой): void init_ethernet (void) { /* Включаю тактирование на порты в.в. */ ... /* Initialize the ETH ethernet controller. */ U32 regv,tout,id1,id2,conn; /* Enable System configuration controller clock */ RCC->APB2ENR |= (1 << 14); /* Reset Ethernet MAC */ RCC->AHB1RSTR |= 0x02000000; SYSCFG->PMC |= (1 << 23); RCC->AHB1RSTR &= ~0x02000000; RCC->AHB1ENR |= 0x1E000047; /* Configure Port A ethernet pins (PA.1, PA.2, PA.7) */ GPIOA->MODER &= ~0x0000C03C; GPIOA->MODER |= 0x00008028; /* Pins to alternate function */ GPIOA->OTYPER &= ~0x00000086; /* Pins in push-pull mode */ GPIOA->OSPEEDR |= 0x0000C03C; /* Slew rate as 100MHz pin */ GPIOA->PUPDR &= ~0x0000C03C; /* No pull up, no pull down */ GPIOA->AFR[0] &= ~0xF0000FF0; GPIOA->AFR[0] |= 0xB0000BB0; /* Pins to AF11 (Ethernet) */ /* Configure Port C ethernet pins (PC.1, PC.4, PC.5) */ GPIOC->MODER &= ~0x00000F0C; GPIOC->MODER |= 0x00000A08; /* Pins to alternate function */ GPIOC->OTYPER &= ~0x00000032; /* Pins in push-pull mode */ GPIOC->OSPEEDR |= 0x00000F0C; /* Slew rate as 100MHz pin */ GPIOC->PUPDR &= ~0x00000F0C; /* No pull up, no pull down */ GPIOC->AFR[0] &= ~0x00FF00F0; GPIOC->AFR[0] |= 0x00BB00B0; /* Pins to AF11 (Ethernet) */ /* Configure Port B ethernet pins (PB.12, PB.13) */ GPIOB->MODER &= ~0x0F000000; GPIOB->MODER |= 0x0A000000; /* Pin to alternate function */ GPIOB->OTYPER &= ~0x00003000; /* Pin in push-pull mode */ GPIOB->OSPEEDR |= 0x0F000000; /* Slew rate as 100MHz pin */ GPIOB->PUPDR &= ~0x0F000000; /* No pull up, no pull down */ GPIOB->AFR[1] &= ~0x00FF0000; GPIOB->AFR[1] |= 0x00BB0000; /* Pin to AF11 (Ethernet) */ /* Configure Port B ethernet pins (PB.11) */ GPIOB->MODER &= ~0x00C00000; GPIOB->MODER |= 0x00800000; /* Pins to alternate function */ GPIOB->OTYPER &= ~0x00000800; /* Pins in push-pull mode */ GPIOB->OSPEEDR |= 0x00C00000; /* Slew rate as 100MHz pin */ GPIOB->PUPDR &= ~0x0FF00000; /* No pull up, no pull down */ GPIOB->AFR[1] &= ~0x0000F000; GPIOB->AFR[1] |= 0x0000B000; /* Pins to AF11 (Ethernet) */ ETH->DMABMR |= DBMR_SR; while (ETH->DMABMR & DBMR_SR); conn = 0; /* HCLK Clock range 100-120MHz. */ ETH->MACMIIAR = 0x00000004; /* Put the LAN8700 in reset mode */ write_PHY (PHY_REG_BCR, 0x8000); /* Wait for hardware reset to end. */ for (tout = 0; tout < 0x100000; tout++) { regv = read_PHY (PHY_REG_BCR); if (!(regv & 0x8000)) { /* Reset complete */ break; } } /* Check if this is a KSZ8863 PHY. */ id1 = read_PHY (PHY_REG_PID1); id2 = read_PHY (PHY_REG_PID2); if (((id1 << 16) | (id2 & 0xFFF0)) == 0x221430) { /* Use autonegotiation about the link speed. */ write_PHY (PHY_REG_BCR, PHY_AUTO_NEG); /* Wait to complete Auto_Negotiation. */ for (tout = 0; tout < 0x100000; tout++) { regv = read_PHY (PHY_REG_BSR); if (regv & 0x0020) { /* Autonegotiation Complete. */ break; } } } /* Check the link status. */ for (tout = 0; tout < 0x10000; tout++) { regv = read_PHY (PHY_REG_BSR); if (regv & 0x0004) { conn |= PHY_CON_SET_FULLD; /* Link is on. */ break; } } /* Initialize MAC configuration register */ ETH->MACCR = MCR_ROD; /* Configure Full/Half Duplex mode. */ if (regv & 0x0004) { /* Full duplex is enabled. */ conn |= PHY_CON_SET_FULLD; } else { /* Half duplex mode. */ } /* Configure 100MBit/10MBit mode. */ if (regv & 0x0002) { /* 10MBit mode. */ } else { /* 100MBit mode. */ conn |= PHY_CON_SET_100M; } /* Configure Full/Half Duplex mode. */ if (conn & PHY_CON_SET_FULLD) { /* Full duplex is enabled. */ ETH->MACCR |= MCR_DM; } /* Configure 100MBit/10MBit mode. */ if (conn & PHY_CON_SET_100M) { /* 100MBit mode. */ ETH->MACCR |= MCR_FES; } /* MAC address filtering, accept multicast packets. */ ETH->MACFFR = MFFR_HPF | MFFR_PAM; ETH->MACFCR = MFCR_ZQPD; /* Set the Ethernet MAC Address registers */ ETH->MACA0HR = ((U32)own_hw_adr[5] << 8) | (U32)own_hw_adr[4]; ETH->MACA0LR = ((U32)own_hw_adr[3] << 24) | (U32)own_hw_adr[2] << 16 | ((U32)own_hw_adr[1] << 8) | (U32)own_hw_adr[0]; /* Initialize Tx and Rx DMA Descriptors */ rx_descr_init (); tx_descr_init (); /* Flush FIFO, start DMA Tx and Rx */ ETH->DMAOMR = DOMR_FTF | DOMR_ST | DOMR_SR; /* Enable receiver and transmiter */ ETH->MACCR |= MCR_TE | MCR_RE; /* Reset all interrupts */ ETH->DMASR = 0xFFFFFFFF; /* Enable Rx and Tx interrupts. */ ETH->DMAIER = ETH_DMAIER_NISE | ETH_DMAIER_AISE | ETH_DMAIER_RBUIE | ETH_DMAIER_RIE; } Не могу добиться пингов. Что я упускаю? -
PHY драйвер для KSZ8863
yanvasilij ответил yanvasilij тема в ARM
Движение на SMRXDV3 есть, даже без пингов (возможно потому, что железка подключена к локальной сети, где много чего ходит?). CRS_DV и TX_EN не перепутаны - проверил только что. А почему вы предположили, что они перепутаны, есть какие-то ньюансы? -
PHY драйвер для KSZ8863
yanvasilij ответил yanvasilij тема в ARM
Выкинув из схемы лишнее получается следующее: Да, я Вас обманул - используется специальная микросхема для тактирования -
PHY драйвер для KSZ8863
yanvasilij ответил yanvasilij тема в ARM
Чтобы проверить связь с микросхемой я запросил Physical Identifier. По даташиту он должен быть 0x0022 страшем и 0x1430 в младшем -> при считывании так и оказалось. Связь по RMII есть я так понимаю. HAL_ETH_ReadPHYRegister(&heth, 0x02, &high); HAL_ETH_ReadPHYRegister(&heth, 0x03, &low); Между внешними портами связь есть. Попробовал через этот свитч соедининить комьютер и роутер - все работает. Тактирование от внешнего кварца 25 МГц. -
PHY драйвер для KSZ8863
yanvasilij ответил yanvasilij тема в ARM
Нет у KSZ8863 помимо свитча есть еще MII/RMII для подключения к ЕМАК контроллеру. Вот у меня не получается заставить работать как раз эту часть, не могу добиться хотябы пингов. Вот и подумал спросить может уже кто оживлял. -
Вообщем проверил, как советовала Tanya - оказалась неверный тип термопары (я думал, что это тип K, а оказался тип E). Мне подогнали фирменный калибратор, который умеет эмулировать термопары, на нем все прекрасно работает. Спасибо всем за помощь!
-
PHY драйвер для KSZ8863
yanvasilij опубликовал тема в ARM
Доброго времени суток! Оживляю плату, у который в качестве физики эзернета заложена KSZ8863. Если у кого есть уже написанный драйвер для этой физики под RMII, поделитесь если не жалко. Буду очень признателен! -
Спасибо за подсказку! Действительно я совсем об это не подумал. Начал проверять и выяснил, что напряжение появлялось, как оказалось, из-за того, что сама плата слегка греется, нагревая тем самым Х.С., создавая разницу между Г.С. и Х.С. А когда я калибровал датчик холодного спая, то не поднес эталонный датчик вплотную к разъему. В результате датчик температуры ХС врал на 4-5 градусов. Это точно вносило погрешность в измерения. Но вот беда: все равно результаты идут неверные. При комнаной температуре показания казались корректными (совпадали с эталоном). Но стоило мне бросить термопару в стакан с кипятком, как стало ясно что показания неверные - 130 градусов на кипящей воде. Чем выше температура тем больше разница между эталоном и моими измерения с термопарой. Например: - Показания эталонного прибора - 35 C - Моя программа показала 41,72 - Термоэдс при этом была 0.481197 мВ - Температура холодного спая 30.04 Проверил градуировочную характеристку, зашитую в контроллер, - точно совпадает с ГОСТом. Что это может быть?
-
Спрошу в продолжении темы. Вообщем реализовал я вышеописанный алгоритм измерения. Вот только недавно у меня в руках оказалась реальная термопара и вот я пытаюсь добиться адекватных показаний от нее. Пока ничего толкового не выходит. Наблюдения следующие: - Термоэдс измеряется точно, я подавал эталонное напряжение и оно совпадало с тем, что выдавал мой микроконтроллер (проверил несколькими приборами) - Температура холодного спая тоже определяется точно (проверял датчиком PT100) - Термопара тип K куплена вот тут - Сама термопара и плата находятся в одном помещении при одной и той же температуре, но показания получаются следующие: ---- Температура в помещении и соотвественно холодного спая 28.5 С ---- Измеренное термоэдс -0.182997 мВ ---- Вычисленное значение температуры термопары 23.89 Код вычисления температуры и термоэдс (ВОТ ТУТ С ПОДСВЕТКОЙ СИНТАКСИСА): /** * @brief Градуировочные значения для термопары типа K от -270 до 1370 с шагом 10. * Всего 153 точки */ static const float calibrationTable[] = { -6.458, -6.441, -6.404, -6.344, -6.262, -6.158, -6.035, -5.891, -5.73, -5.55, -5.354, -5.141, -4.913, -4.669, -4.411, -4.138, -3.852, -3.554, -3.243, -2.92, -2.587, -2.243, -1.889, -1.527, -1.156, -0.778, -0.392, 0.0, 0.397, 0.798, 1.203, 1.612, 2.023, 2.436, 2.851, 3.267, 3.682, 4.096, 4.509, 4.92, 5.328, 5.735, 6.138, 6.54, 6.941, 7.34, 7.739, 8.138, 8.539, 8.94, 9.343, 9.747, 10.153, 10.561, 10.971, 11.382, 11.795, 12.209, 12.624, 13.04, 13.457, 13.874, 14.293, 14.713, 15.133, 15.554, 15.975, 16.397, 16.82, 17.243, 17.667, 18.091, 18.516, 18.941, 19.366, 19.792, 20.218, 20.644, 21.071, 21.497, 21.924, 22.35, 22.776, 23.203, 23.629, 24.055, 24.48, 24.905, 25.33, 25.755, 26.179, 26.602, 27.025, 27.447, 27.869, 28.289, 28.71, 29.129, 29.548, 29.965, 30.382, 30.798, 31.213, 31.628, 32.041, 32.453, 32.865, 33.275, 33.685, 34.093, 34.501, 34.908, 35.313, 35.718, 36.121, 36.524, 36.925, 37.326, 37.725, 38.124, 38.522, 38.918, 39.314, 39.708, 40.101, 40.494, 40.885, 41.276, 41.665, 42.053, 42.44, 42.826, 43.211, 43.595, 43.978, 44.359, 44.74, 45.119, 45.497, 45.873, 46.249, 46.623, 46.995, 47.367, 47.737, 48.105, 48.473, 48.838, 49.202, 49.565, 49.926, 50.286, 50.644, 51.0, 51.355, 51.708, 52.06, 52.41, 52.759, 53.106, 53.451, 53.795, 54.138, 54.479, 54.819 }; float TermocoupleKProcessor::calcTemperature (float eds) { int t = MIN_T, i, dt = DT; if (eds > calibrationTable[i = 0]) while (MAX_T >= t) { if (eds < calibrationTable[++i]) return t + (eds - calibrationTable[i-1]) * dt / (calibrationTable[i] - calibrationTable[i-1]); t += dt; }; return t; } float TermocoupleKProcessor::calcEds (float t) { float eds = calibrationTable[CALIBRATION_TABLE_LEN - 1]; float dEds, t0 = MIN_T; int i = 0; if ( t > t0 ) { while ( calibrationTable[CALIBRATION_TABLE_LEN-1] >= eds ) { i++; if ( t < (t0 + DT) ) { dEds = calibrationTable[i] - calibrationTable[i-1]; eds = calibrationTable[i-1] + ((t - t0) * dEds / DT); return eds; } t0 += DT; } eds = calibrationTable[CALIBRATION_TABLE_LEN-1]; } return eds; } Место, где это используется (C подсветкой синтаксиса): /* Измеряю температуру холодного спая */ ... //Измерения температуры холодного спая обычным термодатчиком опускаю ... data->coldJuncT = calcColdJuncTemperature(rtd); /* Вычисляю ЭДС холодного спая в МИЛЛИВОЛЬТАХ! */ data->cjEds = calcEds (data->coldJuncT); /* Измеряю ЭДС термопары */ ... //Опускаю измерения термоэдс ... data->tEds = data->tEds * 1000; //перевожу в милливольты! /* Вычисляю значение температры */ data->temperature = calcTemperature(data->tEds + data->cjEds); conversationIsReady = 1; /**< @brief Считывание завершено */ Почему может быть такая большая погрешность? Что я упустил, подскажите пожалуйста?
-
Функции требующие статической памяти
yanvasilij ответил yanvasilij тема в Программирование
Так и было сделано, typeSCalibrationTable[]={ .... } и подобные ему массивы объявлены в отдельных *.c файлах, внутри класса TermocoupleSProcessor используются лишь указатель на этот массив. extern const float *tcoupleScalibrationTable; //Таблица объявлена, где-то в другом месте class TermocoupleProcessorBase : public BarrierSensorProcessorBase { public: ... float const *tCoupleParams; /**< @brief Внутри класса лишь указатель на массив */ ... ... //В некотором месте программы происходит назначение этого указателя tCoupleParams = tcoupleScalibrationTable; ... }; -
Функции требующие статической памяти
yanvasilij ответил yanvasilij тема в Программирование
Ну да, похоже придется так и сделать. Не очень красивый способ, как мне кажется, но когда я переделал таким образом потребление памяти уменьшилось в разы. У меня кстати нет ртос в этом проекте, слишком мало памяти у проца и слишком много всего надо впихнуть. -
Функции требующие статической памяти
yanvasilij ответил yanvasilij тема в Программирование
Спасибо, теперь буду знать. Но я использую указатель на этот массив, разве это должно приводить к такому значительному увеличению потребления статически выделенной оперативной памяти? -
Функции требующие статической памяти
yanvasilij ответил yanvasilij тема в Программирование
Да компилятор keil. Моя вина - не сказал. Так и было с самого начала, в классе лишь указатель на этот массив. -
Функции требующие статической памяти
yanvasilij ответил yanvasilij тема в Программирование
stm32f042 -
Функции требующие статической памяти
yanvasilij ответил yanvasilij тема в Программирование
static const float typeSCalibrationTable[] = { -0.226, -0.188, -0.145, -0.1, -0.051, 0, 0.054, 0.111, 0.171, 0.232, 0.296, 0.363, ... много много значений ... }; -
Функции требующие статической памяти
yanvasilij ответил yanvasilij тема в Программирование
Нет, в том то и дело, что работа со стеком это динамика, статически выделяемая память при компиляции тут не при чем (точнее она при чем только при указании размера стека). Я не спорю с тем фактом, что увеличением вызовов увеличит потребление стека, это я понимаю. Проблема в том, что у меня увеличивается объем выделенной статической памяти, на этапе компиляции (секция ZI-data), при увеличении точек входа в эту злосчастную функцию в программе. typeSCalibrationTable уже как static const, я забыл это упомянуть. -
Функции требующие статической памяти
yanvasilij опубликовал тема в Программирование
Доброго времени суток! Столкнулся с тем, что не хватает памяти на микроконтроллере. Начал копать и выяснил, что больше всего памяти потребляет вызов функции, которая у меня занимается вычислениями по калибровочным таблицам (кусочно-линейная аппроксимация). Поскольку мое устройство должно поддерживать большое количество датчиков, вызов этой функции осуществляется из разных мест программы. Добавления каждого нового вызова этой функции вызывает у меня увеличение потребления статической памяти. Я долго думал можно ли с этим что либо поделать, но так и не придумал. Ниже привожу примеры использования.\ Собственно сами функции: float plaStraight (const float *calibrationTable, float delta, float minValue, float maxValue, float inValue) { int i; float outValue = minValue; if (inValue > calibrationTable[i = 0]) while (maxValue >= outValue) { if (inValue < calibrationTable[++i]) return outValue + (inValue - calibrationTable[i-1]) * delta / (calibrationTable[i] - calibrationTable[i-1]); outValue += delta; }; return outValue; } float plaStraight (const float *calibrationTable, float delta, float minValue, float maxValue, float inValue) { int i; float outValue = minValue; if (inValue > calibrationTable[i = 0]) while (maxValue >= outValue) { if (inValue < calibrationTable[++i]) return outValue + (inValue - calibrationTable[i-1]) * delta / (calibrationTable[i] - calibrationTable[i-1]); outValue += delta; }; return outValue; } float plaRevers (const float *calibrationTable, u32 len, float reversDelta, float minValue, float inValue) { float outValue = calibrationTable[len - 1]; float inValue0 = minValue; float straightDelta; int i = 0; outValue = calibrationTable[len - 1]; inValue0 = minValue; if ( inValue > inValue0 ) { while ( calibrationTable[len-1] >= outValue ) { i++; if ( inValue < (inValue0 + reversDelta) ) { straightDelta = calibrationTable[i] - calibrationTable[i-1]; outValue = calibrationTable[i-1] + ((inValue - inValue0) * straightDelta / reversDelta); return outValue; } outValue = calibrationTable[i]; inValue += reversDelta; } outValue = calibrationTable[len-1]; } return outValue; } Пример класса, в котором используются эти функции class TermocoupleSProcessor: public TermocoupleProcessorBase { public: virtual float calcTemperature (float eds) { return plaStraight (typeSCalibrationTable, 10.0, -50.0f, 1760.0f, eds); //<<<Добавления этой строчки приводит к большому выделению памяти } virtual float calcEds (float t) { return plaRevers(typeSCalibrationTable, CALIBRATION_TABLE_LEN, 10.0f, -50.0f, t);//<<<Добавления этой строчки приводит к большому выделению памяти } virtual void init (void) { sensorType = TermocoupleS; conversationIsReady = 0; } }; Объекты я объявляю статически. Для каждого типа термопары у меня по два объекта соответствующего класса. Добавления вызова plaStraight и plaStraight в каждом подобном классе приводит к резкому возрастанию выделения статической памяти. В итоге у меня ее просто не хватает. Что можно с этим поделать, есть идеи?