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

 
 
 
Reply to this topicStart new topic
> Как организовать проект: одна плата - много версий embedded ПО?
Slash
сообщение Dec 19 2016, 22:55
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 202
Регистрация: 10-04-05
Из: Санкт-Петербург
Пользователь №: 4 011



Здравствуйте!

Сделана плата на основе микроконтроллера. Нужно одновременно поддерживать несколько версий встроенного ПО.
Помимо логики работы, версии отличаются инициализацией периферийных модулей.

Если с логикой работы более-менее приемлемо получается директивами условной компиляции, то с разными версиями инициализации периферийных модулей не знаю что делать.
Если модули обобщать, чтобы они были более гибкими, и в разных версиях просто настраивались по-разному, боюсь, модуль сильно разрастется.
И не всегда получается хорошо абстрагировать модуль, чтобы охватывались все варианты.

Пока остановился на такой реализации периферии: класс с минимально-необходимым интерфейсом.
Код
class Uart1
{
public:
    enum Baudrate
    {
      ...
    };


    Uart1();
    void setBaudrate(Baudrate b);
    void write(uint8_t * data, uint32_t size);
...
private:
    DMA_HandleTypeDef mDmaTx;
    UART_HandleTypeDef mUart;
...
};


Реализация по месту, без особых обобщений.
Код
void Uart1::write(uint8_t * data, uint32_t size)
{
    __HAL_DMA_DISABLE(&mDmaTx);
    
    mUart.Instance->CR3 &= ~USART_CR3_DMAT;

    mDmaTx.Instance->CPAR = reinterpret_cast<uint32_t>(&mUart.Instance->TDR);

    mDmaTx.Instance->CMAR = reinterpret_cast<uint32_t>(data);
    
    const uint32_t dataLength = size;
    mDmaTx.Instance->CNDTR = dataLength;
    
    mUart.Instance->CR3 |= USART_CR3_DMAT;
    __HAL_DMA_ENABLE(&mDmaTx);
}


Если нужна другая инициализация модуля - меняю *cpp файл модуля.

Пока думаю, что проект для всех вариантов ПО должен быть один и все версии файлов должны быть в нем.

Так вот, что делать с файлами периферии?

1. Можно раскинуть по папкам
version1/uart1.cpp
version2/uart1.cpp
Но не компилируется - объектные файлы с одинаковыми именами.

2. Можно менять им имена в зависимости от версии
uart1_ver1.cpp
uart1_ver2.cpp
И тогда придется еще вводить для каждой версии свое пространство имен, если хочу сохранить имя класса единое.
Не эстетично rolleyes.gif

3. Как-то организовать на уровне системы контроля версий. Пока не понимаю как, при условии, что все версии нужно вести параллельно.

4. Сделать header only файлы периферии. Не очень красиво, не рекомендуют.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 20 2016, 07:06
Сообщение #2


Гуру
******

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



