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

 
 
 
Reply to this topicStart new topic
> Изменить формат вывода __DATE__ , __TIME__, AVRstudio
Sergey_Aleksandr...
сообщение Oct 25 2009, 19:45
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 167
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Всегда в проектах (пишу на асме в AVRstudio) создаю подобную конструкцию
Код
.org (FLASHEND - 64)
    .db "  Encoder&Keyboard  v1.4  25.10.2009"

Т.е. в конец флеша записываю строку с названием проекта, версией прошивки и датой билда, что порой очень выручает.
На днях узнал про "предопределённые макросы" __DATE__ __TIME__, был приятно удивлён. Но не очень устраивает формат вывода даты макросом __DATE__ . Он выдаёт "Oct 25 2009", а хочется именно "25.10.2009". В хэлпе по AVRasm2 приводят:
Код
-FDformat
-FTformat
Specify the format of the __DATE__ and __TIME__ predefined macros, respectively. The format string is passed directly to the strftime(3) C library function. The __DATE__ and __TIME__ preprocessor macros will always be string tokens, i.e., their values will appear in double quotes.

The default formats are "%b %d %Y" and "%H:%M:%S", respectively.

Example: To specify ISO format for __DATE__, specify  -FD"%Y-%m-%d"  See note below

These formats may only be specified at the command line, there are no corresponding #pragma directives.

Important note: The Windows command interpreter (cmd.exe or command.com) may interpret a character sequence starting and ending with a '%' character as an environment variable to be expanded even when it is quoted. This may cause the date/time format strings to be changed by the command interpreter and not work as expected. A workaround that will work in many cases is to use double '%' characters to specify the format directives, e.g., -FD"%%Y-%%m-%%d" for the example above. The exact behaviour of the command interpreter seems to be inconsistent and vary depending on a number of circumstances, for one, it is different in batch and interactive mode. The effect of the format directives should be tested. It is recommended to put the following line in the source file for testing this:

#message "__DATE__ =" __DATE__ "__TIME__ =" __TIME__

