Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с С и С++ ПОМОГИТЕ!
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
paravozru
Возникла проблема. Есть проект и в одном из циклов есть оператор break. При настройке IAR во вкладке Language1 я указываю следующие настройки.
Language: C
Language Confomance: Standart with IAR extension

Не работает оператор break. но вызываются прерывания.

При выборе C++ оператор break успешно работает но не вызываются прерывания.

Код
for (i = 0; i < MaxAmountPacket; i++) {
if (PackTurnSend[i].State == EmptyItem) {
PackTurnSend[i].BodyType = PacketType;
PackTurnSend[i].State = State;
PackTurnSend[i].Channel = Channel;
PackTurnSend[i].NumBytes = NumBytes;
PackTurnSend[i].TimeOut = TimeOut;
memcpy(PackTurnSend[i].Buff, buff, NumBytes);
result = i;
break;
}

Когда силы уже иссякли я взял с таймером TIM6 (вот отсюда http://chipspace.ru/stm32-basic-timer/#comment-346 ) и проверил. и в самом деле не работают прерывания когда выбираю C++.
Сергей Борщ
QUOTE (paravozru @ Aug 14 2013, 11:49) *
Не работает оператор break
А вы уверены, что попадаете в эту ветку алгоритма?
QUOTE (paravozru @ Aug 14 2013, 11:49) *
и в самом деле не работают прерывания когда выбираю C++.
Прерывания работают. Вы не указали модификатор extern "C" при объявлении обработчика, поэтому написанный на C код определения массива векторов просто не видит ваш Ц-плюс-плюсный обработчик и вместо его прилинковывает свою заглушку.
MrYuran
Закрывающей скобки не хватает }
А код здесь принято оформлять в теге [ code ] (самая правая кнопка на панели редактирования)

Для решения вашего вопроса мало данных.
paravozru
Цитата(Сергей Борщ @ Aug 14 2013, 13:56) *
А вы уверены, что попадаете в эту ветку алгоритма?
Прерывания работают. Вы не указали модификатор extern "C" при объявлении обработчика, поэтому написанный на C код определения массива векторов просто не видит ваш Ц-плюс-плюсный обработчик и вместо его прилинковывает свою заглушку.

Да уверен, и диодом моргал в этом месте и отладчиком проверял. По поводу обработчика можно по подробнее. Прерывания вызываю просто как функцию void TIM6_IRQHandler(void) .

Цитата(MrYuran @ Aug 14 2013, 14:00) *
Закрывающей скобки не хватает }
А код здесь принято оформлять в теге [ code ] (самая правая кнопка на панели редактирования)

Для решения вашего вопроса мало данных.

Да скобку упустил из виду , но в коде разумеется она есть, просто компилятор бы ругался )) Мало данных ? ну можете использовать пример приведенный мною выше - ссылка на сайт chipspace.ru
DASM
Их какбы нельзя вызывать прямо =) Сергей Борщ правильно сказал - у вас линковщик врубает заглушку. Опишите фунцию обработчик как extern "C"
paravozru
Код
void SendToCOM0 (void)  {                                                                       // функция вызывающая прерывание void USART1_IRQHandler  при попадании данных в регистр DR
   chList[chCOM1_0].State &= ~ ChannelWaitSend;
   chList[chCOM1_0].State |= ChannelBusySend;
        
    USART1->CR1 &= ~USART_CR1_RXNEIE;        
    USART1->CR1 |= USART_CR1_TE;        
    USART1->DR = chList[chCOM1_0].BuffOut[chList[chCOM1_0].ptrOutData];
    USART1->CR1 |= USART_CR1_TXEIE;
        
}

