Перейти к содержанию
    

maxntf

Участник
  • Постов

    112
  • Зарегистрирован

  • Посещение

Весь контент maxntf


  1. Похоже отладчик всему беда. Вывел сигнал с прерывания таймера на осциллограф, по количеству тактов определил что все работает нормально.
  2. Для проверки работы приоритетов поменял приоритеты задач - программа в Task1 вообще не попадает, значит приоритеты работают. #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 1 #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 12 * 1024 ) ) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configQUEUE_REGISTRY_SIZE 5 #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_MALLOC_FAILED_HOOK 1 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_COUNTING_SEMAPHORES 1 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 /* Standard assert semantics. */ //#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } /* Use the system definition, if there is one */ #ifdef __NVIC_PRIO_BITS #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 /* 15 priority levels */ #endif #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 /* The lowest priority. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Priority 5, or 95 as only the top four bits are implemented. */ /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Run time stats related macros. */ #define configGENERATE_RUN_TIME_STATS 0 /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #endif /* FREERTOS_CONFIG_H */
  3. Судя по чему конкретно? xTaskCreate(Task2, "Task2-handler", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL); Какие проекты, я про конкретный случай спрашиваю. Убрал то, что моск ломает. void Task2(void *pParams) { vSemaphoreCreateBinary(xSem1ms); xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL); while(1); } void Task1(void *pParams) { xSemaphoreTake(xSem1ms, 0); ctim100us = 10; Tx_Init(); xSemaphoreTake(xSem1ms, 10); TIM_DeInit(TIM10); vTaskDelete(NULL); } Если задачи с одинаковым приоритетом, почему? Может где то настройки FreeRTOS? Если Task2 всегда готова к выполнению, то когда срабатывает portEND_SWITCHING_ISR(xHigherPriorityTaskWoken) разве после выхода из прерывания контекст не должен переключится с Task2 на Task1?
  4. Так вот... Упростил как мог, все выкинул никаких тачлибов и всего остального, только 2 задачи. xSemaphoreHandle xSem1ms; volatile uint32_t ctim100us; uint8_t FlagCreateTask; void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); if(ctim100us) ctim100us--; else { xSemaphoreGiveFromISR(xSem1ms, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } } int main(void) { xTaskCreate(Task2, "Task2-handler", configMINIMAL_STACK_SIZE, NULL, 1, NULL); vTaskStartScheduler(); } void Task2(void *pParams) { FlagCreateTask = 0; vSemaphoreCreateBinary(xSem1ms); xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL); while(1) { if(FlagCreateTask != 0) continue; xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL); } } void Task1(void *pParams) { uint16_t count = 3; xSemaphoreTake(xSem1ms, 0); FlagCreateTask = 1; ctim100us = count; Tx_Init(); while(1) { if(xSemaphoreTake(xSem1ms, 10) != pdTRUE) continue; count++; if(count > 9) break; taskENTER_CRITICAL(); ctim100us = count; taskEXIT_CRITICAL(); GPIO_ToggleBits(GPIOB, GPIO_Pin_5);//пин контроля работы программы } TIM_DeInit(TIM10); FlagCreateTask = 0; vTaskDelete(NULL); } После выхода из обработчика прерывания TIM10 в случае выполнения portEND_SWITCHING_ISR(xHigherPriorityTaskWoken) программа попадает в Task2. О Боже, за что? Даже таймер настроен на 100мкс
  5. Таймер тикает очень часто. Пока я в задаче после разблокировки дойду до установки счетчика (в примере не весь код, я его упростил) в новое значение, он может тикнуть еще несколько раз, по этому в это время (по не удается установить новое событие), наполняется счетчик калибровки, который я отнимаю от нового устанавливаемого значения. И вообще я как бы уже понял что и как нужно делать, вся моя затея была концептуально не верна. Но вылезло много глюков с которыми и разбираюсь, почему так получается, чтоб потом не наступать на подобные грабли. По этому просьба больше не писать что я туплю и делаю не так, это не проект а тесты. В частности сейчас у меня проблема, что не работает portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); Докопался portYIELD(), понял что он устанавливает флаг прерывания PendSV, в котором ОС выполняет переключение контекста. А теперь о моих баранах. В Task2(с низким приоритетом) у меня вызывается функция F1() с той самой тачлиб что фигурировала в начале темы. Так вот после выхода из обработчика прерывания в котором вызывался portEND_SWITCHING_ISR(xHigherPriorityTaskWoken), программа попадает в место из картинки. Получается что флаг прерывания PendSV был установлен когда судя по записи __disable_irq() все прерывания били отключены. Убрал нафиг эти __disable_irq() и __enable_irq(). Но все равно не работает. Как бы в отладчике узнать включено ли прерывание для PendSV? P.S. Кстати у меня с калибровкой на 10мкс все работало четко, только потому, что не переключается контекст и время на это не тратится и все успевает. Вот так бывает :)
  6. void vApplicationIdleHook(void) { //HOOK_PULSE; } void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { for(;;); } void vApplicationTickHook(void) { } void vApplicationMallocFailedHook(void) { for(;;); } #define HOOK_PULSE GPIO_ToggleBits(GPIOB, GPIO_Pin_5) - это вывод пина на осциллограф, когда нужно что то проверить. А так они IdleHook, TickHook пока у меня пустые. Шагаю по прерыванию, а после выхода из обработчика прерывания вываливаюсь в Task2 (точнее в тело функции которую она периодически вызывает) с низким приоритетом (приоритет 1) а Task1 который ждет семафор (только у меня событие из очереди) приоритет 2.
  7. Вот пожалуйста. #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 1 #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 170 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 14 * 1024 ) ) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configQUEUE_REGISTRY_SIZE 5 #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_MALLOC_FAILED_HOOK 1 #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_COUNTING_SEMAPHORES 1 /* Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 /* Standard assert semantics. */ //#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for(;; ); } /* Use the system definition, if there is one */ #ifdef __NVIC_PRIO_BITS #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 /* 15 priority levels */ #endif #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 /* The lowest priority. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Priority 5, or 95 as only the top four bits are implemented. */ /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Run time stats related macros. */ #define configGENERATE_RUN_TIME_STATS 0 /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler
  8. Всем участникам спасибо за помощь и в некоторых случаях за "мат". Кое как вроде разобрался, что то может не до понял, в дальнейшем процессе освоения дойдет. Остался один не решенный момент, а именно макрос portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); В начале я думал, что он работает следующим образом: Task1 имеет более высокий приоритет чем Task2, но она заблокирована, а работает Task2. Вдруг в каком то месте Task2 возникает прерывание, в котором происходит разблокировка Task1 (установили семафор например, который ждет Task1). В макросе portYIELD() грубо говоря поменяли адрес (на задачу с большим приоритетом) куда нужно вернуться. После выхода из функции обработки прерывания уже попадаем в Task1, а не возвращаемся в Task2. Но судя по отладке это не так. Кто может без нервов разжевать, как оно работает?
  9. Опыта с freertos мало, точнее нет. Работал только с кооперативной ОС OSA, под pic_и, там все проще. По этому не смог сделать нужное мне на семафорах, в частности мне нужно было задачу разблокировать , а семафор забрать уже так, чтоб посреди этой функции снова не влететь в прерывание. А вот с очередями получилось, так как там можно прочитать сообщение не забирая его тем самым разблокировать задачу, а потом забрать когда задача будет к этому готова. Чтоб народ с ума сводить :). Чем дальше углубляюсь, тем больше вижу, что там куча всего через дефайны дублируется.
  10. #define pdFALSE ( ( BaseType_t ) 0 ) #define pdTRUE ( ( BaseType_t ) 1 ) typedef long BaseType_t; xHigherPriorityTaskWoken и fGiveResult могут быть только 0x00000000 или 0x00000001 (xHigherPriorityTaskWoken & fGiveResult) в результате даст либо 0 либо 1 if(0) нет if(1) да P.S. Ваш вариант с точки зрения читабельности, верный. Фактически в данном случае мой вариант рабочий и перед тем чтоб такое написать я проверил что там за типы данных и какие значения принимают. Так пишу потому что последнее время писал только под pic с очень малым flash и приходилось очень много вот так подтачивать чтоб все влезло. Ваш код займет больше места, особенно если таких сравнений будет много.
  11. Я спроси конкретный пример! А то все пишете плохо да плохо. Отлично понимаю и вообще косяка не вижу. Поразрядное И с однотипными данными в условии, что тут такого!
  12. На семафоре полностью развязать задачу я не смог, а вот с очередями получилось. Реальная задача динамически запускается и удаляется примерно на сотню миллисекунд - передает команду через ИК диод. В общем сделал так, все работает без проблем на любой частоте таймера. void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, fGiveResult = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); if(ctim10ms) ctim10ms--; else { fGiveResult = xQueueSendToBackFromISR(xQueue, (const void *)0, &xHigherPriorityTaskWoken); if(xHigherPriorityTaskWoken & fGiveResult) { portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } else cal_ctim10ms++; } } } void Task_temp(void *pParams) { uint32_t newValue = 100; uint32_t q_buf; xQueue = xQueueCreate(1, sizeof(uint32_t)); ctim10ms = newValue; Tx_Init(); while(1) { xQueuePeek(xQueue, &q_buf, 10); taskENTER_CRITICAL(); ctim10ms = newValue - cal_ctim10ms; cal_ctim10ms = 0; taskEXIT_CRITICAL(); GPIO_ToggleBits(GPIOB, GPIO_Pin_5);//пин контроля работы программы xQueueReceive(xQueue, &q_buf, 0); } } Если кто объяснит почему так нельзя приведя реальный пример как нужно - респект!
  13. В моем случае не совсем так. у меня запускается планировщик, где то по середине прерывается, и запускается снова и так бесконечно. Так как задача всегда READY, но семафор обработать не успевает. Конкретно в моем варианте нужно так: void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, fGiveResult = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); if(ctim10ms) ctim10ms--; else { fGiveResult = xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken & fGiveResult); } } } P.S. На своей плате поднять частоту я не могу (на данный момент), а пропустить несколько отсчетов по 10мкс. в данном случае не критично и всегда можно подкорректировать. Задача в первую очередь была понять почему так, а путей решения всегда бывает больше чем один!
  14. Все разобрался, не верно обрабатывал семафор. Нужно было так: void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); if(ctim10ms) ctim10ms--; else { if(xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken) != pdFAIL) portEND_SWITCHING_ISR(1); } } } Осталось понять нафиг xHigherPriorityTaskWoken. И почему во всех примерах так xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); А у меня не работает? P.S. Все понял. У меня задача всегда READY. Но в нее не успеваем попасть, и все время выполняем решедулинг!
  15. Да так и есть. Включаем, когда готовы принимать семафор. Ага. Но только если я долблю таймером xSemaphoreGiveFromISR без обработки переменной каждые 10мкс все работает. xSemaphoreGiveFromISR() не должна повторно устанавливать семафор пока задача его не заберет, соответственно возвращает FALSE и portEND_SWITCHING_ISR ничего не переключает. #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() Я как бы увидел что происходит. В неработающем варианте xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken); всегда возвращается pdTREU - соответственно постоянно перевызывается планировщик - почему так?
  16. Привожу проблемные участки кода (инициализация та что в пост №68): 1. Не работает. void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); if(ctim10ms) ctim10ms--; else { xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } } void Task_temp(void *pParams) { vSemaphoreCreateBinary(xSemNx); xSemaphoreTake(xSemNx, 0); ctim10ms = 10; Tx_Init(); while(1) { xSemaphoreTake(xSemNx, 10); ctim10ms = 10; GPIO_ToggleBits(GPIOB, GPIO_Pin_5);//пин контроля работы программы } } 2. Работает void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); if(ctim10ms) ctim10ms--; else { disableInterruptTIM10(); xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } } void Task_temp(void *pParams) { vSemaphoreCreateBinary(xSemNx); xSemaphoreTake(xSemNx, 0); ctim10ms = 10; Tx_Init(); while(1) { enableInterruptTIM10(); xSemaphoreTake(xSemNx, 10); ctim10ms = 10; GPIO_ToggleBits(GPIOB, GPIO_Pin_5);//пин контроля работы программы } } 3.Работает void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } void Task_temp(void *pParams) { vSemaphoreCreateBinary(xSemNx); xSemaphoreTake(xSemNx, 0); Tx_Init(); while(1) { xSemaphoreTake(xSemNx, 10); GPIO_ToggleBits(GPIOB, GPIO_Pin_5);//пин контроля работы программы } }
  17. Не в одном месте. в прерывании отключаем при установке семафора, в задаче включаем после того как забрали семафор и выполнили обработку.
  18. ну в смысле включать и выключать прерывания enableInterruptTIM10() и disableInterruptTIM10() (они в примере закомментированы)
  19. В общем выкинул все лишнее из программы. ТО таймера ставил от 10мкс до 1мсек, вообще не влияет. Если оставить как в коде ниже, не работает. Если раскомментировать вкл/выкл прерывания TIM10 - работает. Если закомментированть обработку переменно ctim10ms в обработчике прерываний таймера, просто устанавливать семафор на каждом прерывании - то же работает. void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); if(ctim10ms) ctim10ms--; else { //disableInterruptTIM10(); xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } } #define enableInterruptTIM10() NVIC->ISER[TIM10_IRQn >> 0x05] = (uint32_t)0x01 << (TIM10_IRQn & (uint8_t)0x1F) #define disableInterruptTIM10() NVIC->ICER[TIM10_IRQn >> 0x05] = (uint32_t)0x01 << (TIM10_IRQn & (uint8_t)0x1F) xSemaphoreHandle xSemNx; //управление задачей volatile uint32_t ctim10ms; //счетчик отсчетов по 10 мксек void Tx_Init(void); void Tx_DeInit (void); void Task_temp(void *pParams); int main(void) { GPIO_InitTypeDef GPIO_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; RCC_HSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI); RCC_HSEConfig(RCC_HSE_OFF); while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET); SystemCoreClockUpdate(); SysTick_Config(SystemCoreClock/1000);//TO=1мс NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); NVIC_InitStruct.NVIC_IRQChannel = TIM10_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //NVIC_InitStruct.NVIC_IRQChannelCmd = DISABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 11; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStruct); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); xTaskCreate(Task_temp, "Temp-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL); vTaskStartScheduler(); } void Task_temp(void *pParams) { uint32_t c = 0; vSemaphoreCreateBinary(xSemNx); while(1){ xSemaphoreTake(xSemNx, 0); ctim10ms = 100; Tx_Init(); while(1) { //enableInterruptTIM10(); if(xSemaphoreTake(xSemNx, 10) != pdTRUE) break; c++; ctim10ms = 100; GPIO_ToggleBits(GPIOB, GPIO_Pin_5);//пин контроля работы программы if(c > 200) break; } //disableInterruptTIM10(); TIM_DeInit(TIM10); } } void Tx_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 160-1; TIM_TimeBaseInitStruct.TIM_Prescaler = 0; TIM_TimeBaseInit(TIM10, &TIM_TimeBaseInitStruct); TIM_ITConfig(TIM10, TIM_IT_Update, ENABLE); TIM_Cmd(TIM10, ENABLE); }
  20. Этим и планирую заняться. Попробую добиться глюков на простом коде (если получиться), а потом опишу непонятные мне моменты.
  21. Проблема не с переменной. Я не пойму (от незнания) почему висит ОС вот здесь: В том случае если Task2 еще не дошла до обработки семафора IrState.xSemNx. То есть глючить начинает когда в прерывании первый раз семафор установили, в задаче его еще не забрали (не успели) и потом в прерывании срабатывают снова эти строки каждые 10мкс. (так как IrState.ctim10ms = 0 и его никто не устанавливает).
  22. Где тут куб увидели? Ядра чего ОС? Если да то я писал 1мсек. P.S. На всякий случай, частота тактирования МК - 16МГц.
  23. Потихоньку разбираюсь далее с FreeRTOS. Возникла новая проблема, я ее решил но возможно не совсем правильно и не понимаю из за чего так получилось. Сейчас системный тик 1мсек. Может кто подскажет? Есть таймер настроенный на 10мкс, на каждом прерывании он декрементирует глоб. переменную, значение которой задает Task2 (имеет самый высокий приоритет). Когда переменная = 0, устанавливает семафор, чтоб разбудить задачу, которая установит новое значение переменной. //Task2 ... IrState.ctim10ms = IrState.bRxTx[pValue->nComm][0]; ctx_bit = 1; xSemaphoreTake(IrState.xSemNx, 0); T10_Init(); while(ctx_bit <= IrState.cRxTx[pValue->nComm]) { [b]enableInterruptTIM10();[/b] if(xSemaphoreTake(IrState.xSemNx, 25) != pdTRUE) break; SwitchPWM; IrState.ctim10ms = IrState.bRxTx[pValue->nComm][ctx_bit]; ctx_bit++; } T10_DeInit(); ... void TIM10_IRQHandler(void) { static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET) { TIM_ClearFlag(TIM10, TIM_FLAG_Update); if(IrState.ctim10ms) IrState.ctim10ms--; else { [b]disableInterruptTIM10();[/b] xSemaphoreGiveFromISR(IrState.xSemNx, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } } В общем пока я не начал отключать прерывания таймера (в коде выделил), все висло в обработчике таймера и ни одна задача управление не получает.
  24. Что то кажется мне, что дело не в тачлиб, во второй задаче у меня используется FatFS, я ее прикрутил и просто читаю файл через SPI. Но сейчас вспоминаю, когда я с ней разбирался (поверхностно) особо на детали внимание не обращал, меня интересовало только чтение файла. Но там ведь где то должны быть часы, чтоб указывать время создания/редактирования файла (по идеи). То есть эта библиотека как то должна работать со временем, а где это делается и настраивается я даже не разбирался. Возможно это вторая задача SysTick останавливает. P.S. Хотя вроде нужно самому эти атрибуты заполнять, FatFS за датой не следит, по крайне мере настраивать ее я не находил как. Там есть структура FILINFO, вот пользователь ее сам и заполняет.
×
×
  • Создать...