Malloc, массив переменной длины или статический массив? - PullRequest
1 голос
/ 18 февраля 2012

Я разрабатываю программу для uC, которая считывает 40-байтовый битовый массив через SPI. Этот 40-байтовый массив является тестовым вектором, который сравнивается с «известным исправным» тестовым вектором, который хранится на SD-карте.

Чтобы найти аномалии / неисправности / ошибки, я XOR каждый байт полученного тестового вектора с сохраненными данными. Это приводит к битовому массиву, который имеет «1», где лежат ошибки. Я легко могу найти положение этих единиц, используя следующий алгоритм .

Беда в том, чтобы сохранить положение этих 1. В настоящее время я использую массивы переменной длины, но их поддержка в GCC4.2 не работает, поэтому я не уверен, насколько надежными они будут в AVR-GCC.

Моей следующей мыслью было использование malloc, но это обычно не рекомендуется во встроенных системах. Должен ли я просто объявить массив unsigned char длиной 320 и сохранить 1, когда я найду установленный бит? Пример: я нахожу биты 4, 8, 10, 42 и 250, установленные в моем битовом массиве. Затем я установил соответствующие элементы в «1», чтобы указать, что в этих позициях были обнаружены «1». Это заняло бы 320 байтов моего SRAM. В качестве альтернативы я мог бы объявить массив как int и сохранить фактическую позицию, начиная с вершины массива.

Зачем мне нужно устанавливать биты? SD-карта содержит другой файл, который содержит информацию, соответствующую позиции в битовом массиве. Таким образом, если в позиции 24 обнаружена ошибка, программа может пойти и прочитать файл и отобразить информацию обо всем, что ей известно, что связано с позицией 24.

ПРИМЕЧАНИЕ. Некоторые могут задаться вопросом, нужно ли мне читать весь тестовый вектор сразу. Это действительно так.

Ответы [ 2 ]

3 голосов
/ 18 февраля 2012

Если вы знаете верхнюю границу хранилища и она не обременительна, обычно лучше просто создать массив фиксированного размера.

Как вы заявили, поддержка массивов переменной длины в некоторых реализациях не совсем корректна, а в других - полностью недоступна. И malloc поставляется с дополнительными накладными расходами и включает в себя возможность его сбоя.

Я бы выбрал массив фиксированной длины не переменной длины (я думаю, что static - это вводящий в заблуждение термин, используемый здесь).


Теперь вопрос о том, используете ли вы символьный массив, где каждое значение указывает, является ли эквивалентный бит плохим, или целочисленный массив, где каждый элемент представляет собой последовательный список плохих бит, является другим вопросом.

Для начала я бы попытался минимизировать данные во втором случае использования, используя 16-битное значение - будь то short или int в вашей реализации, я не знаю.

Но поскольку у вас 320 бит, 8-битный символ не будет работать для битовой позиции, поэтому необходимо 16-битное значение.

Следовательно, для этого второго случая вам нужно будет использовать 640 байт, а не 320, для наихудшего случая, когда каждый бит в выборке плохой. Вы можете обойтись без необходимости подсчета ошибочных битов, сохранив значения -1 в неиспользуемых слотах этого массива.

Таким образом, на самом деле возможны варианты (например, для битовых позиций 42 и 314):

BytePos  BadBitFlag    or:     BytePos  BadBitPosition
0..41    0                     0/1      42
42       1                     2/3      314
43..313  0                     4/5      -1
314      1                     :
315..319 0                     638/9    -1

Это действительно зависит от ограничений хранилища.

Вы должны вычислять данные независимо от того, какой метод вы выберете, поскольку вы выбираете "биты" на основе символов в первом решении, то есть результат XOR необходимо будет расширить из массива битов в 40 байтов в байтовый массив в 320 байтов.

Если вы собираетесь много обрабатывать список плохих битов и можете сэкономить дополнительное хранилище, я бы выбрал второе решение.

Если вы собираетесь обрабатывать список только несколько раз или у вас очень мало памяти, выберите первое решение.

2 голосов
/ 18 февраля 2012

Если пространство стоит так дорого, зачем конвертировать весь массив в индексы одновременно?Я бы держался за 40-байтовый массив xor и перебирал его (используя алгоритм битового сдвига), когда вам нужно посмотреть смещение.

...