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

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

|
Цитата(Alex_inventor @ Jan 30 2007, 19:36)  По теме: Так как насчёт проекта. Для меня ответ на поверхности не лежит. Например: регистр VICRaw сигнализирует что, есть ”необработанное прерывание”. Как он может это делать, если VicIntSelect и VicIntEnabled равны 0. И почему происходит прерывание? И что произойдет, если находится в режиме User и использовать BX. Вроде ничего не должно, но в проекте идёт срыв в SWI.
2sonycman Ну да. А ты что тоже? Да нет, я из Тольятти... Вроде всё нормально с твоей прогой. Проходит инициализация, выполняется твой main() из трёх x++. А дальше программа заканчивается, и библиотечная __main (или куда там попадаешь?) вызывает SWI. Цитата(zltigo @ Jan 30 2007, 19:42)  Элементарно, на самом организуются две очереди - одна до переполнения, другая после. При переполнении счетчика меняется указатель на очередь. При ограничении диапазона половиной счетчика можно навернуь и логику обработки переполнения на старшем бите. При простом декременте это всё не нужно.
Сообщение отредактировал sonycman - Jan 30 2007, 18:46
|
|
|
|
|
Jan 30 2007, 19:03
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sonycman @ Jan 30 2007, 17:44)  При простом декременте это всё не нужно.  Не совсем понял к какому варианту относится "простой декремент", если к случаю в разностными счетчиками в очереди, то не нужен. Зато нужна проверка и при необходимости коррекция текущего счетчика при занесении новой заявки в очередь, снятии заявки, и особенно приятным становится коррекция уже заявленного таймера и всей очереди после него.... Плата за то, чтобы с этим не заморачиваться - переключение (причем крайне редкое относительно работы с таймерами) очереди. Программа обслуживания списка естественно одна и все проблемы при фиксации переполнения счетчика указать другую очередь. При постановке в очередь соответственно банальный контроль на больше/меньше текущего и выбор одной из двух очередей. При этом системный счетчик сам по себе вещь не бесполезная и получается бесплатно. Я использую именно вариант с двумя списками.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 30 2007, 19:09
|

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

|
Цитата(sonycman @ Jan 30 2007, 17:30)  Здесь смущает только ситуация, когда uiTimer0Count переполнится: 0xffffffff -> 0x0. При этом вычисления для текущих таймеров будут неверными. Нет, ничего страшного не происходит, поскольку он объявлен как unsigned и сравнение делается после беззнакового вычитания. Для примера возьмем восьмибитный unsigned, и пусть сейчас uiTimer0Count = 0xF8. Тогда nStartTimerVal = 0xF8, и допустим таймаут будет 12. Тогда когда таймер будет равен 0xF0, тогда getTimer()-(s) = 0xFF - 0xF8 = 7; Теперь таймер переполнился и стал равен 0. Тогда 0 - 0xF8 = 0xFF08, но поскольку результат округляется до тех же 8 бит, то получится 8. Как видите, ничего страшного не произошло. Надо только следить, чтобы сравнение происходило в тех же типах, что и тип uiTimer0Count. Для int это происходит автоматически. Для других типов желательно в макрос ввести явное приведение типов. Проще всего ввести для этого через typedef тип "таймаут" и именно этим типом объявить и uiTimer0Count и nStartTimerVal и в макросе сделать приведения к этому же типу. Тогда при переносе из проекта в проект надо будет только выбрать подходящий тип для таймаута. Как дальнейшее улучшение я бы еще объявил макрос типа MS() и MKS() который бы пересчитывал реальное время в милли- и микросекундах в соответствующее количество тиков исходя из частоты таймера. Тогда и при смене частоты таймера достаточно будет подправить только этот макрос: Код #define RTOS_TICK_RATE 500 // Hz #define RTOS_MS *RTOS_TICK_RATE/1000
void func() { OS::TBaseProcess::Sleep(30 RTOS_MS); } Цитата(zltigo @ Jan 30 2007, 18:03)  Я использую именно вариант с двумя списками. Можешь кинуть вырезку исходника?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 30 2007, 19:14
|
Участник

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

