реклама на сайте
подробности

 
 
> SysTick в Cortex-M3, Вопрос по регистрам.
Omnicake
сообщение Mar 24 2014, 00:16
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 12-01-14
Из: Омск
Пользователь №: 80 002



Здравствуйте, пытаюсь разобраться в логике включения таймера SysTick на Cortex-M3, которую использует стандартная библиотека CMSIS. Взять, например, команду загрузки в регистр SYST_RVR: за это дело в CMSIS отвечает команда вида "SysTick->LOAD=TimerTick", где TimerTick - выбранное время через которое таймер будет обнулять свое значение. В дизассемблере данная команда представляет из себя три команды на ассемблере:
LDR r0,[pc,#32] ; @0x08000210;
MOV r1,#0xE000E000;
STR r0,[r1,#0x14];

Команда MOV в данном случае, как я понял, пишет в R1 стартовый адрес всего регистра SysTick, затем командой STR смещает его на 14 бит, попадая на адрес SYST_RVR (однако при этом я почему-то не вижу, чтобы регистр R1 менялся). А вот, что делает первая строка, почему она взаймодействует с программным счетчиком, и где в этих трех командах происходит загрузка самого значения TimerTick, я не могу понять. Потому прошу помощи.
Проект запущен на Keil mVision, процессор STM32f10x.

Самому удалось разобраться, откуда берется TimerTick, но использование первой строчки все равно осталось загадкой.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
zhevak
сообщение Mar 24 2014, 02:08
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Ваша проблема в том, что Вы не знаете команд Cortex. Вы их неправильно понимаете.

Команда

LDR r0,[pc,#32] ; @0x08000210;

загружает в регистр R0 4-байтное значение (число), которое находится рядом с кодом программы. Доступ к этому значению осуществляется относительно программного счетчика. В комментариях к листингу указан адрес -- 0х08000210.

Видимо, в исходном тексте программы Вы описывали переменную (точнее -- константу). А это ничто иное, как данные. Данные бывают разные -- константы, переменные. Переменные бывают инициализированными и неинициализированными. Кроме данных, в программах присутствует код. В общем, программа состоит из разного рода кирпичиков.

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

Эти кучки называются секциями. Вы наверно уже встречались с их названиями -- .text, .bss, .data и так далее. Названия секций у разных компиляторов (линковщиков) могут отличаться. Я сижу в Линуксе и использую gcc, Вы сидите под Виндовсом и используете Кайл. У нас секции скорее всего будут называться по-разному. Но назначение секций, как правило, соблюдается.

Итак, возвращаемся к Вашей программе. У вас в коде, было какое-то определение данных. Эти данные после линковки попали на адрес, который находится рядом с секцией кода. Чтобы переместить эти данные (значение) из памяти в регистр, понятно, нужно как-то адресовать эту ячейку памяти. Для данного случая оказалось удобнее адресовать ее относительно программного счетчика, что и было сделано приведеной выше командой.


Следующая команда

MOV r1,#0xE000E000;

запиысывает в регистр R1 базовый адрес Системного Таймера.

Системный Таймер -- это группа регистров. Точно так же следует думать и про другие устройства. Например, порт ввода-вывода -- это тоже группа регистров с каким-то базовым адресом. USART, DMA, ADC и так далее -- все эти устройства имеют по нескольку (иногда даже десятков) регистров.

С одной стороны, в микроконтроллерах многие устройства зачастую присутствуют в нескольких экземплярах. А с другой, адресное пространство для регистров практически не ограничено (как антипример, микроконтроллеры ATMEL AVR -- там куда-только не пихают регистры и биты!)

Поэтому оказывается, что более удобно выделить для конкретного устройства базовый адрес в этом адресном пространстве и более не париться с размещением битов и байтов. Но так как, допустим, портов ввода-вывода в микроконтроллере может быть несколько экземпляров, а они все одинаковые, то было бы разумно для каждого порта назначить какой-то базоавый адрес для группы его регистров. А доступ к конкретному регистру осуществлять относительно этого базоаого адреса. Таким образом, всё становится унифицировано и удобно

Следующая команда

STR r0,[r1,#0x14];

сохраняет содержимое регистра R0 по базовому адресу (который находится в регистре R1) плюс смещение 0х14.


(Простите за то, что опять написал много. Был в ударе.)


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th July 2025 - 00:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.01352 секунд с 7
ELECTRONIX ©2004-2016