|
Прерывание от таймера в AT91SAM7X256 |
|
|
|
May 22 2008, 05:35
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Используем FreeRTOS. ВОзникла необходимость использования таймера. Вроде просто так таймер запускается и работает, а вот прерывания не обрабатывает. Я подозреваю, что функцию обработки прерывания нельзя объявлять, как обычную функцию. Наверное, надо прописывать ещё вектор прерывания от таймера где-то там. В том и проблема, что не очень хорошо разбираюсь во всяких там секциях памяти, размещении векторов и т. д (по крайней мере в этом контроллере). Как бы это попроще организовать??? ТЕкст (кстати стандартный) приведен ниже: //ф-ия обработки прерывания void timer1_c_irq_handler(void) { AT91PS_TC TC_pt = AT91C_BASE_TC1; unsigned int dummy; //* Acknowledge interrupt status dummy = TC_pt->TC_SR; //* Suppress warning variable "dummy" was set but never used dummy = dummy; count_timer0_interrupt++; vParTestToggleLED( 2 ); } void AT91F_TC_Open ( AT91PS_TC TC_pt, unsigned int Mode, unsigned int TimerId) { unsigned int dummy; AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<< TimerId ) ; AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_TC1); TC_pt->TC_CCR = AT91C_TC_CLKDIS ; TC_pt->TC_IDR = 0xFFFFFFFF ; dummy = TC_pt->TC_SR; TC_pt->TC_CMR = Mode ; TC_pt->TC_CCR = AT91C_TC_CLKEN ; } void timer_init ( void ) { unsigned int oldHandler; unsigned int mask ; AT91S_AIC *pAIC = AT91C_BASE_AIC; AT91S_TC *pTMR = AT91C_BASE_TC1; //init the timer interrupt counter count_timer0_interrupt=0; count_timer1_interrupt=0; //* Open timer1 AT91F_TC_Open(AT91C_BASE_TC1,TC_CLKS_MCK128,AT91C_ID_TC1); //* Open Timer 1 interrupt AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_TC1, TIMER1_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer1_c_irq_handler); AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1); //* Start timer1 //AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG ; } P.S. Знаю, что подобные посты уже были, но хотелось бы ещё раз остановиться на данной проблеме! Спасибо заранее за ответы.
|
|
|
|
|
May 22 2008, 05:40
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(ZAA @ May 22 2008, 09:35)  Я подозреваю, что функцию обработки прерывания нельзя объявлять, как обычную функцию. Нельзя. Как правильно объявить прерывание ищите в документации на компилятор. Цитата(ZAA @ May 22 2008, 09:35)  P.S. Знаю, что подобные посты уже были, но хотелось бы ещё раз остановиться на данной проблеме! Спасибо заранее за ответы. Были уже сотню раз. Пользуйтесь поиском.
|
|
|
|
|
May 22 2008, 07:29
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(_4afc_ @ May 22 2008, 11:06)  Обработчики - это обычные функции. Ибо вход в во все прерывания всё-равно один и далее ваша функция вызывается как обычная подпрограмма. Представьте себе, далеко не всегда. Более того, обработчики обычно вызываются именно в IRQ режиме. А то, как именно будет вызвана функция, определяется кодом, стартующим с адреса 0x18. Цитата(_4afc_ @ May 22 2008, 11:06)  Надо только поместить указатель на подпрограмму в соответствующий регистр AIC, что делает не компилятор, а специальная подпрограмма AT91F_AIC_ConfigureIt. У любителей использования "специальных подпрограмм AT91F_" обычно плохо с мат. частью. Цитата(_4afc_ @ May 22 2008, 11:06)  Разница в выходе из обработчика, только в прерываниях по уровню и фронту. Надо смотреть какой реализован за вас. Чушь. Цитата(_4afc_ @ May 22 2008, 11:06)  Не путайте божый дар (ARM) с яичницей(AVR).
|
|
|
|
|
May 22 2008, 13:24
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(aaarrr @ May 22 2008, 12:00)  Чтобы получить маааленький совет, укажите: 1. Какой используется компилятор. 2. Какой порт FreeRTOS. Я делаю проект в Eclipse для AT91SAM7X256. А компилятор - gcc (который из эклипсовского gnu-армовского набора инструментов). Пыталась найти что-то подобное в инфе про gcc, но безрезультатно...Видимо, или ищу не там, или не то... А вообще без отладчика тяжко программу писать...
|
|
|
|
|
May 23 2008, 03:08
|

Участник

Группа: Участник
Сообщений: 20
Регистрация: 25-06-07
Из: Томск
Пользователь №: 28 670

|
Цитата(ZAA @ May 22 2008, 19:24)  Я делаю проект в Eclipse для AT91SAM7X256. А компилятор - gcc (который из эклипсовского gnu-армовского набора инструментов). Пыталась найти что-то подобное в инфе про gcc, но безрезультатно...Видимо, или ищу не там, или не то... А вообще без отладчика тяжко программу писать... Тяжело но можно, а потом когда привыкаешь так даже проще ) По вашему случаю рекомендую этот код компилить в ARM режиме, либо разделить код на 2 части и в ARM компилить функцию прерывания, а в THUMB (в котором скомпилен FreeRTOS для SAM7X256) скомпилировать все остальное. Кроме того обратите внимание как обрамлен код прерывания в уже имеющихся прерываниях FreeRTOS. То как сделано сейчас просто уронит ось когда наконец заработает.
|
|
|
|
|
May 23 2008, 05:10
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(sla000 @ May 23 2008, 06:08)  Тяжело но можно, а потом когда привыкаешь так даже проще )
По вашему случаю рекомендую этот код компилить в ARM режиме, либо разделить код на 2 части и в ARM компилить функцию прерывания, а в THUMB (в котором скомпилен FreeRTOS для SAM7X256) скомпилировать все остальное. Кроме того обратите внимание как обрамлен код прерывания в уже имеющихся прерываниях FreeRTOS. То как сделано сейчас просто уронит ось когда наконец заработает. спасибо вам! Я попробую. Ещё встречный вопрос. Надо секцию, отвечающую за прерывания. размещать в Csatartup.c? Там же где и секции .text, .bss? Может быть. вы мне подскажете какой-нибудь источник, в котором хотя бы в общих словах рассказывается о принципах написания ассемблерных файлов для этого контроллера. ну в смысле всяких там секций и т п, а то с этим туговато. а без этого никак  Спасибо! И ещё: что вы имеете ввиду под "То как сделано сейчас просто уронит ось когда наконец заработает"?
Сообщение отредактировал ZAA - May 23 2008, 05:13
|
|
|
|
|
May 23 2008, 05:36
|

Участник

Группа: Участник
Сообщений: 20
Регистрация: 25-06-07
Из: Томск
Пользователь №: 28 670

|
Цитата(ZAA @ May 23 2008, 11:10)  Надо секцию, отвечающую за прерывания. размещать в Csatartup.c? Там же где и секции .text, .bss? Нет, гляньте в мейкфайл, там есть список файлов SRC и SRCARM, так вот, если вы создадите файлик с телом перывания, то его надо добавить в список SRCARM. Так он скомпилится в ARM режиме. Соответсвенно всю остальную требуху - инициализацию таймера и т.п. можно запихнуть в SRC, тогда они скомпилятся в THUMB. Цитата(ZAA @ May 23 2008, 11:10)  Может быть. вы мне подскажете какой-нибудь источник, в котором хотя бы в общих словах рассказывается о принципах написания ассемблерных файлов для этого контроллера. ну в смысле всяких там секций и т п, а то с этим туговато. а без этого никак  Спасибо! Да не переживайте вы так ) зачем вам вообще надо программировать на асме? Ну если уж так интересно читайте документацию на архитектуру ARM7TDMI есть на сайте ATMEL. Цитата(ZAA @ May 23 2008, 11:10)  И ещё: что вы имеете ввиду под "То как сделано сейчас просто уронит ось когда наконец заработает"? У FreeRTOS есть совершенно четкие указания как должно выглядеть прерывание. Если им не следовать результат непредсказуем, но 100% что все пойдет не так как должно. Как должно быть обрамлено прерывание можно почитать тут: http://www.freertos.org/portsam7xlwIP.html
|
|
|
|
|
May 24 2008, 07:34
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(sla000 @ May 23 2008, 08:36)  Нет, гляньте в мейкфайл, там есть список файлов SRC и SRCARM, так вот, если вы создадите файлик с телом перывания, то его надо добавить в список SRCARM. Так он скомпилится в ARM режиме. Соответсвенно всю остальную требуху - инициализацию таймера и т.п. можно запихнуть в SRC, тогда они скомпилятся в THUMB. Да не переживайте вы так ) зачем вам вообще надо программировать на асме? Ну если уж так интересно читайте документацию на архитектуру ARM7TDMI есть на сайте ATMEL. У FreeRTOS есть совершенно четкие указания как должно выглядеть прерывание. Если им не следовать результат непредсказуем, но 100% что все пойдет не так как должно. Как должно быть обрамлено прерывание можно почитать тут: http://www.freertos.org/portsam7xlwIP.htmlОгромное Вам спасибо! Я постараюсь разобраться!!!
|
|
|
|
|
May 24 2008, 18:58
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(sla000 @ May 23 2008, 08:36)  Нет, гляньте в мейкфайл, там есть список файлов SRC и SRCARM, так вот, если вы создадите файлик с телом перывания, то его надо добавить в список SRCARM. Так он скомпилится в ARM режиме. Соответсвенно всю остальную требуху - инициализацию таймера и т.п. можно запихнуть в SRC, тогда они скомпилятся в THUMB. Уважаемый sla000!!! Я следую Вашим советам, но все равно не хочет этот таймер рботать. Уж руки просто опускаются! Я объявляю в файлике interrupt_timer (который компилируется в ARM-mode) 2 функции (как сказано на сайте фриртоса): void vTIMER_ISR_Handler( void ) { portBASE_TYPE xTaskWokenByPost = pdFALSE; static volatile unsigned portLONG ulNextMessage = 0; xISRStatus *pxMessage; AT91PS_TC TC_pt = AT91C_BASE_TC1; unsigned int dummy; //* Acknowledge interrupt status dummy = TC_pt->TC_SR; //* Suppress warning variable "dummy" was set but never used dummy = dummy; count_timer1_interrupt++; vParTestToggleLED(3); AT91C_BASE_AIC->AIC_EOICR = 0; } void vTIMER_ISR_Wrapper( void ) { /* Save the context of the interrupted task. */ portSAVE_CONTEXT();
/* Call the handler itself. This must be a separate function as it uses the stack. */ vTIMER_ISR_Handler();
/* Restore the context of the task that is going to execute next. This might not be the same as the originally interrupted task.*/ portRESTORE_CONTEXT(); }Обе эти функции объявлены в файле interrupt_timer.h так: void vTIMER_ISR_Wrapper( void ) __attribute__((naked)); void vTIMER_ISR_Handler( void ); Потом в init_timer.c (компилируется в THUMB-mode) настраиваю таймер1 (тоже вроде стандартная последовательность) и вызываю обработчик прерывания: void timer_init ( void ) //* Begin { AT91S_AIC *pAIC = AT91C_BASE_AIC; AT91S_TC *pTMR = AT91C_BASE_TC1; //* Open timer1 AT91F_TC_Open(AT91C_BASE_TC1,TC_CLKS_MCK128,AT91C_ID_TC1); AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_TC1); AT91C_BASE_TC1->TC_CMR=AT91C_TC_CLKS_TIMER_DIV4_CLOCK | AT91C_TC_CPCSTOP; //* Open Timer 1 interrupt AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_TC1, TIMER0_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) )vTIMER_ISR_Wrapper); //AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC AT91C_BASE_TC1->TC_RC = 0xFFFF; //AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1); AT91C_BASE_TC1->TC_CCR=AT91C_TC_CLKEN; AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG ; } В чем косяк может быть?  Помогите пожалуйста!!!
|
|
|
|
|
May 24 2008, 20:35
|

Частый гость
 
Группа: Свой
Сообщений: 91
Регистрация: 1-06-05
Пользователь №: 5 621

|
Цитата(ZAA @ May 24 2008, 21:58)  В чем косяк может быть?  Помогите пожалуйста!!! Не уверен, но, может быть, вместо Код AT91C_BASE_AIC->AIC_EOICR = 0; надо Код AT91C_BASE_AIC->AIC_EOICR =AT91C_ID_TC1;
|
|
|
|
|
May 24 2008, 21:30
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(ZAA @ May 24 2008, 22:58)  AT91F_TC_Open(AT91C_BASE_TC1,TC_CLKS_MCK128,AT91C_ID_TC1); AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_TC1); AT91C_BASE_TC1->TC_CMR=AT91C_TC_CLKS_TIMER_DIV4_CLOCK | AT91C_TC_CPCSTOP; Timer1 сконфигурирован в Capture Mode, а бит CPCSTOP существует в Waveform Mode. Цитата(ZAA @ May 24 2008, 22:58)  //AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC AT91C_BASE_TC1->TC_RC = 0xFFFF; //AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1); Присутствующим остается только гадать, почему разрешение оказалось закомментировано? P.S. OFF. Еще раз пройдусь по AT91F_: Человеки! Ну зачем вы пользуетесь этой дрянью? Ведь код становится понять совершенно невозможно, а жизнь они никак облегчить не могут в силу своей примитивности. Цитата(KolyanV @ May 25 2008, 00:35)  Не уверен, но, может быть Не может. В EOICR можно писать что угодно.
|
|
|
|
|
May 25 2008, 07:10
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(aaarrr @ May 25 2008, 00:30)  Timer1 сконфигурирован в Capture Mode, а бит CPCSTOP существует в Waveform Mode. Присутствующим остается только гадать, почему разрешение оказалось закомментировано? P.S. OFF. Еще раз пройдусь по AT91F_: Человеки! Ну зачем вы пользуетесь этой дрянью? Ведь код становится понять совершенно невозможно, а жизнь они никак облегчить не могут в силу своей примитивности. Поправки в настройке таймера не помогли  Не хочет он прерываться. У меня не включено ни одной задачи. Просто в файле main.c инициализируется и запускается таймер. Такое подозрение, что тут сама ОС не дает ему запуститься... И ещё в чем разница между void vTIMER_ISR_Wrapper( void ) __attribute__((naked)); и void vTIMER_ISR_Wrapper( void ) __attribute__((interrupt("IRQ"))); ? КАк не навредить-то собственным FreeRTOSовским перрываниям и получить это несчастное прерывание по таймеру, например по TC1 (ну или TC0)???
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|