Автоматизация инкремента версий в keil
Опишу небольшой заголовочный файлик, который помогает мне не заботиться о том, что бы у каждой вновь скомпилированный прошивки была новая версия.
Люблю Visual Studio за механизм, позволяющий инкрементировать версию собранного проекта, и также сильно ненавижу Keil за отсутствие таковой возможности .
Для чего это нужно? Представим ситуацию, когда очень много устройств, а ПО всё время дорабатывается, или же прошивкой новой версии занимается другой человек, ... много может быть причин, но не всегда можно отследить в каком устройстве какая версия зашита. Да и не всегда при сборки проекта вспоминаешь что нужно увеличить номер версии.
Стало интересно?
Все мы привыкли к нумерации версий вида 1.2.3456. Я тоде привык к такому виду, но так как программисты существа ленивые и я тому подтверждение решил отказаться от такой нумерации ввиду её сложности при реализации.
Пришлось бы писать небольшую утилитку которая бы при запуске сборки автоматически инкрементировала число в каком-нибудь .hфайле. И я всерьёз об этом задумывался.
Но всё изменилось после того, как я увидел как обозначают версию прошивки производители ЭБУ двигателя на авто. Код версии состоял из непонятной последовательности букв и цифр.
Почему бы и мне не сделать также.
Код до безобразия прост, все его содержимое это просто переработка макросов __DATE__
и __TIME__
, поэтому думаю не имеет смысла его объяснять.
/**
*********************************************************************************************************
*
* This file is part of Devprodest Lib.
*
* Devprodest Lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Devprodest Lib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Devprodest Lib. If not, see <http://www.gnu.org/licenses/>.
*
* @file version.c
* @brief Реализация автоматически изменяемого номера версии в зависимости от времени компиляции
* @version 1.0
* @authors Zaikin Denis (ZD)
*
* @copyright GNU General Public License
*********************************************************************************************************
*/
#pragma once
/**----- Макросы -----------------------------------------------------------------------------------------*/
// __DATE__ "Jan 27 2012"
// 01234567890
// __TIME__ "21:06:19"
// 01234567
#define VERSION_Y0 (__DATE__[ 7] - '0')
#define VERSION_Y1 (__DATE__[ 8] - '0')
#define VERSION_Y2 (__DATE__[ 9] - '0')
#define VERSION_Y3 (__DATE__[10] - '0')
#define VERSION_M_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')
#define VERSION_M_FEB (__DATE__[0] == 'F')
#define VERSION_M_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r')
#define VERSION_M_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p')
#define VERSION_M_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y')
#define VERSION_M_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n')
#define VERSION_M_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l')
#define VERSION_M_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u')
#define VERSION_M_SEP (__DATE__[0] == 'S')
#define VERSION_M_OCT (__DATE__[0] == 'O')
#define VERSION_M_NOV (__DATE__[0] == 'N')
#define VERSION_M_DEC (__DATE__[0] == 'D')
#define VERSION_M0 ((VERSION_M_OCT || VERSION_M_NOV || VERSION_M_DEC) ? 1 : 0)
#define VERSION_M1 \
( \
(VERSION_M_JAN) ? 1 : \
(VERSION_M_FEB) ? 2 : \
(VERSION_M_MAR) ? 3 : \
(VERSION_M_APR) ? 4 : \
(VERSION_M_MAY) ? 5 : \
(VERSION_M_JUN) ? 6 : \
(VERSION_M_JUL) ? 7 : \
(VERSION_M_AUG) ? 8 : \
(VERSION_M_SEP) ? 9 : \
(VERSION_M_OCT) ? 0 : \
(VERSION_M_NOV) ? 1 : \
(VERSION_M_DEC) ? 2 : \
0 \
)
#define VERSION_D0 ((__DATE__[4] >= '0') ? (__DATE__[4] - '0') : 0)
#define VERSION_D1 (__DATE__[ 5] - '0')
#define VERSION_HOUR0 (__TIME__[0] - '0')
#define VERSION_HOUR1 (__TIME__[1] - '0')
#define VERSION_MIN0 (__TIME__[3] - '0')
#define VERSION_MIN1 (__TIME__[4] - '0')
#define VERSION_SEC0 (__TIME__[6] - '0')
#define VERSION_SEC1 (__TIME__[7] - '0')
#define VERSION_DAY (10U * VERSION_D0 + VERSION_D1)
#define VERSION_MONTH (10U * VERSION_M0 + VERSION_M1)
#define VERSION_YEAR (10U * VERSION_Y2 + VERSION_Y3)
#define VERSION_HOUR (10U * VERSION_HOUR0 + VERSION_HOUR1)
#define VERSION_MIN (10U * VERSION_MIN0 + VERSION_MIN1)
#define VERSION_SEC (10U * VERSION_SEC0 + VERSION_SEC1)
#define VERSION_BCD_DAY (16U * VERSION_D0 + VERSION_D1)
#define VERSION_BCD_MONTH (16U * VERSION_M0 + VERSION_M1)
#define VERSION_BCD_YEAR (16U * VERSION_Y2 + VERSION_Y3)
#define VERSION_BCD_HOUR (16U * VERSION_HOUR0 + VERSION_HOUR1)
#define VERSION_BCD_MIN (16U * VERSION_MIN0 + VERSION_MIN1)
#define VERSION_BCD_SEC (16U * VERSION_SEC0 + VERSION_SEC1)
/**
Формат данных 0xDDMYYmmm:
DD - День = 0x00..0x1F
M - месяц = 0x0..0xC
YY - Год = 0x00..0x63
mmm - минуты = часы * минуты = 000...5A0
*/
#define VERSION_INT ( VERSION_DAY << 24U | VERSION_MONTH << 20U | VERSION_YEAR << 12U | (VERSION_HOUR * VERSION_MIN) )
/**----- Проверка макросов -------------------------------------------------------------------------------*/
/**----- КОНЕЦ ФАЙЛА -------------------------------------------------------------------------------------*/
Частично реализация была взята с StackOwerflow. К сожалению уже не помню откуда, но можно поискать на предмет автоинкремента версий.
Основная фишка это компоновка полученых значений в полноценный код версии - макрос VERSION_INT
, из которого получается весьма интересные значения:
- 27.08.18 11:56 -
0x1B812268
; - 15.12.18 23:32 -
0x0FC122E0
; - и тд.
Она имеет несколько преимуществ:
- всё число имеет размер 4 байта, что для меня было весьма критично;
- версия при каждой компиляции получается всегда разной за счет произведения значений часов и минут, не думаю что кто-то компилирует проект чаще.
И как всегда - хорошего кодинга.