ZAA 0 22 мая, 2008 Опубликовано 22 мая, 2008 · Жалоба Используем 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. Знаю, что подобные посты уже были, но хотелось бы ещё раз остановиться на данной проблеме! Спасибо заранее за ответы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 22 мая, 2008 Опубликовано 22 мая, 2008 · Жалоба Я подозреваю, что функцию обработки прерывания нельзя объявлять, как обычную функцию. Нельзя. Как правильно объявить прерывание ищите в документации на компилятор. P.S. Знаю, что подобные посты уже были, но хотелось бы ещё раз остановиться на данной проблеме! Спасибо заранее за ответы. Были уже сотню раз. Пользуйтесь поиском. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 25 22 мая, 2008 Опубликовано 22 мая, 2008 (изменено) · Жалоба Нельзя. Как правильно объявить прерывание ищите в документации на компилятор. Были уже сотню раз. Пользуйтесь поиском. А вот в WinARM обработчики - это обычные функции. Ибо вход в во все прерывания всё-равно один и далее ваша функция вызывается как обычная подпрограмма. Надо только поместить указатель на подпрограмму в соответствующий регистр AIC, что делает не компилятор, а специальная подпрограмма AT91F_AIC_ConfigureIt. Разница в выходе из обработчика, только в прерываниях по уровню и фронту. Надо смотреть какой реализован за вас. Изменено 22 мая, 2008 пользователем _4afc_ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 22 мая, 2008 Опубликовано 22 мая, 2008 · Жалоба Обработчики - это обычные функции. Ибо вход в во все прерывания всё-равно один и далее ваша функция вызывается как обычная подпрограмма. Представьте себе, далеко не всегда. Более того, обработчики обычно вызываются именно в IRQ режиме. А то, как именно будет вызвана функция, определяется кодом, стартующим с адреса 0x18. Надо только поместить указатель на подпрограмму в соответствующий регистр AIC, что делает не компилятор, а специальная подпрограмма AT91F_AIC_ConfigureIt. У любителей использования "специальных подпрограмм AT91F_" обычно плохо с мат. частью. Разница в выходе из обработчика, только в прерываниях по уровню и фронту. Надо смотреть какой реализован за вас. Чушь. Не путайте божый дар (ARM) с яичницей(AVR). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZAA 0 22 мая, 2008 Опубликовано 22 мая, 2008 · Жалоба НУ вот, ничего конкретного... :crying: а ведь хотя бы один маааленький совет может натолкнуть на верный путь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 22 мая, 2008 Опубликовано 22 мая, 2008 · Жалоба Чтобы получить маааленький совет, укажите: 1. Какой используется компилятор. 2. Какой порт FreeRTOS. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZAA 0 22 мая, 2008 Опубликовано 22 мая, 2008 · Жалоба Чтобы получить маааленький совет, укажите: 1. Какой используется компилятор. 2. Какой порт FreeRTOS. Я делаю проект в Eclipse для AT91SAM7X256. А компилятор - gcc (который из эклипсовского gnu-армовского набора инструментов). Пыталась найти что-то подобное в инфе про gcc, но безрезультатно...Видимо, или ищу не там, или не то... А вообще без отладчика тяжко программу писать... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sla000 0 23 мая, 2008 Опубликовано 23 мая, 2008 · Жалоба Я делаю проект в Eclipse для AT91SAM7X256. А компилятор - gcc (который из эклипсовского gnu-армовского набора инструментов). Пыталась найти что-то подобное в инфе про gcc, но безрезультатно...Видимо, или ищу не там, или не то... А вообще без отладчика тяжко программу писать... Тяжело но можно, а потом когда привыкаешь так даже проще ) По вашему случаю рекомендую этот код компилить в ARM режиме, либо разделить код на 2 части и в ARM компилить функцию прерывания, а в THUMB (в котором скомпилен FreeRTOS для SAM7X256) скомпилировать все остальное. Кроме того обратите внимание как обрамлен код прерывания в уже имеющихся прерываниях FreeRTOS. То как сделано сейчас просто уронит ось когда наконец заработает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZAA 0 23 мая, 2008 Опубликовано 23 мая, 2008 (изменено) · Жалоба Тяжело но можно, а потом когда привыкаешь так даже проще ) По вашему случаю рекомендую этот код компилить в ARM режиме, либо разделить код на 2 части и в ARM компилить функцию прерывания, а в THUMB (в котором скомпилен FreeRTOS для SAM7X256) скомпилировать все остальное. Кроме того обратите внимание как обрамлен код прерывания в уже имеющихся прерываниях FreeRTOS. То как сделано сейчас просто уронит ось когда наконец заработает. спасибо вам! Я попробую. Ещё встречный вопрос. Надо секцию, отвечающую за прерывания. размещать в Csatartup.c? Там же где и секции .text, .bss? Может быть. вы мне подскажете какой-нибудь источник, в котором хотя бы в общих словах рассказывается о принципах написания ассемблерных файлов для этого контроллера. ну в смысле всяких там секций и т п, а то с этим туговато. а без этого никак :crying: Спасибо! И ещё: что вы имеете ввиду под "То как сделано сейчас просто уронит ось когда наконец заработает"? Изменено 23 мая, 2008 пользователем ZAA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sla000 0 23 мая, 2008 Опубликовано 23 мая, 2008 · Жалоба Надо секцию, отвечающую за прерывания. размещать в Csatartup.c? Там же где и секции .text, .bss? Нет, гляньте в мейкфайл, там есть список файлов SRC и SRCARM, так вот, если вы создадите файлик с телом перывания, то его надо добавить в список SRCARM. Так он скомпилится в ARM режиме. Соответсвенно всю остальную требуху - инициализацию таймера и т.п. можно запихнуть в SRC, тогда они скомпилятся в THUMB. Может быть. вы мне подскажете какой-нибудь источник, в котором хотя бы в общих словах рассказывается о принципах написания ассемблерных файлов для этого контроллера. ну в смысле всяких там секций и т п, а то с этим туговато. а без этого никак :crying: Спасибо! Да не переживайте вы так ) зачем вам вообще надо программировать на асме? Ну если уж так интересно читайте документацию на архитектуру ARM7TDMI есть на сайте ATMEL. И ещё: что вы имеете ввиду под "То как сделано сейчас просто уронит ось когда наконец заработает"? У FreeRTOS есть совершенно четкие указания как должно выглядеть прерывание. Если им не следовать результат непредсказуем, но 100% что все пойдет не так как должно. Как должно быть обрамлено прерывание можно почитать тут: http://www.freertos.org/portsam7xlwIP.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZAA 0 24 мая, 2008 Опубликовано 24 мая, 2008 · Жалоба Нет, гляньте в мейкфайл, там есть список файлов SRC и SRCARM, так вот, если вы создадите файлик с телом перывания, то его надо добавить в список SRCARM. Так он скомпилится в ARM режиме. Соответсвенно всю остальную требуху - инициализацию таймера и т.п. можно запихнуть в SRC, тогда они скомпилятся в THUMB. Да не переживайте вы так ) зачем вам вообще надо программировать на асме? Ну если уж так интересно читайте документацию на архитектуру ARM7TDMI есть на сайте ATMEL. У FreeRTOS есть совершенно четкие указания как должно выглядеть прерывание. Если им не следовать результат непредсказуем, но 100% что все пойдет не так как должно. Как должно быть обрамлено прерывание можно почитать тут: http://www.freertos.org/portsam7xlwIP.html Огромное Вам спасибо! Я постараюсь разобраться!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZAA 0 24 мая, 2008 Опубликовано 24 мая, 2008 · Жалоба Нет, гляньте в мейкфайл, там есть список файлов 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 ; } В чем косяк может быть? Помогите пожалуйста!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolyanV 0 24 мая, 2008 Опубликовано 24 мая, 2008 · Жалоба В чем косяк может быть? Помогите пожалуйста!!! Не уверен, но, может быть, вместо AT91C_BASE_AIC->AIC_EOICR = 0; надо AT91C_BASE_AIC->AIC_EOICR =AT91C_ID_TC1; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 24 мая, 2008 Опубликовано 24 мая, 2008 · Жалоба 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. //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_: Человеки! Ну зачем вы пользуетесь этой дрянью? Ведь код становится понять совершенно невозможно, а жизнь они никак облегчить не могут в силу своей примитивности. Не уверен, но, может быть Не может. В EOICR можно писать что угодно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZAA 0 25 мая, 2008 Опубликовано 25 мая, 2008 · Жалоба Timer1 сконфигурирован в Capture Mode, а бит CPCSTOP существует в Waveform Mode. Присутствующим остается только гадать, почему разрешение оказалось закомментировано? P.S. OFF. Еще раз пройдусь по AT91F_: Человеки! Ну зачем вы пользуетесь этой дрянью? Ведь код становится понять совершенно невозможно, а жизнь они никак облегчить не могут в силу своей примитивности. Поправки в настройке таймера не помогли :crying: Не хочет он прерываться. У меня не включено ни одной задачи. Просто в файле main.c инициализируется и запускается таймер. Такое подозрение, что тут сама ОС не дает ему запуститься... И ещё в чем разница между void vTIMER_ISR_Wrapper( void ) __attribute__((naked)); и void vTIMER_ISR_Wrapper( void ) __attribute__((interrupt("IRQ"))); ? КАк не навредить-то собственным FreeRTOSовским перрываниям и получить это несчастное прерывание по таймеру, например по TC1 (ну или TC0)??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться