|
|
  |
Хочу попробовать ARM, подскажите, что для этого нужно?, Какой проц выбрать, отлад. платку и какой софт? |
|
|
|
Jan 27 2007, 22:15
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 25-01-07
Пользователь №: 24 744

|
2sonycman Давай для точности, разберёмся с определениями. Есть тип константа. Есть тип указатель. Есть макрос #define. В первом случае резервируется регистр (или кусочек RAM) и заносится туда значение (если мы проинитим, если нет то вообще смысл в const теряется). Пример const x=5, если x компилятор назначит R0, то выражение y=x; равносильно y=R0.(вообще не понимаю использования типа const, просто так регистр теряем, разве что на размере программ с экономим, если загрузка числа во flash будет больше чем загрузка из R0). С типом указатель всё понятно. В общих чертах штука “локальная”. Тип #define это макрос. #define x 1 везде, где будет встречаться =x, будет явно =1. Адреса всей периферии фиксированные значения поэтому define использовать само то.
по-моему здесь допущена логическая ошибка: …Смотри: допустим, мы читаем данные из регистра статуса VIC через обычный, не-volatile указатель. Потом идут какие-то действия. И тут нам снова надо обратиться к этому регистру. Так вот - компилятор не будет повторно обращаться к регистру периферии, а использует уже прочитанное до этого (и сохранённое в одном из регистров CPU) значение…. Это будет выглядить примерно так: Int *adr; //создаём указатель на переменную типа int *adr=&x; //присваиваем переменной адрес x y=*adr; //присвоить у=x z=*adr; // здесь, судя по твоим размышлениям будет z=y, что не верно. Если использовать ссылку то будет загружено значение, на которое указывает ссылка, на то она и ссылка, а не по-другому. Или я не прав? Опять же, в упор не пойму использование ссылок на регистры. Хотя выражение: #define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000)) гибрид какой-то, не то ссылка, не то константа, не то число?
|
|
|
|
|
Jan 27 2007, 22:34
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
2Alex_inventor Давай  Const - запрешает любые операции по изменению значения переменной. То есть это уже не переменная - это константа, определённая раз и навсегда. #define - это вроде не макрос, а команда присвоения значения, как EQU в ассемблере. Цитата y=*adr; //присвоить у=x z=*adr; // здесь, судя по твоим размышлениям будет z=y, что не верно. Мы ведь говорим об ОПТИМИЗАЦИЯХ компилятора! Поэтому верхнее выражение будет вернее всего после компиляции таким: LDR R0, [PC, #20] - грузим указатель LDR R1, [R0] - грузим у MOV R2, R1 - грузим z так как указатель один и данные по этому указателю равны (!), какой смысл тратить драгоценные такты на повторное обращение к памяти? А вот именно volatile не даст сгенерить такой код. Я это так понимаю  Цитата #define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000)) гибрид какой-то, не то ссылка, не то константа, не то число? Там просто указатель на указатель на беззнаковое 32 битное значение  В памяти будет находиться 32 битное слово со значением 0xfffff000, которое при вызове будет загружено в регистр процессора, после чего он считает данные, на которые будет указывать этот регистр: LDR R0, [PC, #100] - R0 = 0xfffff000 (считано с адреса [PC+8+100]) LDR R1, [R0] - а теперь читаем периферию.
Сообщение отредактировал sonycman - Jan 27 2007, 22:48
|
|
|
|
|
Jan 27 2007, 23:55
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 25-01-07
Пользователь №: 24 744

