2012-02-18 4 views
1

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

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

Проблема заключается в сохранении положения этих «1». В настоящее время я использую Variable Length Arrays, но поддержка для них нарушена в GCC4.2, и поэтому я не уверен, насколько они надежны в AVR-GCC.

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

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

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

ответ

3

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

Как вы заявили, поддержка массива переменной длины является пятнистой в некоторых реализациях и полностью недоступна в других. И 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 байт.

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

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

+0

Будет ли массив символов хранить «1», где были установлены биты или массив int для хранения фактических позиций? – saad

+0

@saad, если вы можете сэкономить место, будет легче хранить каждый бит в переменной 'char'. Если нет, вам нужно будет хранить биты и использовать маскировку и смещение бит, чтобы получить их. – paxdiablo

+0

Возможно, я что-то недопонимаю, но мне не нужно маскировать или бить. Если у меня есть массив int, а первый «1», с которым я сталкиваюсь в моем битном массиве, равен 20, я сохраняю 20 в 0-м элементе в массиве int. Это будет массив позиций битов. Это потребует большего объема памяти (в два раза больше), но сократит время обработки, потому что цикл будет выполняться только в течение n раз, где n - это общее количество бит, которые были установлены в битовом массиве. Текущая система имеет 8K SRAM, из которых 40% уже потребляется. Мы добавим дополнительную SRAM - до 64K - при следующем вращении досок. – saad

2

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

+0

Поскольку тестовый вектор может содержать связанные ошибки в любой позиции. Ошибка в положении 5 может быть связана с неисправностью в позиции 25. Ваш подход будет работать, но если это так, он может предоставить более полную информацию оператору. – saad

+1

Ну, если вам нужно обработать информацию, вам, вероятно, придется ее каким-то образом организовать. Организуйте его, перебирая биты напрямую. Моя точка зрения состоит в том, что массив из битов 40x32 содержит точно такую ​​же информацию, как массив из целых нулей или единиц 1280. – alexis