Что вызывает ошибку адресации в 16-битной архитектуре?
Я работаю над кодом C для 16-битного микроконтроллера. Когда я отлаживаю приложение на цели, я в конечном итоге сталкиваюсь с ISR AddressError. Я прочитал таблицу данных, и там написано, что это может произойти, если вы попытаетесь прочитать или записать 16-битное значение, выровненное по нечетному адресу памяти. Я думаю, что понимаю, что это значит, но это не кажется правильным. Не означало бы, что если бы я сделал такую структуру:
struct foo{
uint8_t thing1;
uint16_t thing2;
};
что я никогда не смогу читать или писать в thing2 без ошибки? Если нет, значит ли это, что компилятор автоматически заполнит 8 битов между вещью 1 и вещью 2, чтобы вещь две была правильно выровнена по четному адресу? Если это так, то как может произойти ошибка адреса?
3 ответа
Вероятно, вам нужно изменить выравнивание структуры по умолчанию. Вы можете использовать либо прагму в своем коде, либо опцию компилятора. в случае gcc это -fpack-struct[=n]
В зависимости от того, как вы создаете это:
struct foo{
uint8_t thing1;
uint16_t thing2;
};
может быть выровнен по четному адресу, но если компилятор не достаточно умен, между thing2 не будет добавлено дополнение, которое влечет за собой то, что thing2 будет иметь нечетные адреса, следовательно, ошибка. Измените порядок членов или выполните поиск документации по компилятору (возможно, по некоторым директивам препроцессора прагмы), что позволит компилятору помочь вам согласовать ваши данные.
Большинство процессоров небольшого размера допускают только ограниченный набор операций с памятью, поскольку неправильное выравнивание чтения из памяти должно быть выполнено за два или более цикла и увеличит общую сложность процессора.
Это не часто отображается в коде c, так как переменные стека и члены структуры выровнены по собственной ширине типа (или 4 или 8 байтов, в зависимости от того, что меньше). Это можно переопределить с помощью упакованного атрибута, а также переназначить указатель на структуру с неправильно выровненным адресом. Таким образом, можно легко ознакомиться с исключениями смещения адреса.
Хотя например Intel 8086 поддерживает 16-битное чтение по невыровненным адресам, но при попытке доступа к границам сегмента пересечения слов (со смещением 0xffff) можно по-прежнему использовать исключение при генерации адреса.