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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> ARM, C++, IAR. Проблема., STM32F4
Geniok
сообщение Nov 11 2012, 22:02
Сообщение #1





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



Всем добрый день!
Возникла проблема следующего рода. При компиляции проекта на С++, программа стопорится при попытке вызова системного прерывания.
Используется IAR версии 6.40.2, стандартные библиотеки CMSIS.

Конкрентно виснет на функции delay(), которая реализована следующим образом:

Код
// Функция задержки (паузы) в работе
void Delay(__IO uint32_t nTime)
{
    TimingDelay = nTime;

    // Крутимся в бесконечном цикле, пока счетчик
    // оставшегося времени не станет равным нулю.
    // Уменьшение счетчика происходит с помощью
    // прерываний системного таймера.
    while(TimingDelay != 0);
}

// Функция уменьшения счетчика задержки (паузы)
void TimingDelay_Decrement(void)
{
    if (TimingDelay != 0x00)
    {
        TimingDelay--;
    }
}

В файле stm32f4xx_it.c определяем функцию

Код
void SysTick_Handler()
{
    TimingDelay_Decrement();
}


Виснет в файле startup_stm32f4xx.s в блоке

Код
PUBWEAK SysTick_Handler
        SECTION .text:CODE:REORDER(1)
SysTick_Handler
        B SysTick_Handler    ///  !!!!!!!!   Вот тут останавливается исполнение.


То есть как я понимаю, не может найти реализацию функции SysTick_Handler().

Когда проект был на С, данный код работал. Может кто знает, как его заставить работать на С++ ?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 11 2012, 22:27
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(Geniok @ Nov 12 2012, 00:02) *
То есть как я понимаю, не может найти реализацию функции SysTick_Handler().

Когда проект был на С, данный код работал. Может кто знает, как его заставить работать на С++ ?

Что-то мне кажется что это где-то было...

Можно попробовать например
1)
Код
extern  "C" void SysTick_Handler()
{
//код обработчика
}


2) Вариант посложней
Отредактировать хидеры от ST
Код
#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

/*******************************************************************************
**************************   GLOBAL VARIABLES   *******************************
******************************************************************************/

extern uint32_t SystemCoreClock;    /**< System Clock Frequency (Core Clock) */

/*******************************************************************************
*****************************   PROTOTYPES   **********************************
******************************************************************************/

/* Interrupt routines - prototypes */
void Reset_Handler(void);
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
// и так далее
#ifdef __cplusplus
}
#endif

Ну и так далее - думаю там много чего можно добавить или выкинуть.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2012, 22:30
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Geniok @ Nov 12 2012, 00:02) *
В файле stm32f4xx_it.c определяем функцию

Код
void SysTick_Handler()
{
    TimingDelay_Decrement();
}
Странно. Обработчик-то определен в файле с расширением С, он должен вызываться, только до этого не должно дойти, должна быть ошибка линковки, если TimingDelay_Decrement(); определена в C++ файле.
Или у него в режиме компиляции С++ все файлы компилируются в С++ режиме?
Попробуйте
Код
#ifdef __cplusplus
extern "C"
#endif
void SysTick_Handler()
{
    TimingDelay_Decrement();
}


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Geniok
сообщение Nov 11 2012, 22:43
Сообщение #4





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



Цитата(_Артём_ @ Nov 12 2012, 02:27) *
Что-то мне кажется что это где-то было...

Можно попробовать например
1)
Код
extern  "C" void SysTick_Handler()
{
//код обработчика
}


Первый вариант помог, спасибо!

На всякий случай, если кому пригодится

в файле stm32f4xx_it.h объявляем

Код
extern  "C"
{
void SysTick_Handler(void);
}


а потом уже в файле stm32f4xx_it.с пишем

Код
extern  "C"
{
void SysTick_Handler()
{
    TimingDelay_Decrement();
}
}


Пробовал такой вариант, в начале файла stm32f4xx_it.с ставить

Код
#ifdef __cplusplus
extern "C" {
#endif


.......


в конце файла

#ifdef __cplusplus
}
#endif


начинают всплывать куча ошибок при компиляции.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 11 2012, 22:44
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(ReAl @ Nov 12 2012, 00:30) *
Странно. Обработчик-то определен в файле с расширением С, он должен вызываться, только до этого не должно дойти, должна быть ошибка линковки, если TimingDelay_Decrement(); определена в C++ файле.
Или у него в режиме компиляции С++ все файлы компилируются в С++ режиме?

У IAR AVR всегда так было - не особо важно какое расширение файла, если проект С++. С АРМ вроде также.
Go to the top of the page
 
