Маллок висит

Эдвард.Хартманн
Пн 20 августа 2018 г. 14:26
Если я использую Malloc () с размером, превышающим доступную память, то висит Malloc вместо возвращения нулевого указателя. Есть ли способ обойти это?

Хейсан
Пн 20 августа 2018 г., 14:51
[Эдвард.Хартманн - Пн 20 августа 2018 г. 14:26] - ...Есть ли способ обойти это?
Не выделяйте больше, чем доступная память ;) .

Без ОС для вынесения памяти у более простых встроенных алгоритмов нет чеков.

Если вы хотите, чтобы какой -то код реализовал свою бесплатную проверку оперативной памяти, есть недавняя поток, которая охватывает это:
ViewTopic.PHP?f = 3&t = 4009

Но будьте осторожны, так как Libc Malloc является распределителем блоков, поэтому он будет выделять больше, чем вы запрашиваете - насколько больше зависит от ряда эвристики.

РЕДАКТИРОВАТЬ:
Самая простая проверка свободного пространства должна быть что -то вроде: // multi encoder code with speed up values adapted for STM32-arduino by Matthias Diro // no caps for encoder pins needed: gives back wrong acc values // using gpio_read_bit instead of digitalRead gives about 4x more speed http://forums.leaflabs.com/topic.php?id=1107 #define MAXENCODERS 2 volatile int encstate[MAXENCODERS]; volatile int encflag[MAXENCODERS]; boolean A_set[MAXENCODERS]; boolean B_set[MAXENCODERS]; volatile int16_t encoderpos[MAXENCODERS]; volatile int encodertimer = millis(); // acceleration measurement int encoderpinA[MAXENCODERS] = {4, 6}; // pin array of all encoder A inputs int encoderpinB[MAXENCODERS] = {5, 7}; // pin array of all encoder B inputs unsigned int lastEncoderPos[MAXENCODERS]; // timer #define ENCODER_RATE 1000 // in microseconds; HardwareTimer timer(1); void setup() { Serial.begin(9600); initEncoders(); } void loop() { for (byte counter = 0; counter < MAXENCODERS; counter++) { if ((lastEncoderPos[counter] != encoderpos[counter])) { Serial.print("Encoder #"); Serial.print(counter); Serial.print(" Value "); Serial.println(encoderpos[counter]); encflag[counter] = LOW; lastEncoderPos[counter] = encoderpos[counter]; } } } // ********encoder function void readEncoders() { for (byte counter = 0; counter < MAXENCODERS; counter++) { if ( (gpio_read_bit(PIN_MAP[encoderpinA[counter]].gpio_device, PIN_MAP[encoderpinA[counter]].gpio_bit) ? HIGH : LOW) != A_set[counter] ) { A_set[counter] = !A_set[counter]; if ( A_set[counter] && !B_set[counter] ) { if (millis() - encodertimer > 3) encoderpos[counter] += 1; else encoderpos[counter] += 5; } encodertimer = millis(); } if ( (gpio_read_bit(PIN_MAP[encoderpinB[counter]].gpio_device, PIN_MAP[encoderpinB[counter]].gpio_bit) ? HIGH : LOW) != B_set[counter] ) { B_set[counter] = !B_set[counter]; if ( B_set[counter] && !A_set[counter] ) if (millis() - encodertimer > 3) encoderpos[counter] -= 1; else encoderpos[counter] -= 5; encodertimer = millis(); } } } void initEncoders() { encodertimer = millis(); // acceleration measurement for (byte counter = 0; counter < MAXENCODERS; counter++) { encstate[counter] = HIGH; encflag[counter] = HIGH; A_set[counter] = false; B_set[counter] = false; encoderpos[counter] = 0; pinMode(encoderpinA[counter], INPUT_PULLUP); pinMode(encoderpinB[counter], INPUT_PULLUP); lastEncoderPos[counter] = 1; } // timer setup for encoder timer.pause(); timer.setPeriod(ENCODER_RATE); // in microseconds timer.setChannel1Mode(TIMER_OUTPUT_COMPARE); timer.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update timer.attachCompare1Interrupt(readEncoders); timer.refresh(); timer.resume(); }

Рик Кимбалл
Пн 20 августа 2018 г. 15:17
[Эдвард.Хартманн - Пн 20 августа 2018 г. 14:26] - Если я использую Malloc () с размером, превышающим доступную память, то висит Malloc вместо возвращения нулевого указателя. Есть ли способ обойти это?
  • Вы можете предоставить свои собственные процедуры Malloc /Free _SBRK. Посмотрите в STM32STM32F1/VARIAINTS/GENERIC_STM32F103C/WIRISH/SYSCALLS.в
  • Вы могли бы сделать все возможное, что вам нужно в Setup () и самостоятельно выпустить.
  • Вы можете объявить глобальный буфер UINT8_T [8192] как глобальная переменная и управлять его использованием самостоятельно.
  • Вы можете сделать пользовательский класс C ++ и переопределить новую оператора и удалить процедуры. Снова зацепите все воспоминания, вам нужно заранее.
  • Вы можете изменить платформу.TXT и использование -Spec = nano.Спецификации для использования меньших/быстрее для выпуска процедуры Newlib Malloc