|
Если быть точным, то EQU-это директива компилятора. Вводит названия для чисел. Например pi EQU 3.14. #DEFINE это макрос(по крайней мере в RealView). Команда для macro-процессора. Выполняется перед компиляцией. Чем отличается? В макрос можно передавать данные. Например #define sum(x,y) x+y превратится в inline функцию. Если использовать #defne x 3 то она будет эквивалентно EQU. Если использовать #define x 100+300+200 то это тоже превратится в EQU. Я макрос использовал в подпрограмме delay. Класно получилось. Выложу проект когда разберусь с проблемой распределения имён между файлами. Весь прикол в const, то что это как раз переменная. Кто сказал, что переменная не может быть константой? Есть же старый новый год  Под константу резервируете память и туда заносится значение. И объявление соответствующее const int x. А в программе, где нужна константа, вставляется не конкретное значение, а эта переменная. Косвенная адресация какое-то. Блин, мозги пухнут когда пытаюсь разобраться в это путанице. Ладно, попробуем. Int y,z; зарезервирует 2 регистра в банке, например R1,R2 (Кстати в CodeVision компилятор в комментариях указывал какие регистры он резервирует, очень удобно. Я этим постоянно пользовался когда в С вставке на asm вставлял) Int *adr; зарезервирует переменную в банке регистров, ну например R0 y=*adr; превратится в LDR R1, [R0] если сразу за этим будет x=y, всё будет корректно (правда смысла нет). Рассмотрим если между операторами будет ещё что ни-будь. Ну например: y=*adr; LDR R1, [R0] y=0; MOV R1, 0 x=*adr; LDR R2, [R0] Цитата так как указатель один и данные по этому указателю равны (!) Вообщем компилятор не знает равны там данные или нет. Ведь указатель это переменная. Мы можем занести любой адрес. Тогда получается, что любой адрес будет одинаковым, неверно, хотя реально!  Давай пофантазируем (да и посмеёмся  ) где здесь может компилятор соптимизировать. Допустим это константный указатель (который нельзя изменить) на константу. Тогда вместо косвенной загрузки LDR R1, [R0] будет вставлено уже вычисленное выражение, например MOV R1, 5. Хотя какая это оптимизация? Ну я незнаю тогда… И ещё тут просто причин нет для оптимизации. Ведь при присвоении значению х по указателю, не превращает x в указатель. Короче говоря истина рождается в спорах. Подискутируем, может найдём верный ответ. Цитата Там просто указатель на указатель на беззнаковое 32 битное значение В памяти будет находиться 32 битное слово со значением 0xfffff000, А где в памяти? Т.е. банальное const. Смысл использования которого я подвергал под сомнение выше. Тогда написали бы const int 0x123456. Да и указатель ли это? Внутри звёздочка справа стоит, для указателей слева ставится. Жду замечаний.
Сообщение отредактировал Alex_inventor - Jan 27 2007, 23:58
|
|
|
|
|
Jan 28 2007, 00:19
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
2Alex_inventor Можно тебя спросить, как давно ты начал программить на С?  Цитата Внутри звёздочка справа стоит, для указателей слева ставится. Вторая звёздочка тоже стоит слева от значения - (volatile unsigned long *) 0xFFFFF000 Это называется приведение типов (cast).  Цитата Вообщем компилятор не знает равны там данные или нет. Знает. В этом состоит суть оптимизации кода при компиляции. Цитата Ведь при присвоении значению х по указателю, не превращает x в указатель. Зато перед этим надо загрузить этот самый указатель из памяти. Цитата В памяти будет находиться 32 битное слово со значением 0xfffff000, А где в памяти? Да где угодно, это не важно, я просто пример привёл. Начни отлаживать любой проект в дебаггере - посмотри, откуда грузится в PC вектор RESET. Цитата Т.е. банальное const. Смысл использования которого я подвергал под сомнение выше. Тогда написали бы const int 0x123456. Ты лучше тогда почитай любую книжку по С, раз я не могу объяснить...
Сообщение отредактировал sonycman - Jan 28 2007, 00:20
|
|
|
|
|
Jan 28 2007, 02:46
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 25-01-07
Пользователь №: 24 744

