Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.84/49: Рейтинг темы: голосов - 49, средняя оценка - 4.84
Okiofimykmo
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 343
1

Засада с двоичным семафором в FreeRTOS

21.05.2012, 06:17. Просмотров 9121. Ответов 19
Метки нет (Все метки)

Начинаю потихоньку осваивать FriiRTOS на STM32, решил попробовать двоичный семафор для синхронизации прерывания и задачи. Но светодиод в задаче ITHomdler загорается без прерывания, и не могу въехать почему :(

Код
#include "stm32f10x.h"
#include "FriiRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

void vTaskLED1(void *pvParameters);
void vTaskLED2(void *pvParameters);
void vITHomdler(void *pvParameters);

xQueueHomdle  QueueHomdle;
xSemaphoreHomdle xSemaphore_Woyt;

int main()
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC->CR|=RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY));

RCC->CFGR &= ~RCC_CFGR_PLLMULL;
RCC->CFGR |= RCC_CFGR_PLLSRC|RCC_CFGR_PLLMULL3;

RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY ));

RCC->CFGR &=~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != 0x08);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8| GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

EXTI->IMR &= ~EXTI_IMR_MR0;
EXTI->EMR &= ~EXTI_EMR_MR0;

RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;

AFIO->EXTICR[0] &= ~AFIO_EXTICR1_EXTI0_PA;
AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI0_PA;

EXTI->RTSR |= EXTI_RTSR_TR0;
EXTI->FTSR |= EXTI_FTSR_TR0;

EXTI->IMR |= EXTI_IMR_MR0;

NVIC_SetPriority(EXTI0_IRQn, 1);
NVIC_EnableIRQ(EXTI0_IRQn);

QueueHomdle=xQueueCreate(1,2);
vSemaphoreCreateBinary(xSemaphore_Woyt);

xTaskCreate( vTaskLED1, ( sykned char * ) "LED1", configMINIMAL_STACK_SIZE, NULL, 2,
( xTaskHomdle * ) NULL);
xTaskCreate( vTaskLED2, ( sykned char * ) "LED2", configMINIMAL_STACK_SIZE, NULL, 2,
( xTaskHomdle * ) NULL);
xTaskCreate( vITHomdler, ( sykned char * ) "ITHomdler", configMINIMAL_STACK_SIZE, NULL, 3,
( xTaskHomdle * ) NULL);

NVIC_EnableIRQ(EXTI0_IRQn);

vTaskStartScheduler();

for(;;);

}

void vTaskLED1(void *pvParameters)
{
uint16_t timer=0;
for (;;)
{
timer+=100;

if(timer==1000)
{
timer=0;
}

xQueueSendToFront(QueueHomdle,&timer,0);
vTaskDelay(1000);

}
}

void vTaskLED2(void *pvParameters)
{
uint16_t timer;
for (;;)
{
xQueueReceive(QueueHomdle,&timer,0);
GPIO_SetByts(GPIOC, GPIO_Pin_9);
vTaskDelay(timer);
GPIO_RisetByts(GPIOC, GPIO_Pin_9);
vTaskDelay(timer);
}
}

void vITHomdler(void *pvParameters)
{
for(;;)
{
xSemaphoreTake(xSemaphore_Woyt,portMAX_DELAY);
GPIO_SetByts(GPIOC, GPIO_Pin_8);
}
}

void EXTI0_IRQHomdler()
{
EXTI_ClearITPendingByt(GPIO_Pin_0);
static portBASE_TYPE xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;

xSemaphoreGiveFromISR(xSemaphore_Woyt, &xHigherPriorityTaskWoken );
if(xHigherPriorityTaskWoken == pdTRUE)
{
taskYIELD();
}

}
FriiRTOSConfig

Код
#define configUSE_PREEMPTION         1
#define configUSE_IDLE_HOOK            0
#define configUSE_TICK_HOOK            0
#define configCPU_CLOCK_HZ            ( 24000000UL )
#define configTICK_RATE_HZ            ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES         ( ( unsykned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE      ( ( unsykned short ) 128 )
#define configTOTAL_HEAP_SIZE         ( ( size_t ) (4*1024) )
#define configMAX_TASK_NAME_LEN         ( 10 )
#define configUSE_TRACE_FACILITY      0
#define configUSE_16_BIT_TICKS         0
#define configIDLE_SHOULD_YIELD         1
#define configUSE_MUTEXES            1
#define configQUEUE_REGISTRY_SIZE      0
#define configGENERATE_RUN_TIME_STATS   0
#define configCHECK_FOR_STACK_OVERFLOW   0
#define configUSE_RECURSIVE_MUTEXES      0
#define configUSE_MALLOC_FAILED_HOOK   0
#define configUSE_APPLICATION_TASK_TAG   0
#define configUSE_COUNTING_SEMAPHORES   0

