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

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> вопросы по IAR, В поисках идеального компилятора
andrvisht
сообщение Oct 27 2005, 08:58
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Перехожу на С, в связи с этим пересмотрел ICC CV и наконец добрался до IAR
Для начала пересмотрел все что уже было сказано, много пока туманно надо будет осмысливать.
Первый вопрос, хотя я вроде как с ответом утвердился, это возможно ли в IAR представить число в виде 0bxxxxxxxx. Лазая по настройкам пришел к выводу что нет такой возможности, да и в ANSI C это не предусмотрено. Или я чего-то не знаю ?
Второй:
вот в этой ветке
http://forum.electronix.ru/index.php?showtopic=8829
встретил описание макроса как
Код
#define _DDR_(a) DDR##a
#define _DDR(a) _DDR##_(a)
#define SETDDR(x) (_DDR(x##p)|=BIT(x##b))
//PORT A **********************************
#define OUT0p A
#define OUT0b 4


SETDDR(OUT0); макрос который ставит 4 бит в DDRA
В инклудах описаны только представления PORTA, DDRA, PINA, остальные как-то формируются ?? но как так и не понял. sad.gif
В help на IAR по поводу ## нашел вот это:

Rule 98 (required)
There shall be at most one occurrence of the # or ## preprocessor operator in a single macro definition.
How the rule is checked
The compiler will generate an error, indicating a violation of this rule, if more than one of # or ## is used in combination. For example, the occurrence of # and ## in the same macro definition will trigger an error.

Example of rule violations
#define FOO(x) BAR(#x) ## _var

Examples of correct code
#define FOO(x) #x
#define FOO(x) my_ ## x

И опять ничего не понял sad.gif
что за ## что он делает ? В книгах по С ничего такого не нашел...
Кстати этот макрос работает на IAR и ICC, CV ругается.

Может кто обьяснить что это за ## и как они работают ....
Go to the top of the page
 
