реклама на сайте
подробности

 
 
> xSemaphoreTake() первый раз не получать, Первый вызов на свежем семафоре всегда pdTRUE
Cosmojam
сообщение Feb 10 2012, 13:25
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 311
Регистрация: 12-01-11
Из: Калининград (Koenigsberg)
Пользователь №: 62 182



Собственно вопрос. Создал семафор при вызове задачи, вошёл в цикл и должен упереться в него пока семафор не будет отдан из прерывания или ещё откуда. Но первый вызов xSemaphoreTake() всегда pdTRUE независимо от того был он дан или нет. Есть ли правильный способ бороться с этим кроме "холостого" взятия семафора сразу после создания до входа в цикл или установкой флагов "первый раз" ?


--------------------
typedef enum { no, yes, maybe } bool; | блог тут
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aaarrr
сообщение Feb 11 2012, 11:24
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



И получите в коде холостую последовательность xSemaphoreGive() - xSemaphoreTake(). Красиво?
Go to the top of the page
 
+Quote Post
Dele
сообщение Apr 7 2014, 20:06
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 12-06-10
Пользователь №: 57 898



Цитата(aaarrr @ Feb 11 2012, 15:24) *
И получите в коде холостую последовательность 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)
{}

}
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 8 2014, 02:44
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Dele @ Apr 7 2014, 22:06) *
Я ничего не понял, столкнулся с той же проблемой что у автора, объясните поподробней плиз

1) Я ничего не понял, объясните, что у вас за проблема?
2) Вы заметили, что ваше сообщение несколько отличается оформлением от предыдущих?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Dele
сообщение Apr 8 2014, 04:40
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 12-06-10
Пользователь №: 57 898



Цитата(Сергей Борщ @ Apr 8 2014, 06:44) *
1) Я ничего не понял, объясните, что у вас за проблема?
2) Вы заметили, что ваше сообщение несколько отличается оформлением от предыдущих?

Проблема аналогична, создаю семафор, в прерывание даю его задаче которая зажигает светодиод, но задача сразу выпонялется, семафор есть без прерыания...
По программе: 2 семафора, 2 прерывания, 2 разных обработчика и задачи но по сути они зеракально копируют друг друга просто зажигают разные светодиоды...

ПС. простите за оформление... Я только начал приобщаться к форуму)

CODE

#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 ) ;
Ну явно это как то отходит от примеров в книгах...

Сообщение отредактировал Dele - Apr 8 2014, 04:28
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Cosmojam   xSemaphoreTake() первый раз не получать   Feb 10 2012, 13:25
- - aaarrr   Цитата(Cosmojam @ Feb 10 2012, 17:25) Ест...   Feb 10 2012, 13:47
- - Cosmojam   И что он будет делать? Захватывать свежесозданный ...   Feb 10 2012, 17:36
|- - aaarrr   Цитата(Cosmojam @ Feb 10 2012, 21:36) И ч...   Feb 10 2012, 17:45
- - Cosmojam   Всё, теперь понял, ларчик просто открывался Спаси...   Feb 10 2012, 18:49
- - Bass   или просто сразу взять семафор после его создания   Feb 11 2012, 05:15
- - aaarrr   Так создайте семафор приведенным выше макросом. Не...   Apr 8 2014, 05:32
|- - Dele   Цитата(aaarrr @ Apr 8 2014, 09:32) Так со...   Apr 8 2014, 10:39
|- - aaarrr   Цитата(Dele @ Apr 8 2014, 14:39) Немного ...   Apr 8 2014, 11:16
|- - Dele   Цитата(aaarrr @ Apr 8 2014, 15:16) Соверш...   Apr 8 2014, 16:10
- - aaarrr   Пардон, должно быть: КодS = xSemaphoreCreateBinary...   Apr 8 2014, 16:37
- - Dele   Цитата(aaarrr @ Apr 8 2014, 20:37) Пардон...   Apr 9 2014, 02:30
- - LightElf   QUOTE (Dele @ Apr 9 2014, 06:30) Но все р...   Apr 9 2014, 03:43


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 10:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01436 секунд с 7
ELECTRONIX ©2004-2016