|
На С работаю около года. Исключительно на микроконтроллерах. До этого программировал на asm. Прошёл путь PIC, MSK-51, AVR, вот теперь очередь до ARM дошла. Теперь по существу. (*((volatile unsigned long *) 0xFFFFF000)) volatile unsigned long * *((volatile unsigned long *) 0xFFFFF000) Я убрал парные скобки чтоб до звёздочек добраться и где звёздочки находятся? Цитата Это называется приведение типов (cast). Что такое приведение типов я прекрасно знаю. Перечитал главу в K&R (2.7 Преобразование типов.) Вырезки приводить не буду, но звёздочек там не встречал. Что такое cost прочитал впервые. Никогда не пользовался по причине слишком специфичности данной операции. Выражение (unsigned long ) 0xFFFFF000 есть пример cost. Но что делает звезда справа, и что на самом деле volatile обозначает? И зачем для адреса применять тип long(64bit), или в RealViwe long(32bit)? Цитата Знает. В этом состоит суть оптимизации кода при компиляции. Как компилятор может знать заранее значение переменной, на которое указывает указатель? Или мы друг друга не понимаем? Я много раз видел, как и что оптимизирует компилятор (я говорю про оптимизацию по размеру кода). Общие принципы оптимизации по пальцам пересчитать можно. Основная оптимизация это создание массива одинаковых кодовых последовательностей. И прыгание туда и обратно из программы. Далее идёт заранее вычисление выражений, которые можно просчитать до компиляции, в такие выражения не входят переменные, оптимизация сокращения кода, результаты которого одни и теже. Например r0=1; r0=1; Такая ситуация часто встречается при инициализации периферии в которой, в качестве защиты сделана необходимость дважды занести значения в регистр. В таких случаях выключают оптимизацию перед выражением и включают после. Ну и рискованный тип оптимизации, и как правило редко применяющейся, замена блоков кода, который по мнению компилятора выполняет определённый алгоритм, другим, оптимизированным, блоком кода выполняющий тот же алгоритм. Ни один из этих видов оптимизации не должен исказить загрузку по ссылке. Если я не прав приведите пример. Обсудим. Привожупример дизассемблера: LDR PC, Reset_Addr Reset_Addr DCD Reset_Handler Теперь становится понятно. Это особенности инструкции LDR. Она неможет включать в себя число, ну например как в AVR сделано – если идёт загрузка данных, то следующий за инструкцией байт это байт данных. LDR косвенно загружает регистр PC используя метку Reset_Addr, которая указывает на директиву резервирования и инициализации памяти DCD которая заносит число Reset_Handler которое проинициализировано EQU . Во какая цепочка! Самое интересное, что я давно обратил внимание на такое странное кодирование. А выражение (*((volatile unsigned long *) 0xFFFFF000)) это и делает. Но сама запись сбивает с толку. Я бы написал так flash int adr 123, ну или const int adr 123. В данном случае const уместна. Я же говорил в спорах рождается истина  . Цитата Ты лучше тогда почитай любую книжку по С, раз я не могу объяснить... Да читал я книжки по С. Но я не читаю их от корки до корки (как например худ. литературу) по причине другого подхода. Я читаю те главы, которые мне нужны в данный момент. И обсуждаемую книгу я не прочитал. Прочитал главы общей архитектуры, инициализация, UART. Сейчас пишу проект с UART. В принципе написал. Всё работает за исключением некоторых мелочей. По мере появления вопросов читаю новые главы. Сейчас буду осваивать прерывания, ну и читать про них. Буду постепенно наращивать проект, пока не подключу всю периферию. Всем
|
|
|
|
|
Jan 28 2007, 03:22
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Alex_inventor @ Jan 28 2007, 01:46)  (*((volatile unsigned long *) 0xFFFFF000)) Но что делает звезда справа, и что на самом деле volatile обозначает? Дословно *(unsigned long *) 0xFFFFF000 означает "значение типа unsigned long, на которое указывает указатель, содержащий адрес 0xFFFFF000". Или, что тождественно, "значение типа unsigned long, находящееся по адресу 0xFFFFF000". volatile заставляет компилятор при упоминании этого значения каждый раз считывать его заново, а не использовать сохраненное где-то считанное ранее значение. Цитата(Alex_inventor @ Jan 28 2007, 01:46)  Как компилятор может знать заранее значение переменной, на которое указывает указатель? Или мы друг друга не понимаем? Если он это значение недавно прочитал, и сам с тех пор не менял, то вправе предположить, что значение осталось неизменным и использовать сохраненное значение, экономя такты и/или код на повторном обращении к памяти. Цитата(Alex_inventor @ Jan 28 2007, 01:46)  В данном случае const уместна. const была приведена только как пример модификатора объявления переменной. С volatile const никак не связан, они существуют отдельно сами по себе. Цитата(Alex_inventor @ Jan 28 2007, 01:46)  Я читаю те главы, которые мне нужны в данный момент. Ну хотя бы по диагонали остальные просмотреть стоит. Чтобы понять, в каких главах есть что-то для Вас новое и, следовательно, какие главы стоит просмотреть внимательнее. Я, например, сочетаю этот подход с другим - если мне что-то не понятно, читаю дальше. Потом возвращаюсь в начало и читаю снова. После двух прочтений в голове начинает формироваться некоторая картина, которая после трех-четырех приобретает осмысленные формы.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 28 2007, 03:37
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
2Alex_inventor Я пробовал программить только PIC и AVR.  Иногда на персоналке что-нибудь мелкое стряпаю. Теперь вот тоже ARM захотелось пощупать  Цитата Сейчас буду осваивать прерывания, ну и читать про них. Буду постепенно наращивать проект, пока не подключу всю периферию. Это ты всё в Протеусе делаешь? Кстати, чем планируешь отлаживать девайс? Каким аппаратным дебаггером? Я вот думаю MT-Link заказать, но кряка для RDI драйверов под Keil нигде не могу найти  2Сергей Борщ Спасибо за помошь  Сколько у ARMов регистров управления портами ввода-вывода ! Штук двадцать, наверное! Для каждой функции один для установки битов, другой для снятия, третий для статуса. Пока все аббревиатуры запомнишь !  Разъясните, плиз, по прерываниям: при возникновении какого-либо прерывания (FIQ или IRQ), по заданному вектору проц перенаправляется на процедуру обработки. Это понятно. А при выходе из обработчика это прерывание разрешается автоматически, или это надо делать самому? И, если программа пользователя работала в THUMB режиме, то будет ли корректно восстановлен этот режим при выходе из обработчика? Имею ввиду, заложены ли эти механизмы аппаратно в ядро, или это всё надо делать ручками перед выходом из обработчика прерывания?
Сообщение отредактировал sonycman - Jan 28 2007, 04:09
|
|
|
|
|
Jan 28 2007, 04:40
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 25-01-07
Пользователь №: 24 744

