Сколько векторов исключений нужно заливать в прошивку?

Я играю с ARM, используя плату STM32F103C8T6 Blue Pill. Согласно его Руководство по программированию (раздел 2.3.4 Таблица векторов), всего должно быть 83 вектора исключений. набор. Однако это руководство заполняет только первые 6 и этот учебник первые 10. Любопытно, что я могу убедиться, что обе прошивки работают, как ожидалось, несмотря на отсутствие множества обработчиков исключений.

Чтобы уточнить, ниже я имею в виду именно ту часть, о которой я говорю (ссылка на исходный файл). Как видите, обработчик назначается только первым нескольким словам, а все последующее пространство используется для хранения раздела .text.

.section .isr_vector
.align  2
.global _isr_vector
_isr_vector:
    .long   __StackTop /* we will need this later */
    .long   Reset_Handler
    .long   Default_Handler
    .long   Default_Handler
    .long   Default_Handler
    .long   Default_Handler
    .long   Default_Handler
    .long   0
    .long   0
    .long   0
    .long   0
    .long   Default_Handler
    .long   Default_Handler
    .long   0
    .long   Default_Handler
    .long   Default_Handler

Это меня смущает: какое наименьшее количество обработчиков исключений мне нужно заполнить? В моем случае использования (который представляет собой не более чем игрушечный проект) исключений нет, поэтому могу ли я просто установить обработчик сброса?

В качестве бонуса в Руководстве по программированию указано, что «младший бит каждого вектора должен быть равен 1, что указывает на то, что обработчиком исключения является код Thumb». Однако приведенный выше код явно не соответствует этому соглашению, поэтому как он правильно вызывает обработчик сброса при загрузке?


person nalzok    schedule 04.02.2020    source источник


Ответы (2)


.thumb
.global _start
_start:
.word 0x20001000
.word one
.word two
.align
.thumb_func
one:
    b .
two:
    b .

arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -Ttext=0x08000000 so.o -o so.elf
arm-none-eabi-objdump -D so.elf

so.elf:     file format elf32-littlearm


Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   0800000d    stmdaeq r0, {r0, r2, r3}
 8000008:   0800000e    stmdaeq r0, {r1, r2, r3}
    
0800000c <one>:
 800000c:   e7fe        b.n 800000c <one>

0800000e <two>:
 800000e:   e7fe        b.n 800000e <two>

Во-первых, _start не требуется, вы получите предупреждение, проще просто вставить его туда.

Вам нужно объявить метку как функцию. Есть несколько способов сделать это в ассемблере GNU. .thumb_func - это просто, это не обязательно должна быть строка непосредственно перед тем, как вы можете иметь что-то другое между .thumb_func и меткой, но следующая метка помечается как функция.

Вы увидите, что вывод компилятора делает что-то вроде этого (используйте -save-temps или -S, чтобы увидеть вывод компилятора), есть другой способ объявить функцию в газе, для полноразмерной руки есть другой, который у вас есть использовать.

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

И, как указано, минимум две записи только потому, что вам нужно иметь что-то по смещению / адресу 4. Обратите внимание, что 0x08000000 сопоставляется с 0x00000000 при загрузке на этих платформах STM32. Минимум - это вектор сброса, если другие вам не нужны, но при смещении вам нужно заполнить первые четыре байта. Можно также поместить туда начальное значение указателя стека и установить тот же код позже.

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

Два - это минимум, но если в конечном итоге вы столкнетесь с ошибкой выравнивания или другой ошибкой, тогда он попытается найти вектор там, если четное число, то это проблема, если нечетное, а затем попробуйте выполнить с этого адреса (lsbit снят с компьютера, в нем нет нечетного числа, это просто механизм, указывающий на большой палец или руку). Таким образом, хотя технически один вектор, сброс - это минимум, вероятно, неплохо на всякий случай покрыть первые 16 (15).

.thumb
.global _start
_start:

.word 0x20001000
.word reset
.word loop
.word loop

.word loop
.word loop
.word loop
.word loop

.word loop
.word loop
.word loop
.word loop

.word loop
.word loop
.word loop
.word loop

.thumb_func
reset:
    b .

.thumb_func
loop:
    b .

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

По крайней мере, ответ P__J __ - это ответ. Я добавил этот ответ, чтобы ответить на вопрос lsbit.

person old_timer    schedule 04.02.2020
comment
не будет ли разборка на 8000004 0800000с? (где «один»?) - person Tommylee2k; 04.02.2020
comment
обработчик сброса находится по адресу 0x0800000c, поэтому вектор в таблице векторов должен быть 0x0800000c | 1, что составляет 0x0800000d - person old_timer; 04.02.2020
comment
в этом суть, в адресе должен быть установлен lsbit, чтобы процессор работал, если вы правильно используете инструменты (один), они сделают это за вас, если вы этого не сделаете (два), они не будут. - person old_timer; 04.02.2020
comment
В векторной таблице нет ничего особенного, это просто таран. Вы имели в виду ром? Поскольку AFAIK, векторные таблицы хранятся во флеш-памяти вместе с .text, а не в RAM. - person nalzok; 04.02.2020
comment
Кроме того, у меня сложилось впечатление, что _start обычно используется как точка входа, а не для обозначения начала таблицы векторов? - person nalzok; 04.02.2020
comment
... и еще кое-что: вы собираетесь формировать цикл с bx lr? Это похоже на инструкцию вернуться к процедуре вызова. (Извините, что задаю так много вопросов, но я действительно новичок) - person nalzok; 04.02.2020
comment
да, это была ошибка, собиралась вернуться и исправить то, что должно было быть б. не bx lr. фиксированный - person old_timer; 04.02.2020
comment
когда у вас есть операционная система, в которой есть загрузчик, нетрудно будет поддерживать точку входа в эту программу и способ указать это. Цель здесь - сделать байты, которые вы вставляете во флеш-память, нет загрузчика, а точка входа определяется логикой процессора, а не операционной системой или инструментом, поэтому _start не используется, просто поместите его где-нибудь, чтобы инструмент не выдал предупреждение. - person old_timer; 04.02.2020
comment
да, в этом приложении, но с точки зрения оружия, это просто адресное пространство - person old_timer; 04.02.2020

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

person 0___________    schedule 04.02.2020
comment
Я действительно помню один неожиданный момент, когда JLink отказался загрузить мой код, и, насколько я помню, программное обеспечение JLink ожидало, что контрольная сумма будет помещена в ячейку памяти в векторной таблице. Контрольная сумма хранилась в одном из зарезервированных мест. Упоминаю, что на всякий случай у кого-то возникнут проблемы с очень короткой таблицей векторов. - person Elliot Alderson; 04.02.2020
comment
@ElliotAlderson J-link не размещает никаких данных самостоятельно. Этот комментарий не соответствует действительности. - person 0___________; 04.02.2020
comment
Это произошло много лет назад, поэтому, возможно, я не помню точного характера проблемы. - person Elliot Alderson; 04.02.2020
comment
@ElliotAlderson, так в чем причина вашего комментария? Вы только что сделали что-то не так. \ - person 0___________; 04.02.2020
comment
Причина моего комментария заключается в том, что когда-то программное обеспечение JLink не программировало устройство, если значения в векторной таблице не соответствовали определенным требованиям. Я очень прошу прощения за то, что не могу вспомнить подробности, но я подумал, что это может послужить ключом к разгадке для кого-то еще, у кого возникли проблемы. Мой комментарий не был направлен на критику или исправление вашего ответа. - person Elliot Alderson; 04.02.2020