|
2sonycman У меня такие подозрения что дебагер глючит. Ну, во-первых прога не моя. Это стартовый код, который среда генерит. Я только заглушку main добавил. Во вторых, последовательность была следующая. Сделал примитивный проект. Всё OK. Добавил <stdio.h> и прога стала вываливатся в SWI ещё до того как до main дойдёт. Ну ладно. Подумал может где в библиотеке swi вызывается а я ниодного регистра VIC не инител (хотя вроде при ресете оно в default находится?) Убрал <stdio.h>, писал свои функции, всё OK. Потом поменял на <stdio.h>, опять в SWI прыгает. И самое интересное, что откат уже ничего не решал. Всё время в SWI. Пересоздал проект. Всё OK. Глюки какие-то? Выполни debug по шагам, и если он себя будет вести по другому, чем я написал в комментариях, то однозначно глюк. Меня в основном интересует почему в VICRaw заносится 0x1000? У тебя заносится? Видно придётся свежею версию скачивать?
|
|
|
|
|
Jan 30 2007, 19:15
|

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

|
Цитата(Alex_inventor @ Jan 30 2007, 16:52)  Замечания по поводу, правописания, скажу, я не на экзамене по русскому языку, и вообще я не в России живу и язык у меня родной другой. Хотя я почти всегда, посты свои в WORD на ошибки проверял. Я тоже живу не в России (хотя русский родной) и этот факт у меня отмечен в личных данных. У вас не отмечен, поэтому считаем по умолчанию - "Если не указан город - Москва, если проц - AVR, если компилятор - IAR". Так кажется кто-то предлагал на сахаре :-) Согласитесь, исходных данных чтобы считать вашим родным языком другой было недостаточно. Здесь есть один (минимум) участник из Болгарии и ему никто замечаний не делает.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 30 2007, 19:20
|
Местный
  
Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034

|
Цитата(sonycman @ Jan 30 2007, 20:30)  Цитата(Alex03 @ Jan 30 2007, 19:07)  Тут переменных типа nStartTimerVal м.б. сколько угодно, и проверять одну засечку времени можно на несколько значений таймаута (иногда я и такое пользую  ). Разрядность таймерной переменной можно понятно любую, но в timer0ISR() и getTimer() необходимо обеспечить атомарность модификации и чтения переменной. Здесь смущает только ситуация, когда uiTimer0Count переполнится: 0xffffffff -> 0x0. При этом вычисления для текущих таймеров будут неверными. Как этого избежать? Оно само решается. Допустим Вы сделали засечку в 0xFFFFFFFE, т.е. uiTimer0Count==0xFFFFFFFE, а таймаут хотите 4. т.е. if(VerifyTimer(nStartTimerVal, 4)) и #define VerifyTimer(s,t) ((t) <= (getTimer()-(s))) тогда: через 0 мс if(4 <= (0xFFFFFFFE - 0xFFFFFFFE)) или (4 <= 0) - ложь через 1 мс if(4 <= (0xFFFFFFFF - 0xFFFFFFFE)) или (4 <= 1) - ложь через 2 мс if(4 <= (0x00000000 - 0xFFFFFFFE)) или (4 <= 2) - ложь через 3 мс if(4 <= (0x00000001 - 0xFFFFFFFE)) или (4 <= 3) - ложь через 4 мс if(4 <= (0x00000002 - 0xFFFFFFFE)) или (4 <= 4) - истина через 5 мс if(4 <= (0x00000003 - 0xFFFFFFFE)) или (4 <= 5) - истина .... через (2^32-1)мс if(4 <= (0xFFFFFFFD - 0xFFFFFFFE)) или (4 <= 0xFFFFFFFF) - истина через (2^32)мс if(4 <= (0xFFFFFFFE - 0xFFFFFFFE)) или (4 <= 0) - ложь Т.е. Вы должны проверять чаще чем (пересчёт_таймера - таймаут) Цитата И, извиняюсь, я не знаю, что значит "обеспечить атомарность"...  А - вспомнил - одновременное действие? Не совсем. Скорее неделимое действие. Представте что таймер у Вас 64-х разрядный, а процессор 32-х, и в GetTimer() непосредственно после чтения одной части (например младшей, равной 0xFFFFFFFF) происходит прерывание и вся переменная инкрементируется. Тогда стартшую часть переменной GetTimer() вернёт некорректно по отношению к младшей. Способы обеспечения атомарности разные. - запрет/восстановление прерываний. - использование спец. инструкций проца (чтение-модификация-запись например для x86) - В многопроцессорных делах ещё и lock-и межпроцессорные. - и т.д.
|
|
|
|
|
Jan 30 2007, 19:24
|

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

|
Цитата(Alex_inventor @ Jan 30 2007, 18:14)  Меня в основном интересует почему в VICRaw заносится 0x1000? Этот регистр никакого отношения к инструкции SWI не имеет. Ассемблерная инструкция SWI вызывавет исключение независимо от разрешения/запрещения прерываний IRQ, FIQ и контроллера прерываний. А если вы внимательно прочитаете описание регистра VICRawIntr, то увидите, что это биты сработавших источников прерывания, но собственно прерывание вызовут лишь те из них, которые разрешениы в регистре VICIntEnable. Прочтя пропущенные разделы документации вы обнаружите, что двенадцатый бит означает PLL Lock. А прочтя описание PLL (а его прочитать нужно, раз вы PLL настраиваете) вы поймете что означает взведение этого бита.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 30 2007, 19:27
|

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

|
Цитата(Сергей Борщ @ Jan 30 2007, 20:09)  Нет, ничего страшного не происходит, поскольку он объявлен как unsigned и сравнение делается после беззнакового вычитания. Действительно! Это при простом сравнении будет криво, а если сравнивать уже с разностью... А я и не подумал... Ну что-же, попробую воплотить именно этот вариант в след. проекте. Как самый менее громоздкий и по процессорному времени, и по кодированию  2 Alex03Всё понял, спасибо!
Сообщение отредактировал sonycman - Jan 30 2007, 19:30
|
|
|
|
|
Jan 30 2007, 19:32
|
Местный
  
Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034

|
Цитата(zltigo @ Jan 30 2007, 20:42)  Элементарно, на самом организуются две очереди - одна до переполнения, другая после. При переполнении счетчика меняется указатель на очередь. При ограничении диапазона половиной счетчика можно навернуь и логику обработки переполнения на старшем бите. Очередь ж сортированная? При запихивании в очередь и сортировке всё делается без проблем. Например из всех значений перед сравнением вычитается текущее значение таймера. Т.е. если в очереди будут значения 0xB0, 0xE0, 0xFF, 0x10 - ничего страшного, Вы же знаете что в ней!
|
|
|
|
|
Jan 30 2007, 19:40
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jan 30 2007, 18:09)  Цитата(zltigo @ Jan 30 2007, 18:03)  Я использую именно вариант с двумя списками.
Можешь кинуть вырезку исходника? Заявка: Код /* The list item will be inserted in wake time order. */ SET_LIST_ITEM_VALUE( &( CurrentTCB->GenericListItem ), TimeToWake );
if( TimeToWake < TickCount ) { /* Wake time has overflowed. Place this item in the overflow list. */ ListInsert( (List *)DelayedTaskList_Ower, (ListItem *)&( CurrentTCB->GenericListItem ) ); } else { /* The wake time has not overflowed, so we can use the current block list. */ ListInsert( (List *)DelayedTaskList, (ListItem *)&( CurrentTCB->GenericListItem ) ); } Переключение очередей: Код if( ++TickCount == 0 ) { List *tlist; /* Tick count has overflowed so we need to swap the delay lists. If there are any items in DelayedTaskList here then there is an error! */ tlist = DelayedTaskList; DelayedTaskList = DelayedTaskList_Ower; DelayedTaskList_Ower = tlist; }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 30 2007, 19:40
|

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

|
Цитата(Alex_inventor @ Jan 30 2007, 20:14)  Выполни debug по шагам, и если он себя будет вести по другому, чем я написал в комментариях, то однозначно глюк. Меня в основном интересует почему в VICRaw заносится 0x1000? У тебя заносится? Видно придётся свежею версию скачивать? Протрассировалось и выполнило твой main(). А дальше конец программы - всегда улетает по SWI. Ты неправильно трассируешь. Поставь единственную точку останова на свою функцию main(), а не на сишной __main. Или в свойствах дебаггера галочку Run to main() И запусти Run. Дебаггер остановится на main(). Всё нормально. Из main() выхода не должно быть. А на VICRawIntr внимания пока не обращай. У тебя всё равно прерывания запрещены.
Сообщение отредактировал sonycman - Jan 30 2007, 19:55
|
|
|
|
|
Jan 30 2007, 19:53
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Alex03 @ Jan 30 2007, 18:32)  При запихивании в очередь и сортировке всё делается без проблем. Не совсем понимаю о чем это Вы. Есть, допустм 8бит счетчик и очередь 100, 200. Текущий счетчик 80. Хочу добавить два таймера на 1 и на 200 тиков. Запихивайте. Сортируйте. Жду.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|