|
2 Сергей Борщ Цитата Ну хотя бы по диагонали остальные просмотреть стоит. А я и не отрицал этого. Разумеется я просматриваю подробно оглавление и мельком каждую главу. Это необходимое условие что бы иметь общее представление и возможность ориентации. По-другому никак. Иначе как оперативно найти нужные ответы? Углубленно изучаю только необходимые в данный момент главы. Вообщем как справочник. Цитата С volatile const никак не связан, они существуют отдельно сами по себе. Объясните мне в чём такая принципиальная разница? Хотябы небольшая? Цитата volatile заставляет компилятор при упоминании этого значения каждый раз считывать его заново, а не использовать сохраненное где-то считанное ранее значение. Зачем это делать? Какое сохранение времени, тиков? Чтение из flash одна инструкция процессора (LDR PC, Reset_Addr) Цитата а не использовать сохраненное где-то считанное ранее значение. Как это понимать? Если мы присвоим x=*adr, то что компилятор будет наивно полагать что переменная х никогда не изменится и будет использовать её как источник адреса? Хотя выигрыша мы не получим, нельзя оптимизировать одну инструкцию процессора, если не выкинуть её вообще. Извините, если кому-то покажется агрессивным стиль написание, так получилось. Цитата Дословно *(unsigned long *) 0xFFFFF000 означает "значение типа unsigned long, на которое указывает указатель, содержащий адрес 0xFFFFF000". Или, что тождественно, "значение типа unsigned long, находящееся по адресу 0xFFFFF000". Ну если быть точным, насколко я понял, то выражение полностью выглядит так: #define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000)) и означает определение метки VICIRQStatus которое указывает на облость памяти с константой u long имеющую значение 0xFFFFF000. Обращаю особое внимание на слова МЕТКИ, а не указателя. Метка это число, таже константа и менятся не может, а указатель это переменная и может указывать на что угодно в любой момент времени, смотря сто занесёшь туда. Цитата Если он это значение недавно прочитал, и сам с тех пор не менял, то вправе предположить, что значение осталось неизменным и использовать сохраненное значение, экономя такты и/или код на повторном обращении к памяти. Дело в том, что компилятор не может недавно прочитать значение по ссылке . Ссылка это переменная. Недавно прочитать может только работающая программа. Когда компилятор уже давно сделал сваи дела и гордо удалился. В общем, подвожу итог: структура define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000)) разложена по полочкам, стала понятна, появилась осмысленная возможность её использование. Хотя некоторые аспекты так и не объяснены (например, расположение звезды справа).
|
|
|
|
|
Jan 28 2007, 05:16
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 25-01-07
Пользователь №: 24 744

|
2sonycman А у тебя proteus есть? Ты им когда-нибудь пользовался? Если нет, то не видел счастья в жизни!!! Хотя я тебя не виню, если это так. Сам случайно начал им пользоваться. Хотя в протеусе глюк на глюке и глюком погоняет, но всё равно это сказочная среда!!! Нужно просто ожидать от неё то, что она может тебе дать. Аналогов даже приблизительных у неё нет!!! Вобщем если никогда не пользовался, то опишу кратко. Перед тобой экран на котором ты строишь электрическую схему. Интерфейс максимально интуитивно понятный, и максимально удобный. Короче ставишь проц. Там есть Philips 5 видов. Указываешь адрес прошивки, нажимаешь симуляцию… и вот тебе счастье!!! При этом на ноги навешиваешь куча разноцветных светодиодов, lcd всех видов, подключаешь к процу реальный COM компа и туда подключаешь железо, т.е твой виртуальный проц управляет реальным железом!!! Я так делал круто!!! Та же история и с LPT. Далее подключаешь виртуальный COM (который появляется в системе) и твоя прога на С++ подключившись к этому COM общается с процом. Далее подключаешь Несколько виртуальных терминалов. Ставишь микросхемы I2C, SPI, MMC на все шины вешаешь мониторы(типа отлеживать активность в текстовом виде по I2C) Включаешь виртуальные самописцы, осциллографы, вольтметры, амперметрыб подключаешь громкоговоритель и у тебя на звуковую карту выводится фигня с контроллера или куда ты там подключишь вывод. Ставишь ещё кучу контроллеров AVR, PIC, MSK-51, в каждом своя прошивка, подключаешь кучу микросхем жёсткой логики, ставишь кучу аналоговой логики (транзисторы, резисторы, конденсаторы и т.д.) И всё это без единой строчки писанины, выбираешь элемент и ставишь, ставишь, СТАВИШ!!!  Картина РЕПИНА! Короче нажимаешь пуск и балдеешь от происходящей какофонии!  И это малая возможность, что может среда. Стоит ли говорить, если она поддерживает эмуляцию десятка тысяч элементов. Там есть даже таки прикольные элементы как сенсорная ЖК панель 640x480. Там в примерах есть проект, где на АРМе и этой панели шахматы сделаны. Я играл, прикольно. Я выиграл  Правда машину надо мощную иметь. У меня 2.8Г шина 533МГ и то не хватает в некоторых случаях. Я куски кода только в нём отлаживаю, а потом в железо программирую, и как нистранно, сразу всё работает, без отладки!
|
|
|
|
|
Jan 28 2007, 05:36
|
Участник

Группа: Новичок
Сообщений: 54
Регистрация: 25-01-07
Пользователь №: 24 744

|
Добавлю ещё пару строк о PROTEUS. Прошивки можно загонять как в .hex так и в объектном виде. Во втором случае можно по-шагоао ходить по С программе делать точки остановки. Причём в любой момент можно посмотреть внутреннее состояние любого программного элемента. Это всякая там память, а в контроллеры вообще на изнанку вывернуть. На тебе и память и периферия, и РОН и что хочешь. По инету ходят слухи, что скоро выйдет 10 версия. То там наверное вообще можно тушить свет, и блаженствовать. Кстати если очень хочется какой-нибудь элемент, а его нет в библиотеке, то есть возможность сделать его самому. Макро блоки вообще проще пареной репы, напихал уже готовых элементов, соединил по нужному, сделал выводы, нажал кнопочку. Инна тебе микросхема суррогатного производства. Да много элементов нет, но практически у каждого есть двойник. Эту среду не надо использовать как точную копию действительности, как некоторые делают и разочаровываются. В ней надо испытывать общие алгоритмы, принципы, куски прошивок, частей схем, как аналогового вида так и цифрового. А затем всё долизать в железе, причём 90% работы уже сделана.
|
|
|
|
|
Jan 28 2007, 11:29
|
Участник

Группа: Новичок
Сообщений: 73
Регистрация: 10-01-07
Пользователь №: 24 292

