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

 
 
> FreeRtos проблемы с очередями, Иногда очередь "зависает"
yanvasiij
сообщение Apr 15 2014, 07:57
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Доброго времени суток!

Я не уверен, где конкретно ошибся, но возможно ошибка общего характера и кто-нибудь чего подскажет. Вообщем реализовал функцию, которая посылает запрос на модем и дожидается ответа некоторое время. Сделал это посредством очереди:
CODE
/**
* @brief Отправить строку и дождаться ответа от модема
*
* @param string строка, которую отправляем
* @param dataLen длинна отправляемой строки
* @param answer указатель на строку куда положить ответ
* @param answerLen длинна полученного ответа
* @param timeToWait Время в тиках, указывающее сколько времени ждать ответа от модуля
*/

void bgs2SendString (uint8_t *string, uint32_t dataLen, uint8_t *answer, uint32_t *answerLen, uint32_t timeToWait)
{
uint8_t ch;
*answerLen = 0;
uint32_t len=0;

/**
* Здесь отправляемая строка улетает на модем через уарт
*/
for (uint32_t i = 0; i < dataLen; i++)
{
bgs2Putchar (string[i]);
}
/**
* Здесь дожидаюсь ответа от модема. Если после последнего символа в течении timeToWait не пришел следующий символ,
* то принимаю решение, что строка с ответом полностью получена.
*/
while ( pdTRUE == xQueueReceive( uartRxData, &ch, timeToWait) )
{
putchar(ch);
answer[len] = ch;
len++;
}
/**
* На всякий случай сбрасываю очередь, на тот случай, если вдруг чего осталось в очереди. Хотя по идее такого произойти не должно.
*/
xQueueReset(uartRxData);
*answerLen = len;
}

/**
* @brief Обработчик прерываний, из которого данные попадают в очередь uartRxData
*/
void bgs2UartIrqHandler (void)
{
portBASE_TYPE xHigerPriorityTaskWoken;
#if UART_NUM==0
uint32_t interruptStatus = LPC_UART0->IIR & 0x0E;
#elif UART_NUM==1
uint32_t interruptStatus = LPC_UART1->IIR & 0x0E;
#endif
if (interruptStatus == 0x04)
{
#if UART_NUM==0
uint8_t ch = LPC_UART0->RBR;
#elif UART_NUM==1
uint8_t ch = LPC_UART1->RBR;
#endif

xQueueSendToBackFromISR ( uartRxData, &ch, &xHigerPriorityTaskWoken);

}

/** @brief инициализация железа и очереди */
void bgs2InitUartPort (void)
{
#if USE_FREERTOS==1
uartRxData = xQueueCreate (200, 1);
#endif
#if UART_NUM==0
/* Power Up the UART0 controller. */
LPC_SC->PCONP |= (1 << 3);
/* Configure UART0 pins */
LPC_IOCON->P0_2 = (1 << 9)| 1;
LPC_IOCON->P0_3 = (1 << 9)| 1;
/* Init UART0 */
LPC_UART0->LCR = 0x83;
LPC_UART0->DLL = 24;
LPC_UART0->DLM = 0;
LPC_UART0->FDR = 229;
LPC_UART0->LCR = 0x03;
LPC_UART0->IER |= (1<<0);
NVIC_EnableIRQ(UART0_IRQn);
NVIC_SetPriority(UART0_IRQn, 196);

#elif UART_NUM==1
/* Power Up the UART1 controller. */
LPC_SC->PCONP |= (1 << 4);
/* Configure UART1 pins */
LPC_IOCON->P0_15 = (1<<0)|(0<<1)|(0<<2);
LPC_IOCON->P0_16 = (1<<0)|(0<<1)|(0<<2);
/* Init UART1 */
LPC_UART1->LCR = 0x83;
LPC_UART1->DLL = 24;
LPC_UART1->DLM = 0;
LPC_UART1->FDR = 229;
LPC_UART1->LCR = 0x03;
LPC_UART1->IER |= (1<<0);
NVIC_EnableIRQ(UART1_IRQn);
NVIC_SetPriority(UART1_IRQn, 196);

#endif
}


Все работает, я наблюдаю оживленную беседу между модемом и микроконтроллером в том алгоритме, который и нужен. Но иногда, по непонятной для меня причине, задача (именно одна задача, все остальные задачи работают), занимающаяся "беседой" с модемом "застревает" навсегда на строчке while ( pdTRUE == xQueueReceive( uartRxData, &ch, timeToWait) ) (значение timeToWait = 200 - посмотрел в дебаге). Почему она там залипает мне совершенно непонятно, ведь период ожидания не равен portMAX_DELAY. Задача как будто блокируется, но при этом функция vTaskList показывает, что задача не блокирована (статус == READY) и стека у нее более чем достаточно. Конечно я мог ошибиться где то совсем в другом месте. Но если вдруг это что-то общее, буду признателен за помощь. Ну что это может быть, у меня уже просто нет никаких идей, хоть в петлю лезь! Нравоучения и критика на тему "индуский код" приветствуются sm.gif.

p.s.: Забыл упомянуть: приоритет у задачи занимающейся общением с модемом самый высокий, так что такого, что ее вытеснили быть не может.

Сообщение отредактировал yanvasiij - Apr 15 2014, 08:03
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Sekat
сообщение Apr 15 2014, 08:33
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 13-02-12
Пользователь №: 70 242



Цитата(yanvasiij @ Apr 15 2014, 11:57) *
...
p.s.: Забыл упомянуть: приоритет у задачи занимающейся общением с модемом самый высокий, так что такого, что ее вытеснили быть не может.

Посмотрите еще раз внимательно на приоритет обработчика вашего прерывания. По ртосовским правилам он не может быть выше ртосовского, или не используйте вызовы ртосовских функций в этом прерывании - например отдачу семафора.
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Apr 15 2014, 08:50
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Цитата(Sekat @ Apr 15 2014, 14:33) *
Посмотрите еще раз внимательно на приоритет обработчика вашего прерывания. По ртосовским правилам он не может быть выше ртосовского, или не используйте вызовы ртосовских функций в этом прерывании - например отдачу семафора.


Приоритет моего прерывания:
Код
    NVIC_SetPriority(UART0_IRQn, 196);

Ртосовские прерывания ( из файля FreeRtosConfig.h):
Код
#define configKERNEL_INTERRUPT_PRIORITY         255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     191 /* equivalent to 0xb0, or priority 11. */


Если я правильно понимаю там небольшая путаница в нумерациях: у FreeRtos приоритет тем выше, чем выше его цифра, а у CortexM3 наоборот. Получается, если приоритет у ртосовского прерывания стоит 191 (как у меня), то мне нужно сделать приоритет 192 и более, чтобы все работало. Я так и сделал (у меня 196). Верно?
Go to the top of the page
 
+Quote Post
wolfram
сообщение Apr 16 2014, 01:44
Сообщение #4





Группа: Новичок
Сообщений: 3
Регистрация: 15-12-06
Пользователь №: 23 537



Цитата(yanvasiij @ Apr 15 2014, 16:50) *
Приоритет моего прерывания:
Код
    NVIC_SetPriority(UART0_IRQn, 196);

Я так и сделал (у меня 196). Верно?

Не верно. Нужно например так
Код
    NVIC_SetPriority(UART0_IRQn, 12);

посмотрите внимательно на код функции NVIC_SetPriority
Go to the top of the page
 
+Quote Post



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

 


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


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