+Quote Post
G}{OST
сообщение Oct 27 2005, 09:30
Сообщение #2


Участник
*

Группа: Новичок
Сообщений: 48
Регистрация: 6-05-05
Пользователь №: 4 784



## в макросе с параметром обозначает, что далее следует параметр макроса в символьном виде без разрывов, например:
Код
#define Stop(CHN) bCh##CHN##Up = 0; bCh##CHN = 0;
Stop(13); // для препроцессора это "bCh13Up = 0; bCh13 = 0;"


--------------------
cul8r!
* #ru_embedded - эмбеддерский чат
Go to the top of the page
 
+Quote Post
halfdoom
сообщение Oct 27 2005, 09:34
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 003
Регистрация: 20-01-05
Пользователь №: 2 072



Цитата(&-rey @ Oct 27 2005, 11:58)
Examples of correct code
#define FOO(x) #x
#define FOO(x) my_ ## x

Может кто обьяснить что это за ## и как они работают ....

## позволяет образовывать новые идентификаторы путем "склеивания" двух
других идентификаторов. Например, объявление FOO(beep) препроцессор
преобразует в my_beep. Подробности можно почитать здесь.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 27 2005, 09:48
Сообщение #4


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

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



Цитата(&-rey @ Oct 27 2005, 11:58)
Может кто обьяснить что это за ## и как они работают ....
*


## - это склейка аргументов после подстановки в одну лексему.
В ранних версиях С не было, использовался комментарий. Препроцессор его выкидывал перед основной работой и само собой цепочки символов склеивались.

Код
// old C style:
// #define GLUE2(a,b) a/**/b
// ANSI
#define GLUE2(a,b) a ## b

   i = GLUE2(j + 2, 1); // всё равно что i = j + 21;


# - это подстановка аргумента как текстовой строки
Код
#define DUMP(a) printf( "(" #a ") = %d\n", a)

int main(void)
{
   int i=5, j=7;
   DUMP( sizeof( void * ) );
   DUMP( i + j );
   return 0;
}


или, что часто более полезно, так
Код
#define ENTRY(a) { a, #a }
struct {
   int code;
   const char *name;
} error_code_table[] = {
  ENTRY(ALL_OK),
  ENTRY(CRC_ERROR),
  ENTRY(BAD_COMMAND)
};

что писать несколько веселее, чем
Код
ыtruct {
   int code;
   const char *name;
} error_code_table[] = {
  { ALL_OK, "ALL_OK" },
  { CRC_ERROR, "CRC_ERROR" },
  { BAD_COMMAND, "BAD_COMMAND" }
};


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Oct 27 2005, 10:16
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата(G}{OST @ Oct 27 2005, 12:30)
## в макросе с параметром обозначает, что далее следует параметр макроса в символьном виде без разрывов, например:
Код
#define Stop(CHN) bCh##CHN##Up = 0; bCh##CHN = 0;
Stop(13); // для препроцессора это "bCh13Up = 0; bCh13 = 0;"

*


То есть, если я правильно понял:
## (начало вставки) - параметр - ## (конец вставки)
если до вставки ничего нет то можно не писать ## в начале
и соответственно если после вставки ничего нет то можно ## не ставить
Код
#define SETDDR(x) (_DDR(x##p)|=BIT(x##b))

SETDDR(OUT0);


будет выполняться так
_DDR(OUTp)|=BIT(OUTb)
а поскольку у нас
#define OUT0p A
#define OUT0b 4
то:
_DDR(A)|=BIT(4)
за счет
#define _DDR(a) _DDR##_(a)
будет подставлено:
_DDR##_(A)|=BIT(4)
и в итоге
#define _DDR_(a) DDR##a
преобразует все к виду:
DDRA|=BIT(4)

Вот только с последними двумя
#define _DDR_(a) DDR##a
#define _DDR(a) _DDR##_(a)
не совсем понятно
а именно Зачем
#define _DDR(a) _DDR##_(a)
почему не #define _DDR(a) DDR##a ???
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Oct 27 2005, 10:18
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата(halfdoom @ Oct 27 2005, 12:34)
Цитата(&-rey @ Oct 27 2005, 11:58)
Examples of correct code
#define FOO(x) #x
#define FOO(x) my_ ## x

Может кто обьяснить что это за ## и как они работают ....

## позволяет образовывать новые идентификаторы путем "склеивания" двух
других идентификаторов. Например, объявление FOO(beep) препроцессор
преобразует в my_beep. Подробности можно почитать здесь.
*


Спасибо, счас буду переводить.
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Oct 27 2005, 10:20
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата(ReAl @ Oct 27 2005, 12:48)
Цитата(&-rey @ Oct 27 2005, 11:58)
Может кто обьяснить что это за ## и как они работают ....
*


## - это склейка аргументов после подстановки в одну лексему.
В ранних версиях С не было, использовался комментарий. Препроцессор его выкидывал перед основной работой и само собой цепочки символов склеивались.

Код
// old C style:
// #define GLUE2(a,b) a/**/b
// ANSI
#define GLUE2(a,b) a ## b

   i = GLUE2(j + 2, 1); // всё равно что i = j + 21;


# - это подстановка аргумента как текстовой строки
Код
#define DUMP(a) printf( "(" #a ") = %d\n", a)

int main(void)
{
   int i=5, j=7;
   DUMP( sizeof( void * ) );
   DUMP( i + j );
   return 0;
}


или, что часто более полезно, так
Код
#define ENTRY(a) { a, #a }
struct {
   int code;
   const char *name;
} error_code_table[] = {
  ENTRY(ALL_OK),
  ENTRY(CRC_ERROR),
  ENTRY(BAD_COMMAND)
};

что писать несколько веселее, чем
Код
ыtruct {
   int code;
   const char *name;
} error_code_table[] = {
  { ALL_OK, "ALL_OK" },
  { CRC_ERROR, "CRC_ERROR" },
  { BAD_COMMAND, "BAD_COMMAND" }
};

*


Спасибо, буду переваривать.
А по поводу bin формата я прав, или что-то где-то недопонял?
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 27 2005, 10:35
Сообщение #8


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

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



Цитата(&-rey @ Oct 27 2005, 13:16)
То есть, если я правильно понял:
## (начало вставки) - параметр  - ## (конец вставки)
если до вставки ничего нет то можно не писать ## в начале
и соответственно если после вставки ничего нет то можно ## не ставить

Нет, ## - это "двуместный оператор", он склеивает свои левый и правый аргументы (как "+" их складывает).

Цитата(&-rey)
А по поводу bin формата я прав, или что-то где-то недопонял?


А что с bin-форматом? Я что-то не нашёл вопрос.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 27 2005, 10:43
Сообщение #9


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

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



Ещё для переваривания :-)
Для неокрепших желудков - осторожно, понемногу :-)
Вопрос вкусовой, но я не люблю писать лишнее, поэтому не стесняюсь писать так:

Цитата(dlportio_driver.h)
#ifndef DLPORTIO_DRIVER_H
#define DLPORTIO_DRIVER_H


typedef WINAPI void (*DlPortWritePortUchar_t) (unsigned port, uint8_t data);
typedef WINAPI uint8_t(*DlPortReadPortUchar_t) (unsigned p);
typedef WINAPI void (*DlPortWritePortBufferUchar_t) (unsigned p, uint8_t * buf, int len);
typedef WINAPI void (*DlPortReadPortBufferUchar_t) (unsigned p, uint8_t * buf, int len);
typedef WINAPI void (*DlPortWritePortUshort_t) (unsigned p, uint16_t data);
typedef WINAPI uint16_t(*DlPortReadPortUshort_t) (unsigned p);
typedef WINAPI void (*DlPortWritePortBufferUshort_t) (unsigned p, uint16_t * buf, int len);
typedef WINAPI void (*DlPortReadPortBufferUshort_t) (unsigned p, uint16_t * buf, int len);

class dlportio_driver : public port_io_driver {
public:
  static dlportio_driver *create();

/* ЛИШНЕЕ ПОСКИПАНО */

protected:
    HINSTANCE hdlportio;

#define _DL_PTR(_f_)  _f_##_t  _f_##_P

    _DL_PTR( DlPortWritePortUchar );
    _DL_PTR( DlPortReadPortUchar );
    _DL_PTR( DlPortWritePortBufferUchar );
    _DL_PTR( DlPortReadPortBufferUchar );
    _DL_PTR( DlPortWritePortUshort );
    _DL_PTR( DlPortReadPortUshort );
    _DL_PTR( DlPortWritePortBufferUshort );
    _DL_PTR( DlPortReadPortBufferUshort );

#undef _DL_PTR

};


и в соответствующем исходнике
Цитата(dlportio_driver.cpp)
dlportio_driver *dlportio_driver::create()
{
#define _DL_LOAD(_f_) \
    do {\
        pdl->_f_##_P = (_f_##_t)GetProcAddress(pdl->hdlportio, #_f_);\
        if(pdl->_f_##_P == NULL) {\
          delete pdl;\
          return NULL;\
      }\
    } while(0)

    dlportio_driver *pdl = new dlportio_driver;

    pdl->hdlportio = LoadLibrary("DLportIO.dll");
    if (pdl->hdlportio == NULL) {
        delete pdl;
        // "Can't load port library\n"
        return NULL;
    }

    _DL_LOAD( DlPortWritePortUchar );
    _DL_LOAD( DlPortReadPortUchar );
    _DL_LOAD( DlPortWritePortBufferUchar );
    _DL_LOAD( DlPortReadPortBufferUchar );
    _DL_LOAD( DlPortWritePortUshort );
    _DL_LOAD( DlPortReadPortUshort );
    _DL_LOAD( DlPortWritePortBufferUshort );
    _DL_LOAD( DlPortReadPortBufferUshort );

    return pdl;

#undef _DL_LOAD
}


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Oct 27 2005, 12:04
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата(ReAl @ Oct 27 2005, 13:43)
Ещё для переваривания :-)
Для неокрепших желудков - осторожно, понемногу :-)
Вопрос вкусовой, но я не люблю писать лишнее, поэтому не стесняюсь писать так:

Цитата(dlportio_driver.h)
#ifndef DLPORTIO_DRIVER_H
#define DLPORTIO_DRIVER_H


typedef WINAPI void (*DlPortWritePortUchar_t) (unsigned port, uint8_t data);
typedef WINAPI uint8_t(*DlPortReadPortUchar_t) (unsigned p);
typedef WINAPI void (*DlPortWritePortBufferUchar_t) (unsigned p, uint8_t * buf, int len);
typedef WINAPI void (*DlPortReadPortBufferUchar_t) (unsigned p, uint8_t * buf, int len);
typedef WINAPI void (*DlPortWritePortUshort_t) (unsigned p, uint16_t data);
typedef WINAPI uint16_t(*DlPortReadPortUshort_t) (unsigned p);
typedef WINAPI void (*DlPortWritePortBufferUshort_t) (unsigned p, uint16_t * buf, int len);
typedef WINAPI void (*DlPortReadPortBufferUshort_t) (unsigned p, uint16_t * buf, int len);

class dlportio_driver : public port_io_driver {
public:
   static dlportio_driver *create();

/* ЛИШНЕЕ ПОСКИПАНО */

protected:
    HINSTANCE hdlportio;

#define _DL_PTR(_f_)   _f_##_t   _f_##_P

    _DL_PTR( DlPortWritePortUchar );
    _DL_PTR( DlPortReadPortUchar );
    _DL_PTR( DlPortWritePortBufferUchar );
    _DL_PTR( DlPortReadPortBufferUchar );
    _DL_PTR( DlPortWritePortUshort );
    _DL_PTR( DlPortReadPortUshort );
    _DL_PTR( DlPortWritePortBufferUshort );
    _DL_PTR( DlPortReadPortBufferUshort );

#undef _DL_PTR

};


и в соответствующем исходнике
Цитата(dlportio_driver.cpp)
dlportio_driver *dlportio_driver::create()
{
#define _DL_LOAD(_f_) \
    do {\
        pdl->_f_##_P = (_f_##_t)GetProcAddress(pdl->hdlportio, #_f_);\
        if(pdl->_f_##_P == NULL) {\
           delete pdl;\
           return NULL;\
       }\
    } while(0)

    dlportio_driver *pdl = new dlportio_driver;

    pdl->hdlportio = LoadLibrary("DLportIO.dll");
    if (pdl->hdlportio == NULL) {
        delete pdl;
        // "Can't load port library\n"
        return NULL;
    }

    _DL_LOAD( DlPortWritePortUchar );
    _DL_LOAD( DlPortReadPortUchar );
    _DL_LOAD( DlPortWritePortBufferUchar );
    _DL_LOAD( DlPortReadPortBufferUchar );
    _DL_LOAD( DlPortWritePortUshort );
    _DL_LOAD( DlPortReadPortUshort );
    _DL_LOAD( DlPortWritePortBufferUshort );
    _DL_LOAD( DlPortReadPortBufferUshort );

    return pdl;

#undef _DL_LOAD
}

*




Ужас.... но буду принимать понемногу smile.gif
По поводу bin я не нашел в IAR возможность записывать константы типа:
0b11111011
В ANSI C такого и нет, вроде, вот я и решил что IAR этот вариант представлени не поддерживает. Т. е. писать константы в hex 0xFB, или в DEC 251 соответственно.
Или может там есть возможность как-то иначе но в поиск по Help ничего не дал.
???
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 28 2005, 05:33
Сообщение #11


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

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



Цитата(&-rey @ Oct 27 2005, 15:04)
Ужас.... но буду принимать понемногу smile.gif
По поводу bin я не нашел в IAR возможность записывать константы типа:
0b11111011
В ANSI C такого и нет, вроде, вот я и решил что IAR этот вариант представлени не поддерживает. Т. е. писать константы в hex 0xFB, или в DEC  251 соответственно.
Или может там есть возможность как-то иначе но в поиск по Help ничего не дал.
???
*

В порядке убывания разумности с моей точки зрения.

1) писать не 0b0010011 и не 0x23, а (1<<ENABLE) | (3<<MODE), а то придётся помнить наизусть значение всех битов всех регистров либо постоянно лазить в документацию. Заодно надо будет меньше комментариев вида
/* ставим в режим MODE3 и разрешаем работу */
писать - оно по самому выражению будет видно.

2) привыкнуть к HEX-формату и не морочить голову об 0bxxxxxxxx

3) поискать по интернету готовый файл с любопытным #define BIN(a), который применяется как
BIN(00010011)
а на самом деле при помощи уже упомянутого 0##a приклеивает к аргументу a
лидирующий 0 для гарантии восьмеричности числа, после чего при помощи операций %8 /8 выделяет отдельные цифры и составляет двоичное число.
Поскольку всё константы - это операция времени компиляции и код эффективный.