QUOTE (Slash @ Dec 20 2016, 00:55) *
1. Можно раскинуть по папкам
version1/uart1.cpp
version2/uart1.cpp
Но не компилируется - объектные файлы с одинаковыми именами.
Не включайте в проект не относящиеся к нему директории. Ибо даже если вы дадите файлам разные имена и оно у вас скомпилируется - не пройдет линковка, ведь у вас в этих файлах функции с одинаковыми названиями.
QUOTE (Slash @ Dec 20 2016, 00:55) *
3. Как-то организовать на уровне системы контроля версий. Пока не понимаю как, при условии, что все версии нужно вести параллельно.
Я совсем недавно пришел к такой системе - в одном репозитории хранится общий для многих проектов код - заголовочные файлы CMSIS, исходники scmRTOS, lwIP, реализация AES-декодирования для загрузчика, какие-то специфичные файлы, использующиеся более чем в одном проекте. Проекты хранятся в других репозиториях, каждый проект состоит из директорий common (общие для этого железа файлы), bootloader, application. В application может быть несколько директорий для разных вариантов ПО. Общий репозиторий я подключаю как внешний (svn:externals) в директорию common. А дальше уже в makefile подключаю к проекту только те директории, которые мне нужны в этом проекте. При этом в общем репозитории у меня лежит generic_uart.cpp с реализацией неизменных функций, а на уровне проекта у меня есть файл uart.cpp с реализацией недостающих функций под конкретный проект. И если у меня УАСПП во всех исполнениях ПО инициализируются одинаково, то я делаю один uart.cpp с функцией uart::init(), кладу его в common/uart и подключаю ее к проекту. Если в каком-то одном исполнении или в загрузчике мне нужна другая инициализация - то я кладу другой uart.cpp в директорию bootloader или application/variant1 и убираю из makefile этой прошивки подключение common/uart.
Еще вариант - в общем репозитории хранится класс generic_uart, а в проекте - отнаследованный от него uart, у которого добавлена функция init.
Третий вариант - в общем репозитории класс generic_uart делается шаблоном, параметр шаблона используется как базовый класс. А уже этот базовый класс реализуется в каждом конкретном проекте - таким образом я использую два варианта dma (потоки и каналы) в исходниках для разных stm32.

Да, в процессе перевода на эту систему кучи проектов с большим количеством почти одинакового кода пришлось несколько раз довольно радикально "перетрахивать" структуру директорий этого общего репозитория и править под нее по несколько раз уже переведенные проекты (и этот процесс еще не закончен), но я доволен - теперь при исправлении какой-либо ошибки в общем коде мне не нужно вспоминать, в каком еще проекте использовался этот код и править эту же ошибку там - достаточно просто обновиться в очередном проекте и все правки общего репозитория подтягиваются автоматически.

При фиксации стабильной версии в tags я делаю правку в svn:externals, указывая там текущую на момент фиксации версию внешнего общего репозитория.


--------------------
На любой вопрос даю любой ответ
"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
jcxz
сообщение Dec 20 2016, 11:08
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Сергей Борщ @ Dec 20 2016, 10:06) *
Я совсем недавно пришел к такой системе -
...

Легко Вам - пишете всё под один МК.
Go to the top of the page
 
+Quote Post
HardEgor
сообщение Dec 20 2016, 17:10
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925



Цитата(Slash @ Dec 20 2016, 05:55) *
Сделана плата на основе микроконтроллера. Нужно одновременно поддерживать несколько версий встроенного ПО.
Помимо логики работы, версии отличаются инициализацией периферийных модулей.

Если у вас всё такое разное - то не вижу смысла усложнять, делайте отдельные каталоги для каждого проекта и всё.
А так вы усложняете код множеством условных директив и запутываете поддержку.
Возможно какие-то общие алгоритмы стоит вынести в отдельные файлы и всё.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Dec 24 2016, 15:55
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(jcxz @ Dec 20 2016, 14:08) *
Легко Вам - пишете всё под один МК.

Какая разница?
У меня есть в одном воркспейсе два проекта под разные контроллеры одного семейства, есть в двух воркспейсах два проекта, использующие общие файлы, для разных контроллеров разных семейств.
Что касается директив условной компиляции, то стараюсь не злоупотреблять, если зашкаливает, делаю разные файлы.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 24 2016, 16:40
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(jcxz @ Dec 20 2016, 13:08) *
Легко Вам - пишете всё под один МК.


Какая разница? У меня достаточно похоже, на то, что описал Сергей. Но, например, проект над которым вот прямо сейчас работаю, собирается из достаточно большого количества общих исходников и заголовков на:
1) Cortex-M3
1) ARM7
2) BA2
3) M8C
4) PC/Win
5) PC/Lin

При этом ARM7 - две железки
BA2 - 2 железки и 6 (пока только)вариантов софта
M8C - два варианта софта


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 3rd September 2025 - 23:15
Рейтинг@Mail.ru


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