This will print the value of the date and time macros when the program is assembled, making verification easy (see #message directive documentation).

An alternative syntax for the format specification may be considered in future AVRASM2 versions to avoid this problem.


Some relevant strftime() format specifiers (see strftime(3) manual page for full details):

%Y - Year, 4 digits

%y - Year, 2 digits

%m - Month number (01-12)

%b - Abbreviated month name

%B - Full month name

%d - Day number in month (01-31)

%a - Abbreviated weekday name

%A - Full weekday name

%H - Hour, 24-hour clock (00-23)

%I - Hour, 12-hour clock (01-12)

%p - "AM" or "PM" for 12-hour clock

%M - Minute (00-59)

%S - Second (00-59)

Куда писать эти спецификаторы - ума не приложу :-[ Имею подозрения, что поле "Additional Parameters" окна "Project->Assembler Options" для этих целей используется.

Также вопрос вдогонку. При присваивании константам текстовых имён хочу делать проверку на допустимость значения
Код
.equ defineParam1 = 1
......
......
#if (defineParam1 < 3)
#error "defineParam1 must be more then 3"
#endif

Но вот как в тексте ошибки вернуть значение этой константы? Чтобы при неверно заданном параметре был виден не только текст констатирующий ошибку, но и первопричину этой ошибки, что-то вроде #error "defineParam1 must be more then 3. Param1=", (????).
Спасибо всем откликнувшимся.
Go to the top of the page
 
+Quote Post
Sergey_Aleksandr...
сообщение Oct 30 2009, 18:14
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 167
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Сам вопрос задал, сам же на него и отвечу (вдруг кому и пригодится). В поле "Additional Parameters" окна настроек ассемблера "Project->Assembler Options" необходимо ввести спецификатор -FD"%%Y.%%m.%%d" для вывода даты вида "YYYY.MM.DD" (например 2009.10.30). Аналогично предопределяется и макрос __TIME__ . 4 года пользуюсь студией, а о подобных настройках узню только сейчас((
PS А вот как к строке возвращаемой директивой #error приаттачивать число, так и не придумал/нашёл. Может у кого есть соображения по этому вопросу?
Go to the top of the page
 
+Quote Post
C.S.
сообщение Nov 29 2009, 08:41
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 6-05-09
Из: Москва
Пользователь №: 48 733



Насчёт #error - нету. Я тут ещё с номером билда баловался - наваял за полчаса программку, которая ТУПО инкрементит одно число в файле типа .db "build xxx", и этот файл инклудю в код.

PDFLASHData.Inc ====
Код
_CSVersionString:
    .DB "CS PowerDimmer v2.6 "
    .INCLUDE "PDVersion.Inc"
    .DB " @AVR ATMega 8. Copyright © 2009 CS.", NUL, FF


PDVersion.Inc ======
Код
;AUTO-GENERATED SCRIPT!! DO NOT EDIT!!!!!!!!!!
.DB "[0900]"


Прога юзается в шаге Project -> Assebler Options -> Avdanced Options -> Pre-assebling:
Код
IncVersion.Exe PDVersion.Inc


Формат даты-времени ставил, как вы уже нашли.
Эскизы прикрепленных изображений
Прикрепленное изображение
 

Прикрепленные файлы
Прикрепленный файл  IncVersion.rar ( 3.21 килобайт ) Кол-во скачиваний: 15
 
Go to the top of the page
 
+Quote Post
ae_
сообщение Dec 5 2009, 21:26
Сообщение #4


Участник
***

Группа: Свой
Сообщений: 455
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



Цитата(Sergey_Aleksandrovi4 @ Oct 26 2009, 03:45) *
При присваивании константам текстовых имён хочу делать проверку на допустимость значения
Код
.equ defineParam1 = 1
......
......
#if (defineParam1 < 3)
#error "defineParam1 must be more then 3"
#endif

Но вот как в тексте ошибки вернуть значение этой константы?


Использовать #define вместо .equ
Код
#define defineParam1 2
#if (defineParam1 < 3)
#error "defineParam1 must be equal or more then 3. defineParam1 = " defineParam1
#endif
Go to the top of the page
 
+Quote Post
adc
сообщение Dec 6 2009, 11:49
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 409
Регистрация: 29-10-07
Пользователь №: 31 836



Цитата
На днях узнал про "предопределённые макросы" __DATE__ __TIME__, был приятно удивлён.

Тоже был приятно удивлен на днях)))
В этой ветке http://electronix.ru/forum/index.php?s=&am...st&p=685111 ув. V_G написал следующую форму:
Код
Version:
.DB __DAY__,__MONTH__,__YEAR__,__HOUR__,__MINUTE__,__SECOND__;версия ПО

Эта схема возвращает нужный Вам формат т.е. 11.12.2009.... (все в шестнадцатеричном виде )Если нужно, можно добавить точки.
Код
.DB __DAY__,'.',__MONTH__'.',__YEAR_


--------------------
Умный программист пишет тупым кодом гениальные вещи, а не наоборот...
Go to the top of the page
 
+Quote Post
Sergey_Aleksandr...
сообщение May 23 2011, 08:28
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 167
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Спустя время пересел на IAR EWAVR 5.1. Здесь форматы макросов __DATE__ и __TIME__ определены жёстко и строки инициализации наподобие -FD"%%Y.%%m.%%d" используемых в AVRStudio не действуют.
С форматом времени разобрался
Код
#define HOURS        (__TIME__[0]), (__TIME__[1])
#define MINUTES    (__TIME__[3]), (__TIME__[4])
#define SECONDS    (__TIME__[6]), (__TIME__[7])

__flash __root unsigned char PROJECT_INFO4[] = {' ', HOURS, ':', MINUTES, ':', SECONDS};


С датой не получается. Наткнувшись на пример http://www.embeddedrelated.com/groups/msp430/show/44591.php попытался реализовать конструкцию вида
Код
#if __DATE__[2] == 'b'        //Feb
#define MONTH        '0','2'
#elif __DATE__[2] == 'y'        //May
#define MONTH        '0','5'
#elif __DATE__[2] == 'l'        //Jul
#define MONTH        '0','7'
#elif __DATE__[2] == 'g'        //Aug
#define MONTH        '0','8'
#elif __DATE__[2] == 'p'        //Sep
#define MONTH        '0','9'
#elif __DATE__[2] == 't'        //Oct
#define MONTH        '1','0'
#elif __DATE__[2] == 'v'        //Nov
#define MONTH        '1','1'
#elif __DATE__[2] == 'c'        //Dec
#define MONTH        '1','2'

компилятор ругается на сравнение #if __DATE__[2] == 'b', т.е. не может взять член массива и сравнить с константой. Выдаёт ошибку "Error[Pe029]: expected an expression".

У кого есть мысли, как обойти эту проблему. Или может есть другой, более элегантный способ отредактировать __DATE__?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение May 26 2011, 04:20
Сообщение #7


неотягощённый злом
******

Группа: Свой
Сообщений: 2 730
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата
компилятор ругается на сравнение #if __DATE__[2] == 'b', т.е. не может взять член массива и сравнить с константой. Выдаёт ошибку "Error[Pe029]: expected an expression".
А если условие взять в скобочки?
Код
#if (__DATE__[2] == 'b')


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ReAl
сообщение May 26 2011, 06:23
Сообщение #8


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

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



Препроцессор не должен уметь залазить внутрь строк.
Нодо пробовать что-то в духе
Код
#define MONTH \
    (__DATE__[2] == 'b' ? "02" : \
     __DATE__[2] == 'y' ? "05" : \
     __DATE__[2] == 'l'  ? "07" :
И так далее.
Потом только MONTH можно будет использовать только для того, чтобы инициалищировать отедльную строку либо подставить в печать.
А вообще -- чего только люди не сделают, чтобы не разбираться с make и всем прочим
Код
// d.c
char date[] = DATE;

Код
foo:
        avr-gcc -DDATE=\"`date +%Y.%m.%d`\" -Os -S d.c

make -f mk.mk
cat d.s
Код
    .file    "d.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__CCP__  = 0x34
__tmp_reg__ = 0
__zero_reg__ = 1
    .global __do_copy_data
    .global __do_clear_bss
.global    date
    .data
    .type    date, @object
    .size    date, 11
date:
    .string    "2011.05.26"

Под win при наличии make.exe sh.exe должно получаться аналогично.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
kbvsoft
сообщение Dec 25 2017, 20:21
Сообщение #9





Группа: Новичок
Сообщений: 1
Регистрация: 25-12-17
Пользователь №: 100 840



Цитата
У кого есть мысли, как обойти эту проблему. Или может есть другой, более элегантный способ отредактировать __DATE__?

Конечно скобочки в конструкции #if (__DATE__[2] == 'b') обязательны, но это не поможет.
Похоже на этапе выбора условий компиляций (директивы препроцессора #if, #ifdef) компилятор IAR ещё не сформировал макросы __DATE__ и __TIME__ и при любом обращении к ним в этих директивах пустые значения __DATE__ и __TIME__ никогда не включат нужную ветку условной компиляции.
Поэтому условие компиляции типа
#if (__DATE__[2] == 'b') //Feb
#define MONTH '0','2'
...

никогда не выполнится (т.к. на самом деле в директиве #if элемент макроса __DATE__[2] ещё равен 0)

Задание же макросов (директивы препроцессора #define) или символических констант (ключевое слово const происходит на следующем этапе компиляции, когда IAR уже сформировал макросы __DATE__ и __TIME__, тогда уже следующие конструкции прекрасно работают:
#define HOURS (__TIME__[0]), (__TIME__[1])
#define YEAR __DATE__[7], __DATE__[8], __DATE__[9], __DATE__[10];
__flash char BUILD_TIME[] = {__TIME__};


Исходя их вышесказанного, преобразовать __DATE__ в нужный формат на этапе компиляции никак не получится, по крайней мере, у меня не получилось. laughing.gif Зато в runtime всё прекрасно работает. yeah.gif

Следующий код возвращает дату компиляции в нужном нам формате 'DD.MM.YYYY' в строке TempStr:
Код
char TempStr[11];

const char m1 = __DATE__[1];
const char m2 = __DATE__[2];
const char d1 = __DATE__[4];
const char d2 = __DATE__[5];
const char y1 = __DATE__[7];
const char y2 = __DATE__[8];
const char y3 = __DATE__[9];
const char y4 = __DATE__[10];

void BuildDateToTempStr (void )
{
  /*
    Формат макроса IAR '__DATE__'
    на примере '30.01.2000':
              'Jan 30 2000'
               01234567890
    Jan - 01
    Feb - 02
    Mar - 03
    Apr - 04
    May - 05
    Jun - 06
    Jul - 07
    Aug - 08
    Sep - 09
    Oct - 10
    Nov - 11
    Dec - 12
  */
  char M1, M2;
  //••••••••••••••••••••••••
  TempStr[0]  = d1;
  TempStr[1]  = d2;
  TempStr[2]  = '.';
  E1 = '0';
  if (m1 == 'a' && m2 == 'n')  M2 = '1';
  if (m1 == 'e' && m1 == 'b')  M2 = '2';
  if (m1 == 'a' && m2 == 'r')  M2 = '3';
  if (m1 == 'p' && m2 == 'r')  M2 = '4';
  if (m1 == 'a' && m2 == 'y')  M2 = '5';
  if (m1 == 'u' && m2 == 'n')  M2 = '6';
  if (m1 == 'u' && m2 == 'l')  M2 = '7';
  if (m1 == 'u' && m2 == 'g')  M2 = '8';
  if (m1 == 'e' && m2 == 'p')  M2 = '9';
  if (m1 == 'c' && m2 == 't') {M1 = '1'; M2 = '0';}
  if (m1 == 'o' && m2 == 'v') {M1 = '1'; M2 = '1';}
  if (m1 == 'e' && m2 == 'c') {M1 = '1'; M2 = '2';}
  TempStr[3]  = M1;
  TempStr[4]  = M2;
  TempStr[5]  = '.';
  TempStr[6]  = y1;
  TempStr[7]  = y2;
  TempStr[8]  = y3;
  TempStr[9]  = y4;
  //••••••••••••••••••••••••
  TempStr[10] = 0;
}

m1 … y4 – обязательно!!! должны объявляться как константы через const.
Тогда условные операторы типа if (m1 == 'a' && m2 == 'n') в скомпилированный код вообще не включаются, т.к. сравнивать константу с константой нет смысла, поэтому в полученном коде элементам строки просто присваиваются реальные значения даты компиляции в нужном формате и всё!
Если же m1 … y4 объявить через #define, на этапе компиляции дата размещается в памяти данных и все обращения к ней как к памяти, в итоге скомпилированный код раз в 10 больше!.
Go to the top of the page
 
+Quote Post
Baser
сообщение Dec 25 2017, 21:57
Сообщение #10


Просто Che
*****

Группа: Свой
Сообщений: 1 341
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Когда-то давно, на просторах этого форума, пробегал чей-то макрос, которым я все это время без проблем пользуюсь:

Код
#ifndef _COMPILE_DATE_TIME_
#define _COMPILE_DATE_TIME_

#define COMPILE_HOUR   (((__TIME__[0]-'0')*10) + (__TIME__[1]-'0'))
#define COMPILE_MINUTE (((__TIME__[3]-'0')*10) + (__TIME__[4]-'0'))
#define COMPILE_SECOND (((__TIME__[6]-'0')*10) + (__TIME__[7]-'0'))

#define COMPILE_YEAR  ((((__DATE__[7]-'0')*10+(__DATE__[8]-'0'))*10+(__DATE__[9]-'0'))*10+(__DATE__[10]-'0'))

#define COMPILE_MONTH   ((__DATE__[2] == 'n' ? (__DATE__ [1] == 'a'? 0 : 5) \
                        : __DATE__[2] == 'b' ? 1 \
                        : __DATE__[2] == 'r' ? (__DATE__ [0] == 'M'? 2 : 3) \
                        : __DATE__[2] == 'y' ? 4 \
                        : __DATE__[2] == 'l' ? 6 \
                        : __DATE__[2] == 'g' ? 7 \
                        : __DATE__[2] == 'p' ? 8 \
                        : __DATE__[2] == 't' ? 9 \
                        : __DATE__[2] == 'v' ? 10 : 11)+1)

#define COMPILE_DAY  ((__DATE__[4]==' ' ? 0 : __DATE__[4]-'0')*10+(__DATE__[5]-'0'))
#endif

Автору большое спасибо a14.gif
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение Dec 26 2017, 14:02
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 16-10-15
Пользователь №: 88 894



Вариант практического использования для регистров часов и даты stm32f4-7.
Устанавливает дату и время на момент сборки прошивки, макрос сокращается до одиночной записи в регистр.

Код
    RTC->TR =   ((__TIME__[0]-'0') << 20)                           // hour 10
               | ((__TIME__[1]-'0') << 16)                         // hour 1
               | ((__TIME__[3]-'0') << 12)                         // minutes 10
               | ((__TIME__[4]-'0') << 8)                          // minutes 1
               | ((__TIME__[6]-'0') << 4)                          // seconds 10
               | (__TIME__[7]-'0');                                // seconds 1

   RTC->DR = ((__DATE__[9]-'0') << 20)                             // year 10
           | ((__DATE__[10]-'0') << 16)                            // year 1
           | ((__TIMESTAMP__[2]=='e'?2:__TIMESTAMP__[2]=='d'?3 \
           :__TIMESTAMP__[2]=='u'?4:__TIMESTAMP__[2]=='i'?5 \
           :__TIMESTAMP__[2]=='t'?6:__TIMESTAMP__[0]=='M'?1:7) << 13)      // Week day
           | ((((__DATE__[2]=='n'?(__DATE__[1]=='a'?0:5):__DATE__[2]=='b'?1 \
           :__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4 \
           :__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8 \
           :__DATE__[2] =='t'?9:__DATE__[2]=='v'?10:11)+1)/10) << 12)      // Month 10
           | ((((__DATE__[2]=='n'?(__DATE__[1]=='a'?0:5):__DATE__[2]=='b'?1 \
           :__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4 \
           :__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8 \
           :__DATE__[2] =='t'?9:__DATE__[2]=='v'?10:11)+1)%10) << 8)       // Month 1
           | ((__DATE__[4]==' ' ? 0 : __DATE__[4]-'0') << 4)               // day 10
           | (__DATE__[5]-'0');                                            // day  1

Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 17th January 2018 - 11:17
Рейтинг@Mail.ru


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