|
Цитата(Alex_inventor @ Jan 28 2007, 05:16)  А у тебя proteus есть? Ты им когда-нибудь пользовался? Если нет, то не видел счастья в жизни!!! Хотя я тебя не виню, если это так. Сам случайно начал им пользоваться. я тоже случайно наткнулся на - [skipped] - скачал 6.9 sp 5 и очень полюбил эту штуку.
|
|
|
|
|
Jan 28 2007, 13:42
|
Знающий
   
Группа: Свой
Сообщений: 793
Регистрация: 5-11-04
Из: Краматорск, Украина
Пользователь №: 1 057

|
Цитата(Alex_inventor @ Jan 27 2007, 16:48)  2Andy Great Компилятор я качал с keil.com. Он лежит на одной странице, где и сам uVision. Файл является установщиком (gccARM331.exe). Я ничего не настраивал, он сам установил себя в папку с:\ Cygnus и ещё некоторые манипуляции с реестром, по-моему, проделал. На диске есть готовые проекты. В каждом проекте в настройках указан GCC. Так вот, если я нажимаю компиляцию, то выскакивает ошибка. Проекты необходимы только для использования при прочтении книги, и всё! В чём причина разбирается, не хочу (осваиваю RealViwe). Повторяюсь, это не отдельные файлы, а целые проекты, с настройками компилятора и т.д. По этому всё сразу должно заработать. Сей факт пусть остаётся на совести автора. P.S. В некоторых проектах настолько очевидные ошибки, что становится понятно, что автор их никогда и не компилировал. Например использование putchar(), а #include<stdio.h> и в помине нету. "выскакивает ошибка" - неинформативно. Какая ошибка? Почему у меня (на том же компилере, пример Blinky для AT91SAM7S) не выскакивает? Не поленюсь повторить: ну не устанавливайте программы в каталоги с пробелами, если не уверены. "По этому всё сразу должно заработать." - у меня и работает, все не проверял, но то, что проверил - работает, даже в плату загружал - и там моргает. P.S.: В "некоторых проектах", если читать внимательно, putchar реализуется, а не импортируется из библиотеки, да если доку читать, там так и написано: реализуйте свой putchar. Видно, что Вы пришли в программирование МК с программирования ПК, где putchar реализован в библиотеках (хотя и его можно переопределить).
|
|
|
|
|
Jan 28 2007, 13:54
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(sonycman @ Jan 28 2007, 02:37)  Сколько у ARMов регистров управления портами ввода-вывода ! Штук двадцать, наверное! Для каждой функции один для установки битов, другой для снятия, третий для статуса. Пока все аббревиатуры запомнишь !  Причем практически все заполняются только один раз - при старте программы, а в дальнейшем используются три, как и в AVR. Или в дальнейшем пользуются макросы ( например такие) и вообще забываешь как называются эти регистры до написания кода инициализации в следующем проекте. Цитата(sonycman @ Jan 28 2007, 02:37)  Разъясните, плиз, по прерываниям: при возникновении какого-либо прерывания (FIQ или IRQ), Процессор переходит на адрес 0x1С или 0x18 (ARM DDI 0210C, стр 2-21). В момент перехода регистр статуса CPSR (ARM DDI 0210C стр. 2-13), который определяет состояние (THUMB/ARM), режим (User, Svc, Irq..), разрешение прерываний сохраняется в специальном регистре (SPSR_xxxx). В регистр статуса автоматически заносится значение, переключающее процессор в нужный режим (ARM DDI 0210C стр. 2-17). Дальше он предоставлен программисту - тут может стоять ветвление по вектору из контроллера прерываний или процедура обработки, которая где-то внутри себя осуществляет ветвление на обработчики конкретных источников прерываний. Как вариант - тупая проверка флагов (у ADuC70xx контроллера прерываний нет). При выходе из прерывания регистр статуса восстанавливается из SPSR_xxxx, таким образом процессор попадает в то же состояние и режим в котором он находился до прерывания. Цитата(sonycman @ Jan 28 2007, 02:37)  Имею ввиду, заложены ли эти механизмы аппаратно в ядро, или это всё надо делать ручками перед выходом из обработчика прерывания? Заложено в ядро. Если писать на С, то достаточно объявить функцию обработчика с соответствующим квалификатором ( тут обсуждалось). А на ассемблере есть специальная команда, которая одновременно с переходом (возвратом из прерывания) восстанавливает регистр статуса.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|