+Quote Post
Geniok
сообщение Nov 11 2012, 23:30
Сообщение #6





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



Цитата(ReAl @ Nov 12 2012, 02:30) *
Странно. Обработчик-то определен в файле с расширением С, он должен вызываться, только до этого не должно дойти, должна быть ошибка линковки, если TimingDelay_Decrement(); определена в C++ файле.
Или у него в режиме компиляции С++ все файлы компилируются в С++ режиме?


Скорее всего для С++ компилятора расширения с и срр едины. Ну и соответственно компиляция должна быть в режиме С++.

Цитата(Geniok @ Nov 12 2012, 02:48) *
Вопрос еще возник такой, может кто знает, возможна ли своя замена файла stm32f4xx_it.с ?
То есть возможно ли все обработчики прописать в файле "MyFile.cpp" и чтобы при вызове прерывания перенаправление было туда, а не к stm32f4xx_it.с ?


Ответ уже нашел!

Спасибо всем, кто отозвался!

С Уважением!

Сообщение отредактировал Geniok - Nov 11 2012, 23:30
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Nov 12 2012, 07:12
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(ReAl @ Nov 12 2012, 02:30) *
Странно. Обработчик-то определен в файле с расширением С, он должен вызываться, только до этого не должно дойти, должна быть ошибка линковки, если TimingDelay_Decrement(); определена в C++ файле.
Или у него в режиме компиляции С++ все файлы компилируются в С++ режиме?


Там скорее всего сделано через weak-связывание. Так что он просто не находит обработчик при линковке и использует умолчательный.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 12 2012, 07:50
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Geniok @ Nov 12 2012, 01:30) *
Скорее всего для С++ компилятора расширения с и срр едины. Ну и соответственно компиляция должна быть в режиме С++.
Насколько помню, там в настройках было три варианта:
1)Программист лох, не смог правильно обозвать файлы, на самом деле они все С
2)Программист лох, не смог правильно обозвать файлы, на самом деле они все С++
3)Компилить C/C++в зависимости от расширения файла.

И если вы выбрали один из первых двух - кто злобный Буратина?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
MK2
сообщение Nov 22 2012, 18:25
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 202
Регистрация: 30-10-10
Пользователь №: 60 535



Что бы не плодить лишних тем, рушил написать сюда.
Итак компилятор IAR 6.40 чип stm32f100
часть проекта уже написана на С, и сейчас решил остальное дописать на С++
поэтому поставил в настройках галку Auto на вкладке С/С++ compiler
Прикрепленное изображение

и написал простенький класс:
Код
// class.h
#include "stm32f10x.h"

#define MAX_BUF_UART    10

class UART1 {
          protected :
      uint8_t buf [MAX_BUF_UART];
      static uint8_t current, send_point;
          public :
      UART1(void)
      { current = 0;
              send_point = 0; }
      
       uint8_t cop_buf(uint8_t byte);
       void start_send(void);
            };

Код
class.cpp
#include "stm32f10x.h"
#include "class_UART.h"

#define current this->current
#define send_point this->send_point

uint8_t UART1::cop_buf(uint8_t byte)
{      
.....
    buf[current] = byte;
    current++;
    current %= MAX_BUF_UART;
    return 0;
}

void UART1::start_send(void)
{
      for(; send_point != current; send_point++)
      {
                 USART1->DR = buf[send_point];
     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    
     send_point %= MAX_BUF_UART;
      };
}

void testcpp(void)
{
     UART1 port;
      port.cop_buf('t');
      ......
      port.start_send();
}


далее testcpp() вызываю в в ф-ции main

и ругается линковщик

Код
Error[Li005]: no definition for "testcpp" [referenced from Z:\bla-...-bla-bla\Obj\main.o]


хотя её объявление перед main присутствует;
и еще почему то не удается сделать UART1 port глобальным объектом (вынести перед void testcpp(void))
в этом случае добавляются такие error :
Код
Error[Li005]: no definition for "UART1::current" [referenced from Z:\bla-...-bla-bla\Obj\class_UART.o]
Error[Li005]: no definition for "UART1::send_point" [referenced from Z:\bla-...-bla-bla\Obj\class_UART.o]


что здесь не так? плюсы знаю не очень, как это подружить с IAR?
есть какие-нибудь примеры под него? гугл ничего не дал
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 22 2012, 20:23
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Интересно, в чём смысл этих макросов:
Цитата(MK2 @ Nov 22 2012, 20:25) *
#define current this->current
#define send_point this->send_point

?

