Перевожу проект с Си на Ардуино

michael_il
Offline
Зарегистрирован: 25.08.2015

Привет всем!

Сейчас занимаюсь тем, что перевожу один из своих проектов, написанный в Visual Studio с GCC компилятором, для Меги328, на платформу Ардуино 32 бита. Плата Arduino Due. 
Пара десятков С и h- файлов. Столкнулся с гемороем видимости глобальных переменных и функций в разных файлах. 
Для начала сохранил файл проекта ino в удобном для себя месте. Туда же кинул один С-файл и его заголовочный h-файл, отвечающие за индикацию на семисегментниках  -  display.c display.h  
Добавил их в проект. 
В этих файлах прописал  #include <Arduino.h> 
В главном файле проекта прописал  #include "display.h"
Вроде все нормально. Компилится. 
 
Но когда я в главном файле объявил глобальную переменную bBlinkON, а в  display.c  объявил ее как extern, получил ошибку компилятора, что переменная не видна.
 
display.c: In function 'DisplayRefresh':
display.c:120: error: 'bBlinkON' undeclared (first use in this function)
 
Подскажите пожалуйста для начала, как правильно пользоваться глобальными переменными?
Заранее благодарю
 
michael_il
Offline
Зарегистрирован: 25.08.2015

Сам себе отвечу.

Нашел выход в том, что каждую пару файлов *.c  и *.h оформляю в виде отдельной библиотеки и подключаю к проекту. Приходится сишный код переводить в С++. Надеюсь, что кто-нибудь все же подскажет более простое решение. 

Если у кого-то есть примеры многофайловых проектов, буду очень рад 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012
michael_il
Offline
Зарегистрирован: 25.08.2015

kisoft пишет:

 В .h файлах нужно использовать слово extern при описании функций и переменных

Попробую. Спасибо

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Меня несколько смутила фраза "Приходится сишный код переводить в С++". Должно практически один в один компилироваться. Мы раньше на одном из С проектов так практиковали, компилировали С++ компилятором и смотрели предупреждения, находили таким образом не совсем "корректный" код, впрочем, скорее подчищали.

 

michael_il
Offline
Зарегистрирован: 25.08.2015

Я сейчас из каждой пары *.c  и *.h делаю библиотеки. Так работает. И доступ ко всем public-переменным нормальный. 

Ранее весть проект был написан на чистом С, под другой проц, и не был связан с оболочкой Ардуино

Logik
Offline
Зарегистрирован: 05.08.2014

michael_il пишет:

 Приходится сишный код переводить в С++.

Совсем не обязательно. Либки на С - как набор функций а не класс подхватывает на ура.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Зачем делать кучу ненужных библиотек? Вопрос риторический и ответ мне не нужен.
И ещё С для любого контроллера останется С. Я про чистый С о котором Вы упоминаете.
Ок,вопрос решён , удачи

michael_il
Offline
Зарегистрирован: 25.08.2015

kisoft пишет:
Зачем делать кучу ненужных библиотек?

Согласен стопроцентно! Просто на тот момент другого решения у меня не было. 

michael_il
Offline
Зарегистрирован: 25.08.2015
Что-то не получается с extern
Открыл новый скетч. Добавил два файла MyFile.c и MyFile.h Туда - единственную функцию void Init( void ); добавил extern, как Вы советуете
 
//this is test_prj.ino
#include "MyFile.h"

void setup() {
  Init();
}

void loop() {
  
}
// this is MyFile.c
#include <Arduino.h>
#include "MyFile.h"

void Init( void )
{
    pinMode( 13, OUTPUT );
}

// this is MyFile.h
#include <Arduino.h>

extern void Init( void );
 
Получаю ворнинг:
test_prj.cpp.o: In function `setup':
C:\Program Files\Arduino/test_prj.ino:7: warning: undefined reference to `Init()'
 
 
Я что-то упустил?

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

У Вас опять туз в кармане? В прошлый раз это был Due, а теперь какой сюрприз?

1. Создал новый скетч, вставил в него Ваш текст. Сохранил проект с именем test_prj
2. Закрыл ArduinoIDE
3. Создал в папке проекта test_prj два файла MyFile.cpp & MyFile.h и скопировал в них Ваш текст.
4. Открыл ArduinoIDE и проект test_prj.
5. Скомпилировал без ошибок.

Для того, чтобы к этому не возвращаться, это компилируется как для Due, так и для Uno.

 

michael_il
Offline
Зарегистрирован: 25.08.2015

Проверил карманы, тузов нет. Может какие-то демоны испытыват меня?
шутка

Сюрпризов нет, тот же Due
Закрыл ArduinoIDE, открыл заново. Откомпилил - ворнинг остался
Перевел на Uno - то же самое

Не пойму. Должно быть все просто

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

michael_il пишет:
Проверил карманы, тузов нет. Может какие-то демоны испытыват меня? шутка Сюрпризов нет, тот же Due Закрыл ArduinoIDE, открыл заново. Откомпилил - ворнинг остался Перевел на Uno - то же самое Не пойму. Должно быть все просто

наверное , тузы не в карманах ? а в рукавах !
....у соседа такая же проблема - результатов исправления = 0
:(

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Я создавал файл с расширением cpp, не удивлюсь, если в этом проблема.

michael_il
Offline
Зарегистрирован: 25.08.2015

Так вот где собака порылась!

У меня был с-файл. Поменял на cpp и все заработало!

kisoft, спасибо огромное!

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

У C++ и у С разные имена функций, точнее по разному формируются, потому, если модуль С, то нужно его объявлять как extern "C" void Init(void);
Компиляторы часто определяют по расширению, использование С или С++ компиляции.