void USART1_IRQHandler (void)   {                                                 //  ну вот сама функция прерывания она не вызывается когда указываю C++
  
  uint8_t data;

  if (USART1->SR & USART_SR_RXNE) {                                                                                                        
      data = USART1->DR;
      chList[chCOM1_0].BuffIn[chList[chCOM1_0].ptrInData] = data;                                            
      chList[chCOM1_0].LenInData++;                                                                                                    
      chList[chCOM1_0].ptrInData++;
      //LedGreen(0x1FFFF);
        
  } else if (USART1->SR & USART_SR_TXE) {
             chList[chCOM1_0].ptrOutData++;
            
              if (chList[chCOM1_0].ptrOutData >= chList[chCOM1_0].LenOutData) {                
                  USART1->CR1 &= ~USART_CR1_TXEIE;                                                                        
                  USART1->CR1 |= USART_CR1_RXNEIE;    
                  chList[chCOM1_0].State &= ~ PacketWaitSend;        
                  chList[chCOM1_0].State &= ~ChannelBusySend;
              
              } else {
              USART1->DR = chList[chCOM1_0].BuffOut[chList[chCOM1_0].ptrOutData];
              //LedBlue(0x1FFF);
                                
        }
    }
}


Объясните где нужно ставить extern C как это будет выглядит ?!
Lotor
Как-то так...
Код
#ifdef __cplusplus
extern "C" {
#endif
void USART1_IRQHandler (void)   { //  ну вот сама функция прерывания она не вызывается когда указываю C++
...
}
#ifdef __cplusplus
}
#endif


Цитата(paravozru @ Aug 16 2013, 12:35) *
Объясните где нужно ставить extern C как это будет выглядит ?!

А что мешает Вам погуглить ответ на этот популярный вопрос? Вектор поиска уже дали.

PS: Можете просто приписать extern "C" перед void USART1_IRQHandler (void)
paravozru
Цитата(Lotor @ Aug 16 2013, 13:24) *
Как-то так...
Код
#ifdef __cplusplus
extern "C" {
#endif
void USART1_IRQHandler (void)   { //  ну вот сама функция прерывания она не вызывается когда указываю C++
...
}
#ifdef __cplusplus
}
#endif



А что мешает Вам погуглить ответ на этот популярный вопрос? Вектор поиска уже дали.

PS: Можете просто приписать extern "C" перед void USART1_IRQHandler (void)

Ну первым делом я полез в Гугл )) ну вроде делал как описано в примерах, но не получалось. В итоге сделал так:
В заголовочном файле перед объявлением функции добавил extern "С"
Код
extern "C" void USART1_IRQHandler (void);

В .с файле где исполняется функция так :
Код
#ifdef __cplusplus
extern "C" {
#endif
void USART1_IRQHandler (void)   {

  uint8_t data;

  if (USART1->SR & USART_SR_RXNE) {                                                                                                        
      data = USART1->DR;
      chList[chCOM1_0].BuffIn[chList[chCOM1_0].ptrInData] = data;                                            
      chList[chCOM1_0].LenInData++;                                                                                                    
      chList[chCOM1_0].ptrInData++;
      //LedGreen(0x1FFFF);
        
  } else if (USART1->SR & USART_SR_TXE) {
             chList[chCOM1_0].ptrOutData++;
            
              if (chList[chCOM1_0].ptrOutData >= chList[chCOM1_0].LenOutData) {                
                  USART1->CR1 &= ~USART_CR1_TXEIE;                                                                        
                  USART1->CR1 |= USART_CR1_RXNEIE;    
                  chList[chCOM1_0].State &= ~ PacketWaitSend;
                  
                  chList[chCOM1_0].State &= ~ChannelBusySend;
              
              } else {
              USART1->DR = chList[chCOM1_0].BuffOut[chList[chCOM1_0].ptrOutData];
              //LedBlue(0x1FFF);
                                
        }
    }
}

#ifdef __cplusplus
}
#endif
Lotor
Из ответа не понятно - пришли ли Вы к успеху?
paravozru
Цитата(Lotor @ Aug 16 2013, 16:23) *
Из ответа не понятно - пришли ли Вы к успеху?

Ой в самом деле не написал )) пришел, путем описанным выше. Спасибоооооо)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.