vitek101 0 25 августа, 2009 Опубликовано 25 августа, 2009 · Жалоба Пишу для XMega128, IAR 5.20. Не работают вызовы OSMboxPost, OSSemPost и OSQPost из обработчика прерывания. Между задачами вызовы работают прекрасно, сами прерывания тоже работают (диоды моргают, байты в UART бегают). Что делать ума не приложу :07: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
capnemo777 0 25 августа, 2009 Опубликовано 25 августа, 2009 · Жалоба Пишу для XMega128, IAR 5.20. Не работают вызовы OSMboxPost, OSSemPost и OSQPost из обработчика прерывания. Между задачами вызовы работают прекрасно, сами прерывания тоже работают (диоды моргают, байты в UART бегают). Что делать ума не приложу :07: как используются функции OSIntEnter(), OSIntExit() ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vladimir_T 1 25 августа, 2009 Опубликовано 25 августа, 2009 · Жалоба Непосредственно из прерывания сервисы ОС вызывать нельзя. Можно находясь в прерывании вызвать вспомогательную функцию в которой и устанавливается, например, семафор: OSSemPost (Sem_LCD); // установить семафор для прорисовки дисплея В отладчике можно проследить за переменной-семафором. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitek101 0 26 августа, 2009 Опубликовано 26 августа, 2009 · Жалоба как используются функции OSIntEnter(), OSIntExit() ? Вот обработчик из отдельного асмового файла. BSP_USARTC0_RXC_IRQ_Hndlr - мой обработчик прерывания. Изначально взят из порта, скачанного с Micriuma, изменил только ссылку на свой обработчик. BSP_USARTC0_RXC_IRQ_vect: CLI ; Disable Global Interrupts to avoid breaking context save PUSH_ALL ; Save all registers and status register PUSH_SREG_INT ; Save the SREG but with interrupts enabled PUSH_SP ; Save the task's hardware stack pointer onto task's stack LDS R16,OSIntNesting ; Notify uC/OS-II of ISR INC R16 ; STS OSIntNesting,R16 ; CPI R16,1 ; if (OSIntNesting == 1) { BRNE BSP_USARTC0_RXC_IRQ_vect_1 LDS R30,OSTCBCur ; OSTCBCur->OSTCBStkPtr = Y LDS R31,OSTCBCur+1 ST Z+,R28 ST Z+,R29 ; } BSP_USARTC0_RXC_IRQ_vect_1: CALL BSP_USARTC0_RXC_IRQ_Hndlr ; Call Handler written in C CALL OSIntExit ; Notify uC/OS-II about end of ISR POP_SP ; Restore the hardware stack pointer from task's stack POP_SREG_INT ; Restore status register (DISABLE interrupts) POP_ALL ; Restore all registers SEI ; Enable interrupts, since RETI does not on Xmega RETI Непосредственно из прерывания сервисы ОС вызывать нельзя. Можно находясь в прерывании вызвать вспомогательную функцию в которой и устанавливается, например, семафор: OSSemPost (Sem_LCD); // установить семафор для прорисовки дисплея В отладчике можно проследить за переменной-семафором. Сейчас попробовал - не работает. Смотрю в отладчике, при вызове OSSemPost параметр pevent равен нулю и в жирном месте процедура вылетает. Если вызываю из задачи, то все нормально. Сам этот параметр при вызове располагается в регистрах R24-R25. Не может система при вызове прерывания как-нибудь кривить их? :05: INT8U OSSemPost (OS_EVENT *pevent) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ return (OS_ERR_PEVENT_NULL); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0) { /* See if any task waiting for semaphore */ /* Ready HPT waiting on event */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); OS_EXIT_CRITICAL(); OS_Sched(); /* Find HPT ready to run */ return (OS_ERR_NONE); } if (pevent->OSEventCnt < 65535u) { /* Make sure semaphore will not overflow */ pevent->OSEventCnt++; /* Increment semaphore count to register event */ OS_EXIT_CRITICAL(); return (OS_ERR_NONE); } OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */ return (OS_ERR_SEM_OVF); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andy_Mozzhevilov 0 26 августа, 2009 Опубликовано 26 августа, 2009 · Жалоба Непосредственно из прерывания сервисы ОС вызывать нельзя. Почему? Можно находясь в прерывании вызвать вспомогательную функцию в которой и устанавливается, например, семафор: Чем прямой вызов OSSemPost будет принципиально отличаться от его вызова через промежуточную функцию? Сейчас попробовал - не работает. Смотрю в отладчике, при вызове OSSemPost параметр pevent равен нулю и в жирном месте процедура вылетает. Если вызываю из задачи, то все нормально. Сам этот параметр при вызове располагается в регистрах R24-R25. Не может система при вызове прерывания как-нибудь кривить их? :05: По моему у вас проблемы не с ОС, а с Си. Код покажите. Как вы семафор объявляете, как инициализируете. Вы уверены, что он успевает инициализироваться до первого прерывания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitek101 0 26 августа, 2009 Опубликовано 26 августа, 2009 · Жалоба По моему у вас проблемы не с ОС, а с Си. Код покажите. Как вы семафор объявляете, как инициализируете. Вы уверены, что он успевает инициализироваться до первого прерывания? Я думаю успевает, т.к. прерывание от УАРТа, а оно происходит по нажатию клавиши на клавиатуре (ну если конечно ему не 5 минут на инициализацию надо). Вот код. В BSP_Init настраиваю УАРТ, разрешаю его прерывания, настраиваю таймер и порт для светодиода. Задача просто ждет семафора и моргает диодом (должна моргать, но не моргает :huh: ). Приоритет задачи 5, таймера 63. #define APP_CFG_TASK1_STK_SIZE 360 static void App_Task1 (void *p_arg); static OS_STK App_Task1Stk[APP_CFG_TASK1_STK_SIZE]; static OS_EVENT *App_Sem; void main (void) { BSP_IntDisAll(); /* Disable all interrupts until we are ready to accept them */ /* IMPORTANT: MUST be setup before calling 'OSInit()' */ OSTaskStkSize = OS_TASK_IDLE_STK_SIZE; /* Setup the default stack size */ OSTaskStkSizeHard = OS_TASK_STK_SIZE_HARD; /* Setup the default hardware stack size */ OSInit(); /* Initialize "uC/OS-II, The Real-Time Kernel" */ BSP_Init(); /* Initialize the BSP */ App_TaskCreate(); /* Create the application tasks */ App_EventCreate(); /* Create the application events */ OSStart(); /* Start multitasking (i.e. give control to uC/OS-II) */ } static void App_TaskCreate (void) { #if (OS_TASK_NAME_SIZE > 13) CPU_INT08U os_err; #endif OSTaskCreateExt((void (*)(void *)) App_Task1, (void *) 0, (OS_STK *)&App_Task1Stk[APP_CFG_TASK1_STK_SIZE - 1], (INT8U ) APP_CFG_TASK1_PRIO, (INT16U ) APP_CFG_TASK1_PRIO, (OS_STK *)&App_Task1Stk[0], (INT32U ) APP_CFG_TASK1_STK_SIZE, (void *) 0, (INT16U )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR)); #if (OS_TASK_NAME_SIZE > 13) OSTaskNameSet(APP_CFG_TASK1_PRIO, "Task1", &os_err); #endif } static void App_EventCreate (void) { CPU_INT08U os_err; App_Sem = OSSemCreate(1); #if (OS_EVENT_NAME_SIZE > 8) OSEventNameSet(App_Sem, "Semafor", &os_err); #else void(os_err); #endif } static void App_Task1 (void *p_arg) { (void)p_arg; while (DEF_TRUE) { OSSemPend(App_Sem); BSP_LED_Toggle(1); } } Может у кого есть рабочий проект хотя бы для ATmega128. Если не жалко поделитесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andy_Mozzhevilov 0 26 августа, 2009 Опубликовано 26 августа, 2009 · Жалоба Во-первых, пользуйтесь тегом code для вставки исходных текстов. Во-вторых, вы не показали здесь функцию прерывания, в которой делается OSSemPost. Попытаюсь проявить телепатические способности: Вызов OSSemPost у вас происходит в другом модуле, а App_Sem в приведенном вами тексте объявлен как static, то есть его область видимости ограничена этим модулем (единицей компиляции). Соответственно, переменная App_Sem, которую вы используете в OSSemPost - это другая переменная в другой области видимости, которая у вас не инициализируется. Покажите свой код, как вы объявляете и импользуете App_Sem в другом модуле. Проследите в отладчике, по каким адресам у вас лежат эти переменные, чем и когда они инициализируются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitek101 0 26 августа, 2009 Опубликовано 26 августа, 2009 · Жалоба Во-первых, пользуйтесь тегом code для вставки исходных текстов. Во-вторых, вы не показали здесь функцию прерывания, в которой делается OSSemPost. Попытаюсь проявить телепатические способности: Вызов OSSemPost у вас происходит в другом модуле, а App_Sem в приведенном вами тексте объявлен как static, то есть его область видимости ограничена этим модулем (единицей компиляции). Соответственно, переменная App_Sem, которую вы используете в OSSemPost - это другая переменная в другой области видимости, которая у вас не инициализируется. Покажите свой код, как вы объявляете и импользуетет App_Sem в другом модуле. Проследите в отладчике, по каким адресам у вас лежат эти переменные, чем и когда они инициализируются. Спасибо за наводку. Сейчас попробую :rolleyes: Во-первых, пользуйтесь тегом code для вставки исходных текстов. Во-вторых, вы не показали здесь функцию прерывания, в которой делается OSSemPost. Попытаюсь проявить телепатические способности: Вызов OSSemPost у вас происходит в другом модуле, а App_Sem в приведенном вами тексте объявлен как static, то есть его область видимости ограничена этим модулем (единицей компиляции). Соответственно, переменная App_Sem, которую вы используете в OSSemPost - это другая переменная в другой области видимости, которая у вас не инициализируется. Покажите свой код, как вы объявляете и импользуете App_Sem в другом модуле. Проследите в отладчике, по каким адресам у вас лежат эти переменные, чем и когда они инициализируются. Вот обработчик, вызываемый из приведенного выше асмового обработчика. Эта процедура находится в файле bsp.c. App_Sem и задача объявляются в App.c. А не подскажете, как надо правильно объявлять App_Sem чтобы он всюду был виден? void BSP_USARTC0_RXC_IRQ_Hndlr (void) { CPU_INT08U temp; temp = USARTC0.DATA; OSSemPost(App_Sem); BSP_LED_Toggle(8); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andy_Mozzhevilov 0 26 августа, 2009 Опубликовано 26 августа, 2009 · Жалоба Вот обработчик, вызываемый из приведенного выше асмового обработчика. Эта процедура находится в файле bsp.c. App_Sem и задача объявляются в App.c. А не подскажете, как надо правильно объявлять App_Sem чтобы он всюду был виден? Говорю же, у вас проблемы с Си, а вы сразу за ОС. Читайте о ключевом слове extern. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitek101 0 26 августа, 2009 Опубликовано 26 августа, 2009 · Жалоба Говорю же, у вас проблемы с Си, а вы сразу за ОС. Читайте о ключевом слове extern. Заработало! Спасибо!!! :08: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться