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

 
 
> Использование portENTER_CRITICAL(), Программирование для FreeRTOS
Cryon
сообщение Nov 18 2008, 19:02
Сообщение #1





Группа: Новичок
Сообщений: 9
Регистрация: 28-02-06
Пользователь №: 14 797



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

Есть пример функции, которая посылает байт (см. ниже), используя очередь под FreeRTOS. Если ее упростить до уровня моего вопроса, то останется вот это:

portENTER_CRITICAL ();
xQueueSend (xTX0Queue, &cOutChar, xBlockTime);
portEXIT_CRITICAL ();

Внимание вопрос: portENTER_CRITICAL () запрещает прерывания в текущем режиме, причем как IRQ, так и FIQ. Тогда как же так получается, что отрабатывает xBlockTime (т.е. прерывания от таймера должны быть) в xQueueSend() ? wacko.gif

Спасибо!

Сами функции:

Код
signed portBASE_TYPE uart0PutChar (signed portCHAR cOutChar, portTickType xBlockTime)
{
  signed portBASE_TYPE xReturn = 0;

  portENTER_CRITICAL ();
  {
    //
    //  Is there space to write directly to the UART?
    //
    if (*plTHREEmpty0 == (portLONG) pdTRUE)
    {
      *plTHREEmpty0 = pdFALSE;
      UART0_THR = cOutChar;
      xReturn = pdPASS;
    }
    else
    {
      //
      //  We cannot write directly to the UART, so queue the character.  Block for a maximum of
      //  xBlockTime if there is no space in the queue.
      //
      xReturn = xQueueSend (xTX0Queue, &cOutChar, xBlockTime);

      //
      //  Depending on queue sizing and task prioritisation:  While we were blocked waiting to post
      //  interrupts were not disabled.  It is possible that the serial ISR has emptied the Tx queue,
      //  in which case we need to start the Tx off again.
      //
      if ((*plTHREEmpty0 == (portLONG) pdTRUE) && (xReturn == pdPASS))
      {
        xQueueReceive (xTX0Queue, &cOutChar, serNO_BLOCK);
        *plTHREEmpty0 = pdFALSE;
        UART0_THR = cOutChar;
      }
    }
  }

  portEXIT_CRITICAL ();

  return xReturn;
}


portENTER_CRITICAL() продифайнен так:
#define portENTER_CRITICAL() vPortEnterCritical();

Код
void vPortEnterCritical( void )
{
    /* Disable interrupts as per portDISABLE_INTERRUPTS();                             */
    asm volatile (
        "STMDB    SP!, {R0}            \n\t"    /* Push R0.                                */
        "MRS    R0, CPSR            \n\t"    /* Get CPSR.                            */
        "ORR    R0, R0, #0xC0        \n\t"    /* Disable IRQ, FIQ.                    */
        "MSR    CPSR, R0            \n\t"    /* Write back modified value.            */
        "LDMIA    SP!, {R0}" );                /* Pop R0.                                */

    /* Now interrupts are disabled ulCriticalNesting can be accessed
    directly.  Increment ulCriticalNesting to keep a count of how many times
    portENTER_CRITICAL() has been called. */
    ulCriticalNesting++;
}
Go to the top of the page
 
+Quote Post



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

 


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


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