Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: avr306
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
alux
Разбираюсь с этим апнотом. IAR v.5.10A выдает предупреждения на сравнения двух volatile глобальных переменных:
Код
// Static Variables
static unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile unsigned char UART_RxHead;
static volatile unsigned char UART_RxTail;
static unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile unsigned char UART_TxHead;
static volatile unsigned char UART_TxTail;
.......................
#pragma vector=USART0_UDRE_vect
__interrupt void USART0_TX_interrupt( void )
{
  unsigned char tmptail;

  // Check if all data is transmitted
  if ( UART_TxHead != UART_TxTail ) <<<< Warning
  {
......
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement

Переменные UART_TxHead , UART_TxTail, UART_RxHead, UART_RxTail проинициализированы 0 в uart_Init() до разрешения прерываний. Как правильно поступить в данном случае:
1) не обращать внимания на предупреждения
2) заблокировать выдачу сообщений
3) убрать volatile при объявлении этих переменных ?
Если убрать volatile в одной из сравниваемой переменной, то варнинги не выдает. Но не будет ли при этом проблем с оптимизацией?
zltigo
Цитата(alux @ Mar 23 2008, 17:51) *
2) заблокировать выдачу сообщений

Переменные байтовые. Сравнение идет в обработчике прерывания. В данном конкретном случае задавить warning для одной этой строчки допустимо.
Цитата
..убрать volatile в одной из сравниваемой переменной,

Можно или нет так делать зависит уже от того, как построена ВСЯ работа с ними.
singlskv
4) добавте локальную переменную
Код
....................
  unsigned char tmp;
....................

  tmp = UART_TxHead;

  if ( tmp != UART_TxTail )
  {
.................

и варнинги давить не придется
alux
Почему в данном примере в uart_Init() переменные инициализируются 0 ?
Код
void uart_Init(unsigned int ubrr)
{
  unsigned char x;
    
...........
  x = 0;                 // Flush receive buffer
  UART_RxTail = x;
  UART_RxHead = x;
  UART_TxTail = x;
  UART_TxHead = x;  
}
И почему это делается через переменную х, а не просто через присвоение 0 ? Ведь они же объявлены как статические, поэтому по умолчанию должны быть проинициализированы 0. Или для static volatile это правило не распространяется?
IgorKossak
Цитата(alux @ Mar 24 2008, 06:37) *
Почему в данном примере в uart_Init() переменные инициализируются 0 ?
И почему это делается через переменную х, а не просто через присвоение 0 ? Ведь они же объявлены как статические, поэтому по умолчанию должны быть проинициализированы 0. Или для static volatile это правило не распространяется?

По умолчанию обнуляются переменные, определённые на уровне функций и без инициализирующих значений.
static и volatile на это никакого влияния не оказывают.
Очевидно в uart_Init() это делается с целью их инициализации в любое время, а не только в C_startup.
Почему через переменную? Видимо это какая-то ручная оптимизация. Попробуйте так и эдак и сравните листинг.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.