Цитата(MK2 @ Nov 22 2012, 20:25) *
и еще почему то не удается сделать UART1 port глобальным объектом (вынести перед void testcpp(void))
в этом случае добавляются такие error :
Код
Error[Li005]: no definition for "UART1::current" [referenced from Z:\bla-...-bla-bla\Obj\class_UART.o]
Error[Li005]: no definition for "UART1::send_point" [referenced from Z:\bla-...-bla-bla\Obj\class_UART.o]


что здесь не так? плюсы знаю не очень, как это подружить с IAR?
есть какие-нибудь примеры под него? гугл ничего не дал


Видимо надо объчвить переменные send_point и пт.
Код
uint8_t UART1::send_point;
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 22 2012, 20:26
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (MK2 @ Nov 22 2012, 20:25) *
далее testcpp() вызываю в в ф-ции main

и ругается линковщик

CODE
Error[Li005]: no definition for "testcpp" [referenced from Z:\bla-...-bla-bla\Obj\main.o]


хотя её объявление перед main присутствует;
А main() находится в .c или .cpp? Если в .c, то в определении функции в файле class.cpp вы должны указать ей спецификатор extern "C":
CODE
extern "C" void testcpp(void)
{
    .....
}

QUOTE (MK2 @ Nov 22 2012, 20:25) *
и еще почему то не удается сделать UART1 port глобальным объектом
Так вы же эти две переменные указали статическими. Зачем - непонятно (буфер у вас нестатический), но раз уж вы их так объявили, то должны и определить их в глобальной области видимости:
CODE
uint8_t UART1::current = 0, UART1::send_point = 0;
UART1 port;

extern "C" void testcpp(void)
{
    .....
}

А то, что ошибки не было когда вы объявляли объект локально объясняется очень просто: ваша функция testcpp() не прилинковывалась и упомянутый в ней объект линкер не использовал.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
MK2
сообщение Nov 22 2012, 21:14
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 202
Регистрация: 30-10-10
Пользователь №: 60 535



Цитата(_Артём_ @ Nov 22 2012, 23:23) *
Интересно, в чём смысл этих макросов:

я поначалу думал что ошибки с переменными идут от того что надо к ним обращаться через указатель this, поэтому что бы не исправлять написал такой макрос

Цитата(Сергей Борщ @ Nov 22 2012, 23:26) *
А main() находится в .c или .cpp? Если в .c, то в определении функции в файле class.cpp вы должны указать ей спецификатор extern "C":

Да, main в .с файле.
extern тоже применял, но только наверно к main ф-ции, сегодня попробую так.

Цитата(Сергей Борщ @ Nov 22 2012, 23:26) *
Так вы же эти две переменные указали статическими. Зачем - непонятно (буфер у вас нестатический),

это мой косяк - буфер должен быть статическим.

Цитата(Сергей Борщ @ Nov 22 2012, 23:26) *
но раз уж вы их так объявили, то должны и определить их в глобальной области видимости:
[code]uint8_t UART1::current = 0, UART1::send_point = 0;
UART1 port;

я их специально в protected объявил, что бы они не были доступны из вне, а теперь они получаются будут глобальными переменными? Или все-таки в пределах модуля, но тогда поидеи перед ними static требуется
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 22 2012, 21:33
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(MK2 @ Nov 22 2012, 23:14) *
Да, main в .с файле.
extern тоже применял, но только наверно к main ф-ции, сегодня попробую так.

Мне так кажется, что ИАРу фиолетово - с или cpp. По крайней мере иногда...

Цитата(MK2 @ Nov 22 2012, 23:14) *
я их специально в protected объявил, что бы они не были доступны из вне, а теперь они получаются будут глобальными переменными?

Глобальными они будут, но доступны будут тольке тем, кому положено.

Цитата(MK2 @ Nov 22 2012, 23:14) *
но тогда поидеи перед ними static требуется

У вас же не Си, и смысл static другой - статическая переменная будет одна на все экземпляры одного типа.
Go to the top of the page
 
+Quote Post
MK2
сообщение Nov 23 2012, 11:58
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 202
Регистрация: 30-10-10
Пользователь №: 60 535



Программа завелась... правда подвели макросы...
Спасибо большое за разъяснения.
посмотрим дальше как он на статические методы будет реагировать, особенно если это будут обработчиками прерываний wink.gif
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 23 2012, 21:04
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(MK2 @ Nov 23 2012, 13:58) *
посмотрим дальше как он на статические методы будет реагировать, особенно если это будут обработчиками прерываний wink.gif

Реагировать будет: выдаст кучу ошибок - оно ж вроде не можно так делать. Для АВР можно было, а тут почему-то нельзя.

P.S. Если получится выложте пример - интересно посмотреть.
Go to the top of the page
 
+Quote Post

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

 


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


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