Хейсан
Пн 20 августа 2018 г., 17:44
Это не выглядит так, как будто у процессоров STM32 есть аппаратная поддержка для ограничений стека, поэтому у вас никогда не может быть «безопасного» распределения памяти. Всегда будет шанс на переполнение стека.

Вы можете предотвратить переполнение стека с небольшим изменением в _sbrk в Sycalls.C: disableDebugPorts();

Хейсан
Пн 20 августа 2018 г., 18:19
Как насчет чего -то подобного для _sbrk:
I2S.begin(I2S_PHILIPS_MODE, 48000, 16,1)

AG123
Вторник 21 августа 2018 12:56
Я видел код «бесплатного стека», который распространяется с SD-Fat в Util.час
disableDebugPorts();

Хейсан
Вторник 21 августа 2018 13:23
Это будет работать с Nano.спецификации (libc_s.а), но в стандартном LIBC есть распределитель блоков, поэтому он попытается захватить больше, чем просьба - вот почему я предложил изменение в _sbrk (). Malloc () в конечном итоге вызовет _sbrk () для приобретения памяти, поэтому, когда она вернется -1, Malloc вернется NULL, и, надеюсь, приложение будет обработать это чисто.

AG123
Вторник 21 августа 2018 13:29
Мои мысли - это настоящий Malloc (), нуждающийся в таблицах книги памяти для распределения блоков, 20K SRAM просто «слишком драгоценен», чтобы сохранить дополнительные таблицы для управления распределением блоков, этот «Malloc» в основном пытается создать «стек» каплей в «глобальной» области памяти. Строго говоря, MCU даже не будет беспокоиться об этом и может перезаписать «глобальную» область памяти, если она нуждается в ней для стека. Ну, я не слишком уверен в этом, но это кажется таким

Хейсан
Вторник 21 августа 2018 13:39
Я исследую способы замены Malloc () в легком весе. По умолчанию Malloc () большой (более 5 тыс. Флэш) и слишком сложный для среды MCU. Мне просто нужно выяснить, как сказать линкеру, чтобы пропустить связанные символы в LIBC.А и используйте их из локальной библиотеки. На данный момент я ослабляю весь LIBC, но это не распределимое решение.

AG123
Вторник 21 августа 2018 г. 13:44
Я думаю, что это не будет не Libc 'Malloc', а не что -то другое, что «пользовательский» Malloc должен был бы сделать книгу памяти таким образом, чтобы это не было «обычным» Маллоком. В некотором смысле я думаю, что это может быть очень похоже на концепцию C ++ «умных» указателей

Эдвард.Хартманн
Ср 22 августа 2018 г., 11:24
Спасибо за все ответы, мне действительно не нужно использовать Malloc, и я не понял, что Malloc был таким большим. - Я просто пытался использовать его, чтобы определить, сколько места было доступно, прежде чем определить большой массив для очереди на таймер событий, который я использую. Я просто продолжу размер вручную, когда накапливаю свой код, чтобы дать мне самый большой безопасный размер массива.

AG123
Ср 22 августа 2018 г., 19:10
Я думаю, что большинство из нас поступают из среды «большие системы», а не на «встроенных системах», и легко забыть, что эти MCU - это «маленькие машины», которые не поставляются с MMU
https: // en.Википедия.org/wiki/memory_managemage_unit
Нет ОС и более того, нет *виртуальной памяти *, так как долгое время назад, когда x86 становятся 286, 386 с переходом на 32 бита, является другим дополнением, которое является MMU, который создает виртуальный адрес 4 ГБ. Пространство, наряду с этим тщательно продуманным управлением памятью ядра ОС и библиотек и т. Д. Это делает возможным для защиты аппаратной памяти и, что более важно, *между процессами *

Я думаю, что STM32 (даже включая F1) имеет MPU, но MPU не MMU, и это в некоторой степени «темное искусство» (в значительной степени игнорируется, поскольку мысли есть (только) 20к шрама, U'd Просто используйте все, что там есть ;) )

Я сделал немного Google и столкнулся с несколькими статьями о в значительной степени игнорируемой/пренебрегаемой MP
https: // www.встроенный.com/electronics-bl ... Кора-мп
https: // www.ул.com/resource/en/applicat ... 272912.PDF
^^ Этот документ из ST рассказывает довольно смягченной архитектурой памяти Procesors Cortex-M, одна из упомянутых вещей-«Исправлена ​​карта памяти по умолчанию» (раздел 2.1 модель памяти). я.эн. Нет виртуального адреса, следовательно, вы не можете создать иллюзию, что приложение имеет всю память для себя и создает сложное управление ошибками страницы (E.глин. Вы не можете отделить «стек» и глобальную память, они находятся в той же * памяти)

Учитывая это, я думаю, вполне возможно, что стек растет вниз и перезаписывает «глобальную» память, где хранятся глобальные переменные (в конце концов, это 20 тыс. Срама). Если кто -то действительно хочу исследовать глубины, можно глубже углубиться в MPU, чтобы увидеть, как это может помочь.

Программирование с голой металла в значительной степени является своего рода компромиссом, в значительной степени основная основа, учитывая чрезвычайно ограниченную оперативную память и т. Д
Я подумал, что самая безопасная * динамическая * память - это * стек * (я.эн. локальные переменные), для очереди я использовал круговой буфер с фиксированной длиной
https: // chackaday.com/2015/10/29/Enced-W ... R-буферы/

Тянуть нити......

Проблема с SD -картой