Cosmojam 0 10 февраля, 2012 Опубликовано 10 февраля, 2012 · Жалоба Собственно вопрос. Создал семафор при вызове задачи, вошёл в цикл и должен упереться в него пока семафор не будет отдан из прерывания или ещё откуда. Но первый вызов xSemaphoreTake() всегда pdTRUE независимо от того был он дан или нет. Есть ли правильный способ бороться с этим кроме "холостого" взятия семафора сразу после создания до входа в цикл или установкой флагов "первый раз" ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 10 февраля, 2012 Опубликовано 10 февраля, 2012 · Жалоба Есть ли правильный способ бороться с этим кроме "холостого" взятия семафора сразу после создания до входа в цикл или установкой флагов "первый раз" ? Напишите свой макрос для создания закрытого семафора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Cosmojam 0 10 февраля, 2012 Опубликовано 10 февраля, 2012 · Жалоба И что он будет делать? Захватывать свежесозданный семафор в первый? Я не уверен что это правильно, поэтому спрашиваю. Или Вы про что-то другое? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 10 февраля, 2012 Опубликовано 10 февраля, 2012 · Жалоба И что он будет делать? Захватывать свежесозданный семафор в первый? Нет, разумеется. Он будет создавать семафор, но не будет затем вызывать xSemaphoreGive, в отличие от "родного" макроса. #define xSemaphoreCreateBinaryDisabled() xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Cosmojam 0 10 февраля, 2012 Опубликовано 10 февраля, 2012 · Жалоба Всё, теперь понял, ларчик просто открывался :) Спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bass 0 11 февраля, 2012 Опубликовано 11 февраля, 2012 · Жалоба или просто сразу взять семафор после его создания Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 11 февраля, 2012 Опубликовано 11 февраля, 2012 · Жалоба И получите в коде холостую последовательность xSemaphoreGive() - xSemaphoreTake(). Красиво? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dele 0 7 апреля, 2014 Опубликовано 7 апреля, 2014 · Жалоба И получите в коде холостую последовательность xSemaphoreGive() - xSemaphoreTake(). Красиво? Я ничего не понял, столкнулся с той же проблемой что у автора, объясните поподробней плиз. #include "stm32l1xx_gpio.h" #include "stm32l1xx_rcc.h" #include "stm32l1xx.h" #include "stm32l1xx_exti.h" #include "misc.h" #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" #include "croutine.h" xTaskHandle xp; xTaskHandle xp1; xSemaphoreHandle xBS; xSemaphoreHandle xBS1; static void prvLedBlink( void *pvParameters ); static void prvLedBlink2( void *pvParameters ); void vApplicationIdleHook( void ){} void vApplicationMallocFailedHook( void ){ for( ;; );} void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) { ( void ) pcTaskName; ( void ) pxTask; for( ;; );} void vApplicationTickHook( void ){} void RCC_Configuration(void) { SystemInit(); // Сброс по умолчанию GPIO_DeInit(GPIOA); GPIO_DeInit(GPIOB); GPIO_DeInit(GPIOC); GPIO_DeInit(GPIOD); GPIO_DeInit(GPIOE); RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOAEN, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIODEN, ENABLE); } void init_led() { GPIO_InitTypeDef PORT; PORT.GPIO_Pin = (GPIO_Pin_7 | GPIO_Pin_6); PORT.GPIO_Mode = GPIO_Mode_OUT; PORT.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init( GPIOB , &PORT); } void init_but() { GPIO_InitTypeDef BUTA; BUTA.GPIO_Pin = GPIO_Pin_0; BUTA.GPIO_Mode = GPIO_Mode_IN; BUTA.GPIO_Mode = GPIO_PuPd_NOPULL; // Хардварная кнопка и так подтянута BUTA.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init( GPIOA , &BUTA); GPIO_InitTypeDef BUTD; BUTD.GPIO_Pin = GPIO_Pin_2; BUTD.GPIO_Mode = GPIO_Mode_IN; BUTD.GPIO_Mode = GPIO_PuPd_UP; BUTD.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init( GPIOD , &BUTD); } void exiti() { __enable_irq (); RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; SYSCFG->EXTICR[0]|=SYSCFG_EXTICR1_EXTI0_PA; //линии конфирурируем SYSCFG->EXTICR[0]|=SYSCFG_EXTICR1_EXTI2_PD; EXTI->IMR|=EXTI_IMR_MR0; //разрешение прерывания всех Px0 EXTI->IMR|=EXTI_IMR_MR2; //разрешение прерывания всех Px2 EXTI->RTSR|=EXTI_RTSR_TR0; //фронт нарост EXTI->RTSR|=EXTI_FTSR_TR2; //фронт спад EXTI->RTSR|=EXTI_RTSR_TR2; //фронт нарост EXTI->RTSR|=EXTI_FTSR_TR0; //фронт спад NVIC_EnableIRQ (EXTI0_IRQn); // Разрешаем прерывания NVIC_EnableIRQ (EXTI2_IRQn); // Разрешаем прерывания NVIC_SetPriority(EXTI0_IRQn, 3); NVIC_SetPriority(EXTI2_IRQn, 3); } void EXTI0_IRQHandler(void) { //GPIO_SetBits(GPIOB, GPIO_Pin_6); EXTI->PR |= EXTI_PR_PR0;//сбросили бит прерывания GPIO_SetBits(GPIOB, GPIO_Pin_7); BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(xBS, xHigherPriorityTaskWoken); if( xHigherPriorityTaskWoken == pdFALSE ) { portYIELD(); } //taskYIELD(); } void EXTI2_IRQHandler(void) { //GPIO_SetBits(GPIOB, GPIO_Pin_7); portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(xBS, xHigherPriorityTaskWoken); EXTI->PR |= EXTI_PR_PR2;//сбросили бит прерывания taskYIELD(); } void prvLedBlink( void *pvParameters ) { while(1){ xSemaphoreTake( xBS, portMAX_DELAY ); GPIO_SetBits(GPIOB, GPIO_Pin_6); taskYIELD(); } } void prvLedBlink2( void *pvParameters ) { while(1){ xSemaphoreTake( xBS1, portMAX_DELAY ); GPIO_SetBits(GPIOB, GPIO_Pin_7); taskYIELD(); } } int main(void) { RCC_Configuration(); init_led(); init_but(); exiti(); int i; vSemaphoreCreateBinary(xBS); vSemaphoreCreateBinary(xBS1); if( xBS != NULL ) { xTaskCreate(prvLedBlink,"LED",configMINIMAL_STACK_SIZE, NULL, 1, &xp); } if( xBS1!= NULL ){ xTaskCreate(prvLedBlink2,"LED2",configMINIMAL_STACK_SIZE, NULL, 1, &xp); } xTaskCreate(prvLedBlink2,"LED2",configMINIMAL_STACK_SIZE, NULL, 1, &xp1); vTaskStartScheduler(); while(1) {} } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 8 апреля, 2014 Опубликовано 8 апреля, 2014 · Жалоба Я ничего не понял, столкнулся с той же проблемой что у автора, объясните поподробней плиз 1) Я ничего не понял, объясните, что у вас за проблема? 2) Вы заметили, что ваше сообщение несколько отличается оформлением от предыдущих? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dele 0 8 апреля, 2014 Опубликовано 8 апреля, 2014 (изменено) · Жалоба 1) Я ничего не понял, объясните, что у вас за проблема? 2) Вы заметили, что ваше сообщение несколько отличается оформлением от предыдущих? Проблема аналогична, создаю семафор, в прерывание даю его задаче которая зажигает светодиод, но задача сразу выпонялется, семафор есть без прерыания... По программе: 2 семафора, 2 прерывания, 2 разных обработчика и задачи но по сути они зеракально копируют друг друга просто зажигают разные светодиоды... ПС. простите за оформление... Я только начал приобщаться к форуму) #include "stm32l1xx_gpio.h" #include "stm32l1xx_rcc.h" #include "stm32l1xx.h" #include "stm32l1xx_exti.h" #include "misc.h" #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" #include "croutine.h" xTaskHandle xp; xTaskHandle xp1; xSemaphoreHandle xBS; xSemaphoreHandle xBS1; static void prvLedBlink( void *pvParameters ); static void prvLedBlink2( void *pvParameters ); void vApplicationIdleHook( void ){} void vApplicationMallocFailedHook( void ){ for( ;; );} void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) { ( void ) pcTaskName; ( void ) pxTask; for( ;; );} void vApplicationTickHook( void ){} void RCC_Configuration(void) { SystemInit(); // Сброс по умолчанию GPIO_DeInit(GPIOA); GPIO_DeInit(GPIOB); GPIO_DeInit(GPIOC); GPIO_DeInit(GPIOD); GPIO_DeInit(GPIOE); RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOAEN, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIODEN, ENABLE); } void init_led() { GPIO_InitTypeDef PORT; PORT.GPIO_Pin = (GPIO_Pin_7 | GPIO_Pin_6); PORT.GPIO_Mode = GPIO_Mode_OUT; PORT.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init( GPIOB , &PORT); } void init_but() { GPIO_InitTypeDef BUTA; BUTA.GPIO_Pin = GPIO_Pin_0; BUTA.GPIO_Mode = GPIO_Mode_IN; BUTA.GPIO_Mode = GPIO_PuPd_NOPULL; // Хардварная кнопка и так подтянута BUTA.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init( GPIOA , &BUTA); GPIO_InitTypeDef BUTD; BUTD.GPIO_Pin = GPIO_Pin_2; BUTD.GPIO_Mode = GPIO_Mode_IN; BUTD.GPIO_Mode = GPIO_PuPd_UP; BUTD.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init( GPIOD , &BUTD); } void exiti() { __enable_irq (); RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; SYSCFG->EXTICR[0]|=SYSCFG_EXTICR1_EXTI0_PA; //линии конфирурируем SYSCFG->EXTICR[0]|=SYSCFG_EXTICR1_EXTI2_PD; EXTI->IMR|=EXTI_IMR_MR0; //разрешение прерывания всех Px0 EXTI->IMR|=EXTI_IMR_MR2; //разрешение прерывания всех Px2 EXTI->RTSR|=EXTI_RTSR_TR0; //фронт нарост EXTI->RTSR|=EXTI_FTSR_TR2; //фронт спад EXTI->RTSR|=EXTI_RTSR_TR2; //фронт нарост EXTI->RTSR|=EXTI_FTSR_TR0; //фронт спад NVIC_EnableIRQ (EXTI0_IRQn); // Разрешаем прерывания NVIC_EnableIRQ (EXTI2_IRQn); // Разрешаем прерывания NVIC_SetPriority(EXTI0_IRQn, 3); NVIC_SetPriority(EXTI2_IRQn, 3); } void EXTI0_IRQHandler(void) { //GPIO_SetBits(GPIOB, GPIO_Pin_6); EXTI->PR |= EXTI_PR_PR0;//сбросили бит прерывания GPIO_SetBits(GPIOB, GPIO_Pin_7); // Green для проверки произошло ли прерывание BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(xBS, xHigherPriorityTaskWoken); if( xHigherPriorityTaskWoken == pdTRUE ) { portYIELD(); } //taskYIELD(); } void EXTI2_IRQHandler(void) { //GPIO_SetBits(GPIOB, GPIO_Pin_7); portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(xBS, xHigherPriorityTaskWoken); EXTI->PR |= EXTI_PR_PR2;//сбросили бит прерывания taskYIELD(); } void prvLedBlink( void *pvParameters ) { portBASE_TYPE xStatus; while(1){ xStatus=xSemaphoreTake( xBS, portMAX_DELAY ); if (xStatus == pdPASS) { GPIO_SetBits(GPIOB, GPIO_Pin_6); } EXTI->PR |= EXTI_PR_PR0;//сбросили бит прерывания taskYIELD(); } } void prvLedBlink2( void *pvParameters ) { while(1){ xSemaphoreTake( xBS1, portMAX_DELAY ); GPIO_SetBits(GPIOB, GPIO_Pin_7); taskYIELD(); } } int main(void) { RCC_Configuration(); init_led(); init_but(); exiti(); int i; vSemaphoreCreateBinary(xBS); vSemaphoreCreateBinary(xBS1); if( xBS != NULL ) { xTaskCreate(prvLedBlink,"LED",configMINIMAL_STACK_SIZE, NULL, 0, &xp); } //if( xBS1!= NULL ){ //xTaskCreate(prvLedBlink2,"LED2",configMINIMAL_STACK_SIZE, NULL, 1, &xp); // } //xTaskCreate(prvLedBlink2,"LED2",configMINIMAL_STACK_SIZE, NULL, 1, &xp1); vTaskStartScheduler(); while(1) {} } Проблему решил но считаю что что-то все равно не так как должно быть, я после создания семафора сразу беру его vSemaphoreCreateBinary(xBS); vSemaphoreCreateBinary(xBS1); xSemaphoreTake(xBS, pdFALSE ) ; xSemaphoreTake(xBS1, pdFALSE ) ; Ну явно это как то отходит от примеров в книгах... Изменено 8 апреля, 2014 пользователем Dele Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 8 апреля, 2014 Опубликовано 8 апреля, 2014 · Жалоба Так создайте семафор приведенным выше макросом. Не будет лишнего Give-Take. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dele 0 8 апреля, 2014 Опубликовано 8 апреля, 2014 · Жалоба Так создайте семафор приведенным выше макросом. Не будет лишнего Give-Take. Немного не понял, как создать таким образом семафор. В queue.h нету такого определения, Coocox выдает: C:\CooCox\CoIDE\workspace\ledexitl/main.c:148: undefined reference to `SemaphoreCreateBinaryDisabled' вы меня простите я учусь, ткните меня как это сделать пожалуйста) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 8 апреля, 2014 Опубликовано 8 апреля, 2014 (изменено) · Жалоба Немного не понял, как создать таким образом семафор. В queue.h нету такого определения Совершенно верно, его там нет. Поэтому добавьте упомянутый #define в любом удобном месте: #define xSemaphoreCreateBinaryDisabled() xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ) xSemaphoreHandle S; int main(void) { S = xSemaphoreCreateBinaryDisabled(); } Лучше, конечно, в какой-нибудь заголовочный файл. Изменено 8 апреля, 2014 пользователем aaarrr Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dele 0 8 апреля, 2014 Опубликовано 8 апреля, 2014 · Жалоба Совершенно верно, его там нет. Поэтому добавьте упомянутый #define в любом удобном месте: #define xSemaphoreCreateBinaryDisabled() xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ) xSemaphoreHandle S; int main(void) { xSemaphoreCreateBinaryDisabled(S) } Лучше, конечно, в какой-нибудь заголовочный файл. Добавил строчку в queue.h в итоге: [cc] C:\CooCox\CoIDE\workspace\ledexitl\main.c:148:37: error: macro "xSemaphoreCreateBinaryDisabled" passed 1 arguments, but takes just 0 [cc] xSemaphoreCreateBinaryDisabled(xBS1); [cc] ^ [cc] C:\CooCox\CoIDE\workspace\ledexitl\main.c:148:2: error: 'xSemaphoreCreateBinaryDisabled' undeclared (first use in this function) Как то так... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 8 апреля, 2014 Опубликовано 8 апреля, 2014 · Жалоба Пардон, должно быть: S = xSemaphoreCreateBinaryDisabled(); CCCV иногда подводит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться