Меню
+7 (495) 785-95-25
sale@lcard.ru
sale@lcard.ru
Страницы 1
|
||||
|
L502 подсчёт времениЗдравствуйте. Есть ваша l502 с сигнальным процессором Bfin. Есть необходимость писать свою прошивку для него и в ней считать время с миллисекундной точностью. Не подскажете, как это сделать? Функция clock из time.h возвращает -1. START_CYCLE_COUNT и STOP_CYCLE_COUNT из cycle_count.h тоже не работают. Для сборки прошивки использую тулчейн bfin-elf-gcc под Linux с sourceforge. Спасибо. |
|||
|
||||
|
Re: L502 подсчёт времениЧастично отвечу сам на свой вопрос. В makefile прошивки нужно добавить дефайн DO_CYCLE_COUNTS (строка, начинающаяся с DDEFS=). В файл l502-bf_basiccrt.s добавить строки (я добавил перед //Zero bss memory):
В хедере тулчейна /bfin-elf/include/cycle_count_bf.h заменить все вхождения r0, r1, r2 на R0, R1, R2 соответственно. ПОЛНОСТЬЮ пересобрать прошивку. Теперь в прошивке можно делать такие вещи:
В stop будет лежать количество тактов процессора, прошедших со START_CYCLE_COUNT(start). Чтобы получить миллисекунды, нужно это значение разделить на 530000. У меня осталось пару вопросов. Насколько точен такой метод? Почему бы не включить в прошивку что-то подобное из коробки? Можно ли использовать таймеры в прошивке? Если да, то как? |
|||
|
||||
|
Re: L502 подсчёт времениПомогите пожалуйста включить таймер и добавить обработчик его прерываний в вашу прошивку. Требуемая частота - 1КГц. Добавил в l502_init.c в l502_init перед hdma_init() следующий код:
ISR(inc_time) определён, но не срабатывает. Что я делаю не так? |
|||
|
||||
|
Re: L502 подсчёт времениЗдравствуйте. По поводу точности, то нужно учитывать, что для любого способа, основанного на внутренней частоте процессора есть ошибка, связанная с неточностью значения самой этой частоты, от которой работает процессор. Для L-502 эта точность 50ppm или 0.005 % (т.е. для измерения времени секунды может быть ошибка до 50 мкс). По поводу Вашего кода. Если Вам нужен таймер, который генерирует прерывания раз в мс, то Вам нужно настроить режим PWM_OUT без использования собственно выходного сигнала PWM на ножке (OUT_DIS = 1), с постоянной (не однократной) генерацией сигнала (PERIOD_CNT = 1) и с разрешенной установкой бита прерывания в конце каждого периода (IRQ_ENA = 1). Таймер по умолчанию работает от частоты SCLK = 132.5 МГц, соответственно в регистр длительности периода, чтобы она была 1 мс, нужно записать значение 132500. Регистр WIDTH определяет длину активного значения импульса (duty cycle) для сигнала pwm и т.к. сам PWM сигнал Вы не используете, то его значение не важно, но на всякий случай лучше установить его в действительное значение, т.е. не менее 1, но меньше PERIOD. Т.е. код инициализации таймера без разрешения обработчика прерывания таймера может выглядеть так:
После конфигурации таймер необходимо также запустить через TIMER_ENABLE.
В этом режиме можно проверить настройки таймера без разрешения обработчика путем обычного опроса (т.к. бит IRQ_ENA установлен, то таймер будет устанавливать флаг прерывания, который можно проверить и сбросить, но сам обработчик не будет вызываться, т.к. не разрешен в pSIC_IMASK1), периодически вызывая проверку:
Если все работает как надо (идет подсчет мс корректно), то долее можно разрешить уже обработчик. Строка REGISTER_ISR(12, inc_time); регистрирует обработчик прерывания для прерывания IVG12. Через регистры IAR Вы делаете маппинг прерываний от периферии на прерывания контроллера (IVG7 - IVG15) (что необходимо, т.к. обработчиков под периферию всего 9, а источников намного больше). В макросе Pxx_IVG(n) значение n - это как раз номер IVG, а значение xx - Peripheral ID# (для TIMER0 - 32), т.е. правильный вызов макроса - P32_IVG(12). Во-вторых делать просто операцию "или" не совсем корректно, т.к. уже есть назначение по умолчанию при старте и поле может быть не 0 (и к слову для TIMER0 это как раз IVG12 и можно было бы ничего не писать), поэтому сперва значение этого поля в IAR4 нужно обнулить. Для этого я не нашел готовый макрос, поэтому в прошивке пишу через явную битовую маску:
Т.е. после настройки таймера и до его разрешения через pTIMER_ENABLE, нужно вставить:
В обработчике прерывания необходимо аналогично проверить флаг от таймера и сбросить его, после чего вызвать ssync(), чтобы флаг сбросился до выхода из обработчика и не попасть в обработчик второй раз:
|
Страницы 1
Адрес: 117105, Москва, Варшавское шоссе, д. 5, корп. 4, стр. 2
Многоканальный телефон:
+7 (495) 785-95-25
Отдел продаж: sale@lcard.ru
Техническая поддержка: support@lcard.ru
Время работы: с 9-00 до 19-00 мск