4) Поискать по интернету готовый файл с 256-ю #defin-ами вида
#define b00000000 0x00
#define b00000001 0x01
и т.д. (внимание на то, что начинается с b, а не с нуля)


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
spf
сообщение Oct 28 2005, 06:12
Сообщение #12


Странник
****

Группа: Свой
Сообщений: 766
Регистрация: 29-08-05
Из: Екатеринбург
Пользователь №: 8 051



Цитата(ReAl @ Oct 28 2005, 10:33)
3) поискать по интернету готовый файл с любопытным #define BIN(a), который применяется как
BIN(00010011)
*


Зачем же так далеко посылать ;-)

Код
#define BIN2BYTE(a) ( ((0x##a##L>>21) & 0x80) + ((0x##a##L>>18) & 0x40) \
                   + ((0x##a##L>>15) & 0x20) + ((0x##a##L>>12) & 0x10) \
                   + ((0x##a##L>>9) & 0x08) + ((0x##a##L>>6) & 0x04)  \
                   + ((0x##a##L>>3) & 0x02) + (0x##a##L & 0x01))


--------------------
"Как много есть на свете вещей, которые мне не нужны!" Сократ
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 28 2005, 12:11
Сообщение #13


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

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



Цитата(spf @ Oct 28 2005, 09:12)
Цитата(ReAl @ Oct 28 2005, 10:33)
3) поискать по интернету готовый файл с любопытным #define BIN(a), который применяется как
BIN(00010011)
*


Зачем же так далеко посылать ;-)
*


А мне оно ненадо, я в пределах пунктов 1) и 2) работаю. Увидел, идею запомнил, писать в форум из головы влом (а сам макрос не сохранял за ненадобностью).


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
grave
сообщение Oct 28 2005, 13:35
Сообщение #14


Участник
*

Группа: Новичок
Сообщений: 33
Регистрация: 9-12-04
Из: Odessa
Пользователь №: 1 424



Вот держите заголовочник.


Иногда даже удобней пользоваться записью
#define ______o_ 2
#define ______oo 3
#define _____o__ 4
............
и т.д.

Сообщение отредактировал IgorKossak - Oct 31 2005, 07:49
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Nov 1 2005, 06:28
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Всем Спасибо за ответы, но проблема bin формата для меня не столь важна, просто если бы было, хорошо, а раз нет, то и ладно. Жить можно. В любом случае на примерах посмотрел как пишут макросы.

Вот снова копался в форумах и нашел такое:

от haker fox

Цитата(haker_fox @ Oct 21 2005, 02:26)
#ifndef CONST_H //если константа не определена, то
#define CONST_H //определить константу
//Код хедера
#endif

Когда компилятор будет во-второй раз цеплять хедер, он его не подцепит, т.к. константа CONST_H уже определена (при первом проходе)

Вместо CONST_H соответственно для другого файла - другое имя, например MAIN_H
*


и от IgorKossak

[quote=IgorKossak,Oct 24 2005, 10:55]
Никто почему-то не расскажет ещё об одной технике обьявления/определения переменных в хедерах.
Помимо охранных констант, исключающих повторное включение файла иногда бывает удобно в одном файле и определять и обьявлять переменные (экземпляры класса).
Код
#ifndef _xxx_DEF
...
unsigned int My_Int_Var;
...
#else
...
extern unsigned int My_Int_Var;
...
#endif

Константа _xxx_DEF обьявляется только в одном файле *.c, где происходит выделение под них памяти. Все же остальные файлы включающие данный хедер, будут видеть только обьявления.
При желании можно написать макрос, который сделает всё это автоматически.
*


мне как раз понадобилась данная рекомендация и я в *.h поставил так
Код
#ifndef _*_h
#define _*_h
char a=5;
#else
extern char a;
#endif

но компилятор ругается и говорит что переменная a определяется в 2-х файлах

Но вроде бы должно было быть определение как переменной a только в одном файле, а в другом где подключен *.h уже просто определение как extern.
получается что "защитный код" не работает.

Ложки не существует ? или я что-то не так сделал ???
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 17th June 2025 - 13:31
Рейтинг@Mail.ru


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