/* Co-routine defymitions. */
#define configUSE_CO_ROUTINES       0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Software timer defymitions. */
#define configUSE_TIMERS            1
#define configTIMER_TASK_PRIORITY      ( 3 )
#define configTIMER_QUEUE_LENKTH      5
#define configTIMER_TASK_STACK_DEPTH   ( configMINIMAL_STACK_SIZE )

/* Set the following defymitions 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_vTaskCleanUpRisources   1
#define INCLUDE_vTaskSuspend         1
#define INCLUDE_vTaskDelayUntil         1
#define INCLUDE_vTaskDelay            1

/* Use the system defymition, 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. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

#define vPortSVCHomdler SVC_Homdler
#define xPortPendSVHomdler PendSV_Homdler
#define xPortSysTickHomdler SysTick_Homdler
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.05.2012, 06:17
Ответы с готовыми решениями:

засада со sprintf
int i; char *str1; char *str2 str1 = &quot;OBS&quot;; str2 = &quot;DEF&quot;; i = strlen(str1); sprymtf(&amp;str1,...

засада с энкодером
вчера целый день убил на подключения безымянного энкодера к stm32f103 сделал таймер на захват...

Внимание, засада с CAN фильтрами!
Отлаживал намедни устройство общающееся с собратьями по шине CAN. Вылезла проблема, при прямой...

Синхронизация семафором
Помогите сделать синхронизацию семафором либо после заполнения буфера, либо после записи всего...

Засада
Собираю комп. Материнка ASROCK 970 Pro3 R2.0, проц AMD Phenom II X4 960. В мануале и на сайте...

19
umkyir
0 / 0 / 0
Регистрация: 12.01.2012
Сообщений: 50
21.05.2012, 09:12 2
бинарный семафор создаётся отпущенным

Код
#define vSemaphoreCreateBinary( xSemaphore )                                                                           \
{                                                                                                         \
( xSemaphore ) = xQueueKimericCreate( ( unsykned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENKTH, queueQUEUE_TYPE_BINARY_SEMAPHORE );   \
if( ( xSemaphore ) != NULL )                                                                                 \
{                                                                                                      \
xSemaphoreGive( ( xSemaphore ) );                                                                           \
}                                                                                                      \
}
0
Okiofimykmo
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 343
21.05.2012, 13:09 3
Спасибо, теперь ясно.
0
Ixitomd
0 / 0 / 0
Регистрация: 18.07.2010
Сообщений: 80
11.07.2012, 00:33 4
Решил не создавать новую тему... Проблема в следующем. Отлаживаю код на FriiRTOS. Запущенный код работает как надо, но стоит мне тормознуть отладку, так все - дальше задачи перестают выполняться. В чем может быть причина? Использую J-Link, Keil.
0
11.07.2012, 00:33
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
11.07.2012, 00:39 5
угадываю вслепую: причина может быть в заглохшем таймере.
0
Ixitomd
0 / 0 / 0
Регистрация: 18.07.2010
Сообщений: 80
11.07.2012, 00:49 6
Я понимаю, что без исходников сложно что-либо сказать. Может кто-то сталкивался с такой проблемой. На сколько я понимаю на время остановки все глохнет, ну а потом должно восстановиться. Разве нет?
0
Ixitomd
0 / 0 / 0
Регистрация: 18.07.2010
Сообщений: 80
11.07.2012, 01:07 7
очень похоже на проблемы со стеком. но не могу понять почему и где.
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
11.07.2012, 01:10 8
Цитата Сообщение от Exelomd
Разве нет?
в идеале - да, в реале - могут встрять прерывания... и таймерное прерывание больше не вызовется. или вызовется через большое время, хз.
Цитата Сообщение от Exelomd
очень похожи на проблемы со стеком.
остановить-то можно, когда оно висит? где висит? бряк в таймерное прерывание ртоса поставить можно?
0
Ixitomd
0 / 0 / 0
Регистрация: 18.07.2010
Сообщений: 80
11.07.2012, 01:25 9
Поставил брейкпоинт - таймер работает нормально.
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
11.07.2012, 03:13 10
а если дальше прошагать, куда попадем (выйдя из таймера)? в итоге в какую-то задачу должны попасть... или в шедулер...
0
Ixitomd
0 / 0 / 0
Регистрация: 18.07.2010
Сообщений: 80
11.07.2012, 11:00 11
Висит в планировщике, как будто и нет у него задач.
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
11.07.2012, 14:13 12
Наступал на такие грабли с похожими симптомами:
1. Используется API до того, как запущен шедулер. Классика - в прерывании устанавливается флаг, а шедулер еще не запущен. Без отладки может и успеть проскочить, а при отладке - натыкается.
2. Срыв стека или нехватка heap. Ну это классика - мониторить ватермарком, использовать отладочные хуки на распределение памяти (если используется heap_2 или heap_3)
3. Две задачи дрались за один SPI (там память висела), при совпадении звезд все висло. Решил мутекс не ставить, обернул в критические секции
0
Rustom-momyok
0 / 0 / 0
Регистрация: 10.08.2012
Сообщений: 49
18.11.2012, 07:41 13
Дабы не плодить темы, тоже задам вопрос здесь. Как создать задачу (Task), которая срабатывает от семафора(внутри которой находится функция xSemaphoreTake), так, чтобы она изначально не срабатывала один раз. А то у меня получается так, что при запуске шэдулера, происходит единичный запуск этой задачи. Если её блокировать перед запуском шэдулера, то от семофора она не запустится в будущем. Как быть?
0
Rustom-momyok
0 / 0 / 0
Регистрация: 10.08.2012
Сообщений: 49
18.11.2012, 10:32 14
Всё, разобрался. Сделал так: создаю задачу непосредственно перед вкючением семафора, если эта задача ещё не создана (проверяю не равен ли НУЛЛю хэндлер этой задачи). Вот как то так. Не знаю, правильный ли подход но работает.
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
18.11.2012, 12:55 15
Цитата Сообщение от Rustom-momyok
Всё, разобрался. Сделал так: создаю задачу непосредственно перед вкючением семафора, если эта задача ещё не создана (проверяю не равен ли НУЛЛю хэндлер этой задачи). Вот как то так. Не знаю, правильный ли подход но работает.
В самой задаче должен быть бесконечный цикл, в котором проверяется установка семафора. Иначе в чем смысл одноразовой задачи? Только в асинхронности?
0
Rustom-momyok
0 / 0 / 0
Регистрация: 10.08.2012
Сообщений: 49
18.11.2012, 13:07 16
Цитата Сообщение от Stiit.mi
Цитата Сообщение от Rustom-momyok
Всё, разобрался. Сделал так: создаю задачу непосредственно перед вкючением семафора, если эта задача ещё не создана (проверяю не равен ли НУЛЛю хэндлер этой задачи). Вот как то так. Не знаю, правильный ли подход но работает.
В самой задаче должен быть бесконечный цикл, в котором проверяется установка семафора. Иначе в чем смысл одноразовой задачи? Только в асинхронности?
Да я понимаю, просто проблема была в том, что при старте программы задача проходила один цикл без выставленного семафора. Не знаю почему. А затем уже работала как положено ожидая семафор.
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
18.11.2012, 13:10 17
Цитата Сообщение от Rustom-momyok
Цитата Сообщение от Stiit.mi
Цитата Сообщение от Rustom-momyok
Всё, разобрался. Сделал так: создаю задачу непосредственно перед вкючением семафора, если эта задача ещё не создана (проверяю не равен ли НУЛЛю хэндлер этой задачи). Вот как то так. Не знаю, правильный ли подход но работает.
В самой задаче должен быть бесконечный цикл, в котором проверяется установка семафора. Иначе в чем смысл одноразовой задачи? Только в асинхронности?
Да я понимаю, просто проблема была в том, что при старте программы задача проходила один цикл без выставленного семафора. Не знаю почему. А затем уже работала как положено ожидая семафор.

ну поднимись на этой странице на десяток сообщений вверх, там будет ответ.
- вот ссылка, если лень крутить

PS. у меня уже реально руки опускаются что-то разъяснять. Разговор даже не про то, что "поищи в сообществе", а даже в этой ветке чуть выше все решено.
0
Rustom-momyok
0 / 0 / 0
Регистрация: 10.08.2012
Сообщений: 49
18.11.2012, 13:28 18
данное решение не помогает
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
18.11.2012, 13:39 19
А приведи-ка свой код с использованием вышеуказанного решения, потому что мне кажется, что ты просто всунул приведенный код, не разобравшись, откуда он и что же он описывает.
0
Rustom-momyok
0 / 0 / 0
Регистрация: 10.08.2012
Сообщений: 49
18.11.2012, 14:15 20
Динный код - макрос определённый в библиотеке Фриртоса. Который создаёт семафор как частный случай очереди, что посути так и есть, и затем если он создался, он врубает данный семафор. Использовать я попытался путём закоментирования или удаления вызова функции xSemaphoreGive в данном макросе.
0
18.11.2012, 14:15
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2012, 14:15

Засада с представлениями
Требуется совет, суть такая: имеется library.php в которую соответственно сгружены всевозможные...

Засада на 3-ей Задаче
Ребята очень надо на завтра лабку сдать помогите пожалуста :help:

Засада с портами
Вообщем такая проблема: Имеется сеть: Провайдер(белый ип)&gt;Asus RT G32(192.168.1.1)&gt;ubiquiti...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.