Эдвард.Хартманн
Пн 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:
Вы можете предотвратить переполнение стека с небольшим изменением в _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-буферы/
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-буферы/