ICC AVR и стpоки - Page 6

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Russian to

Threaded View
Re: ICC AVR и стpоки
Hello "Harry.

24 Sep 03 20:59, you wrote to Oleksandr Redchuk:

 HZ>>>     А как тогда быть с прерываниями? Т.е. вот вошли в функцию,
 HZ>>> скопировали SP в Y, начали использовать Y, и тут - бац! -
 HZ>>> прерывание! Какой поинтер будет использоваться в прерывании?
 OR>>  Если прерыванию надо, то оно себе сделает, если не надо - делать
 OR>> не будет. Hе понимаю, в чём проблемы, что тебе непонятно.

 HZ>     Мне не понятно вот что: зашли в функцию, скопировали SP в Y,
 HZ> начали с ним работать - разместили в этой памяти локальные объекты, Y,
 HZ> ессно, модифицировался - TOS "уплыл" от исходного значения SP на
 HZ> величину размера локальных объектов + место под адрес возврата на
 HZ> случай прерывания/вызов функции.

Hет. SP также опускается вниз.

push    bp
mov     bp, sp
sub     sp, locals

Помнишь такое?

Так вот этот самый sub sp, locals на AVR ну очень плохо получается.


Alexey


Re: ICC AVR и стpоки
Hello Oleksandr.

25 Sep 03 09:11, you wrote to "Harry Zhurov":

Справедливости ради хочу заметить:

 OR>  Два стека (данных и управления) -- мысль довольно неплохая.
 OR> Hо, с другой стороны, требующая более аккуратного распределения
 OR> памяти -- каждому стеку надо дать, и каждому чтобы хватило.
 OR> С третьей - неужели нет gcc для sparc?

Есть.

 OR> А у него, если я правильно помню, сразу по жизни два указателя стека.

Стека 2, указатель один :)
Точнее один стек аппаратный - регистровые окна. Hа нем сохраняются адреса
возвратов, первые 6 параметров процедуры, локалы процедуры и указатели для 2го
стека (sp и fp). Этот стек полностью обслуживается операционной системой.
Второй стек расположен в памяти и управляется программой. В нем хранятся все
параметры (под первые 6 только отведено место), локальные и временные
переменные, которые не уместились в регистры, еще там есть область для
сохранения текущего окна регистров (из 1го стека). Этот стек так же
используется операционной системой (для сохранения регистров).
Создание/удаление фреймов на обоих стеках производится одной командой (одна для
создания, вторая для удаления)

Roman


Re: ICC AVR и стpоки
Hi Harry, hope you are having a nice day!


25 Сен 03, Harry Zhurov wrote to Alexey Musin:

 HZ>>>     В классах писать private не надо - объявляешь приватное
 HZ>>> сразу, потом пишешь public для открытого и вуаля. :)  Т.ч. все
 HZ>>> нативно. :))

 AM>> темнишь :)
 AM>> хоpоший стиль ввеpхy pазместить public, а ниже него - private

 HZ>     Это с чего ты взял? Этот стиль у всех свой, и можно долго спорить,
 HZ> какой лучше и правильнее.

Страуструп считает иначе. Ему нельзя верить? :)

WBR,
    AVB

ICQ# 43835774
mailto: avb<at>dialup.etr.ru

ICC AVR и стpоки
Alexey V Bugrov wrote to Harry Zhurov on Thu, 25 Sep 2003 22:58:51 +0400:

[...]

AM>>> темнишь :)
AM>>> хоpоший стиль ввеpхy pазместить public, а ниже него - private

HZ>>     Это с чего ты взял? Этот стиль у всех свой, и можно долго спорить,
HZ>> какой лучше и правильнее.

AV> Страуструп считает иначе. Ему нельзя верить? :)

    Однако книга его, 3-е издание, изобилует примерами, где у него сначала идет
представление в закрытой части, а уж затем открытый интерфейс. Сам он пишет,
что в более сложных случаях реального кода, когда представление объемно, он
предпочитает помещать его в конце, дабы не загромождать интерфейс. Я тоже
придерживаюсь такого стиля, но иногда, в простых случаях, удобно сделать
наоборот, как в примерах про complex:

// -------------------------------------------------------
    class complex
    {
        double re, im;

    public:
        complex(double r, double i) { re=r; im=i; }
        complex(double r)  // преобразование float->complex
            { re=r; im=0; }
        friend complex operator+(complex, complex);
        friend complex operator-(complex, complex); // вычитание
        friend complex operator-(complex)           // унарный минус
        friend complex operator*(complex, complex);
        friend complex operator/(complex, complex);
        // ...
     };
// -------------------------------------------------------

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

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


...so long!

### Одеяла и подружки ждут ребят.




Re: ICC AVR и стpоки
Hello "Harry.

25 Sep 03 19:22, you wrote to Oleksandr Redchuk:

 OR>> inline иметь положено. Уже 3 года как.
 HZ>     IAR C - последняя версия, afaik, 1.51, вышла где-то в 99 году. И
 HZ> много ты знаешь компиляторов, удовлетворяющих C99? Там, кстати, если и
 HZ> более существенные вещи - локальные динамические массивы. Какие
 HZ> компиляторы уже поддерживают это?

gcc

Я даже пользовался.

Alexey


Re: ICC AVR и стpоки
Hello "Harry.

25 Sep 03 19:22, you wrote to Oleksandr Redchuk:

 OR>>  вычли из SP размер локальных переменных
 HZ>     Все это в критической секции?

У тебя же есть avr-gcc. Посмотри же сам.

 HZ>>> начали с ним работать -

 HZ>     sbiw r28:r29,... ; выделили память под несколько переменных

    ; аналогично push BP
    push    R28
    push    R29

    ; аналогично mov BP, SP
    in      R28, SPL
    in      R29, SPH

    ; аналогично sub SP, locals
    sbiw    R28, locals
    in      tmp, SREG
    cli
    out     SPH, R29
    out     SREG, tmp
    out     SPL, R28

    Теперь SP продолжает указывать на вершину стека, а Y - на кадр стека
    Стек то один.

 HZ>     st -Y,...        ; тут сунули в стек еще переменную
 HZ>     ...

    Зачем? Переменные и так в распределены в стеке. Если нужно сохранить
что-то,
    то push/pop


 HZ>     Это что, после каждого такого обращения SP модифицировать?

Теперь понял?


Если компилировать с опцией -mno-interrupt, тогда при сохранении SP,
нет шаманства с SREG, а просто

out SPL, R28
out SPH, R29


А был бы SP регистром, то вообще:

push    R28
push    R29
sbiw    R28, locals
movw    SP, R28


 HZ>     Причем тут 430-й? У него SP нормально сделан, он позволяет
 HZ> адресоваться любым штатным способом и косвенно, и со смещением, и
 HZ> адресная арифметика там работает, поэтому нет необходимости его
 HZ> значение куда-то копировать. Вот если бы в том же AVR Y-pointer был бы
 HZ> одновременно и SP (т.е. был бы способен участвовать в процессе
 HZ> запоминания адресов возвратов из функций и прерываний), то всего этого
 HZ> геморроя не было бы. Правда тогда там осталось бы полтора указателя.

Можно было убрать in/out, а вместо них сделать 4 регистровых пары указателя.

r24:r25, r26:r27, r28:r29, r30:r31

Это было бы намного лучше.

А еще можно было убрать половину регистров, так как только половина из них
нормальные, а остальные используются только как временное хранение.

Alexey


ICC AVR и стpоки
Alexey Boyko wrote to "Harry Zhurov" <Harry Zhurov on Fri, 26 Sep 2003 09:40:22
+0400:

[...]

HZ>>     sbiw r28:r29,... ; выделили память под несколько переменных

AB>     ; аналогично push BP
AB>     push    R28
AB>     push    R29

AB>     ; аналогично mov BP, SP
AB>     in      R28, SPL
AB>     in      R29, SPH

AB>     ; аналогично sub SP, locals
AB>     sbiw    R28, locals
AB>     in      tmp, SREG
AB>     cli
AB>     out     SPH, R29
AB>     out     SREG, tmp
AB>     out     SPL, R28

AB>     Теперь SP продолжает указывать на вершину стека, а Y - на кадр стека
AB>     Стек то один.

HZ>>     st -Y,...        ; тут сунули в стек еще переменную
HZ>>     ...

AB>     Зачем? Переменные и так в распределены в стеке. Если нужно сохранить
AB> что-то,
AB>     то push/pop

// -----------------------------------

extern int key;
void f()
{
    char  buf[16];
    long  x = 5;
    ...

    switch(key)
    {
    case 1:
        {
            ...   //
            f1(); // функция, которая жрет много стека
        }
        break;

    case 2:
        {
            int buf[32]; // буфер, который жрет много стека
            ... //
        }
    }

}
// -----------------------------------

    Сколько памяти нужно выделять? Если по твоей технологии, то нужно
просмотреть всю функцию и выделить по максимуму: 16 + 1*4 + 32*2 = 84 байта. В
стеке. Но если поток управления пойдет по первой ветке, то выделять память под
буфер во второй не нужно, и память эта может оказаться очень не лишней при
вызове функции из первой ветки, которая (функция) тоже прилично хавает стека.
Если по второй ветке, то придется выделять по максимуму, но зато нет жручих
функций. Таким образом, если выделять не все сразу, а смотреть по  ходу дела,
то получается более эффективное расходование памяти, а если все сразу, то,
соответственно, неэффективное.


HZ>>     Это что, после каждого такого обращения SP модифицировать?

AB> Теперь понял?

    Понял, понял, но не могу признать это лучшим, чем использование отдельного
стека для данных, как это сделано в ИАРе.

AB> Если компилировать с опцией -mno-interrupt, тогда при сохранении SP,
AB> нет шаманства с SREG, а просто

    Зато можно получить по полной программе в случае возникновения прерывания
во время изменения SP.

AB> А был бы SP регистром, то вообще:

AB> push    R28
AB> push    R29
AB> sbiw    R28, locals
AB> movw    SP, R28

    Будь он регистром, то просто обязан быть указателем.


HZ>>     Причем тут 430-й? У него SP нормально сделан, он позволяет
HZ>> адресоваться любым штатным способом и косвенно, и со смещением, и
HZ>> адресная арифметика там работает, поэтому нет необходимости его
HZ>> значение куда-то копировать. Вот если бы в том же AVR Y-pointer был бы
HZ>> одновременно и SP (т.е. был бы способен участвовать в процессе
HZ>> запоминания адресов возвратов из функций и прерываний), то всего этого
HZ>> геморроя не было бы. Правда тогда там осталось бы полтора указателя.

AB> Можно было убрать in/out, а вместо них сделать 4 регистровых пары
AB> указателя.

AB> r24:r25, r26:r27, r28:r29, r30:r31

AB> Это было бы намного лучше.

    Ну, давай помечтаем: оставить 16 регистров, которые образуют 8 регистровых
пар-указателей. Все регистры полностью равноправны. Обращение в память
производится за один такт. При входе в прерывание SREG аппаратно сохраняется в
стеке, а при возврате восстанавливается... Ну, ладно, как говорит батя моего
друга: "Слезай, а то сломаешь!" ;-))


AB> А еще можно было убрать половину регистров, так как только половина из них
AB> нормальные, а остальные используются только как временное хранение.

    А avr-gcc, вроде, позволяет заблокировать произвольное количество регистров
от использования компилятором?


...so long!

### Тяжело в мyчении - легко в гpобy.



Re: ICC AVR и стpоки
27-Sep-03 04:07 Harry Zhurov wrote to Alexey Boyko:

HZ> extern int key;
HZ> void f()
HZ> {
HZ>     char  buf[16];
HZ>     long  x = 5;
HZ>     ...

HZ>     switch(key) {
HZ>     case 1:  {
HZ>             ...   //
HZ>             f1(); // функция, которая жрет много стека
 Какого из стеков? :-)
HZ>         }
HZ>         break;
HZ>     case 2: {
HZ>             int buf[32]; // буфер, который жрет много стека
HZ>             ... //
HZ>         }
HZ>     }

HZ>     Сколько памяти нужно выделять? Если по твоей технологии, то нужно
HZ> просмотреть всю функцию и выделить по максимуму: 16 + 1*4 + 32*2 = 84
 Ну вот и пожалуйста, скомпили это свежим иаром.
Так как 1.40 превосходно выделяет 80 байт на стеке в самом начале функции
(long x селит в R7:R4). AVR кривой?
Скомпили IAR/MSP430 (gcc/430 точно так же выделяет 80 байт в самом начале
функции при помощи sub #80,r1).
Аналогично поступает bcc32 от BC5.02, только число байт больше, так как
int 4-байтный. Аналогично -- OpenWatcom/win32.
Как это ни странно, но заморачиваться никто с таким не хочет (хотелось
бы ошибиться), поэтому я давно стараюсь в таких случаях
   case 2: {
        f2(); // и пусть она жрёт стек, а тут будет сбалансировано
   }
даже если эта f2() вызывается один раз отсюда и всё.

HZ> байта. В стеке. Но если поток управления пойдет по первой ветке,
HZ> то выделять память под
HZ> буфер во второй не нужно, и память эта может оказаться очень не лишней
HZ> при
HZ> вызове функции из первой ветки, которая (функция) тоже прилично хавает
HZ> стека.
 Покажи мне, что это делает IAR на двух стеках (на Y как указателе
стека, а не указателе кадра, это делается _очень_ легко) и я буду знать,
что такой компилятор точно есть.
Так как меня терзают сомнения -- я вроде бы видел компилятор,
который модифицировал указатель стека по ходу заседания, но не помню
какой и когда. А следил за этим строго :-), у меня очень частое явление
даже без switch()
foo()
{
   uchar u;
   uchar buf[3];
   ...
   {
      int i,j;
      ...
   }
   ...
   {
      uchar tmpbuf[5];
      ...
   }

}
именно для экономии стека.

Причём я уверенно помню, что _точно_ был компилятор, который
для приведенного примера раcпределял не 9 байт на стеке (sizeof(int)==2),
чего достаточно, так как i,j перекрываются с tmpbuf[], а все 13,
просто сумму всех локальных переменных :-(
Как бы это не DECUS C для PDP-11 (очень маленький и быстрый,
но очень тупой и многого даже из K&R не умевший).

HZ>     Понял, понял, но не могу признать это лучшим, чем использование
 Это не лучше, это просто "стандартно".
Почему при портировании gcc на avr не попытались сделать два стека --
я не знаю. IMHO просилось. Возможно, это просто неудобно на нём.

HZ> стека для данных, как это сделано в ИАРе.

AB>> Если компилировать с опцией -mno-interrupt, тогда при сохранении SP,
AB>> нет шаманства с SREG, а просто

HZ>     Зато можно получить по полной программе в случае возникновения
HZ> прерывания во время изменения SP.
 Надо быть полным идиотом, чтобы использовать -mno-interrupt
в программе, в которой используются прерывания. За это НАДО
получить, а не МОЖНО получить.
 Но, знаешь, как многие програмисты обходятся без C++, так же
и многие программы обходятся без прерываний :-).
Ну не нужны они там.
 Кроме того для AVR ещё есть -mtiny-stack, если даже на меге8
ручками разместить стек ниже 256-ого байта, то с этой опцией
становится жить легче, установка нового заначения атомарна.

HZ>     Будь он регистром, то просто обязан быть указателем.
 x86/16
Согласен, пример довольно кривой архитектуры, но как у него
создаётся стековый кадр - тебе уже тут рассказывали.
Если бы sp был указателем, то это было бы ненужным.
Более того, на x86/32 по esp уже можно адресоваться, но
по умолчанию часто делается стековый кадр на ebp (с сохранением
старого ebp на стеке).

HZ>>>     Причем тут 430-й? У него SP нормально сделан, он позволяет
HZ>>> адресоваться любым штатным способом и косвенно, и со смещением, и
HZ>>> адресная арифметика там работает, поэтому нет необходимости его
HZ>>> значение куда-то копировать.
 Речь не [только] о том, надо копировать или нет, а о том, что
его указательность _облегчает_ создание стекового кадра,
не _не_устраняет_ необходимость этого действия.
А то, что ты написал в прошлом письме с вопросом по AVR -- забыло
о понятии стекового кадра.

HZ>     А avr-gcc, вроде, позволяет заблокировать произвольное количество
HZ> регистров от использования компилятором?
 А толку?

wbr,
p.s. Как раз сегодня писал на ассемблере x86/32 процедуру
 (int64 * int64 + int64) / int64
с промежуточным результатами в int128.
Как мало регистров у x86 :-(
Особенно если нельзя ebp задействовать :-((

--
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua     */


ICC AVR и стpоки
Sep 2003 18:54:32 +0000 (UTC):

HZ>>     Сколько памяти нужно выделять? Если по твоей технологии, то нужно
HZ>> просмотреть всю функцию и выделить по максимуму: 16 + 1*4 + 32*2 = 84
OR>  Ну вот и пожалуйста, скомпили это свежим иаром.
OR> Так как 1.40 превосходно выделяет 80 байт на стеке в самом начале функции
OR> (long x селит в R7:R4). AVR кривой?
OR> Скомпили IAR/MSP430 (gcc/430 точно так же выделяет 80 байт в самом начале
OR> функции при помощи sub #80,r1).

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

[...]

HZ>>     А avr-gcc, вроде, позволяет заблокировать произвольное количество
HZ>> регистров от использования компилятором?
OR>  А толку?

    В реальном коде (я специально исследовал) половина регистров почти не
используется, зато при переключении контекста таскать нужно все. Вот и смысл (я
ведь не праздно интересуюсь :))!.


...so long!

### "Анна сошлась с Вронским совсем новым, неприемлемым для страны способом."
(с) Из школьного сочинения.



Re: ICC AVR и стpоки
Hello Dmitry.

22 Sep 03 16:36, you wrote to Yurij Sysoev:

 >> Отсюда же одна невкусность C++ - с Cями без pантайма в случае
 >> необходимости pаботать не пpоблема, свой crt0.o за 10 минут
 >> делается. А вот стаpтап-код для C++ - штука  ОЧЕHЬ не тpивиальная.
 DF> Всей поддержки C++ для linux kernel module - 617 строк/11930 байт.
 DF> Включая конструкторы/деструкторы для статических объектов,
 DF> обертки для new/delete.
 DF> Исключения я не использую.
 DF> Чего еще нужно?

Hефиговый такой стартап получится...   ;)

Alexey


Re: ICC AVR и стpоки
Quoted text here. Click to load it


11930 байт - это исходников, в основном инлайнов и макро.
Что из этого получается я не мерял - это мелочи по сравнению
с основным кодом.

--
Если виртуальная память закончилась, она ненастоящая.

ICC AVR и стpоки
Hi Oleksandr!
15:56:28 +0000 (UTC):

HZ>>     Это почему же? Чем плохо обернуть тот же UART в класс, где в
HZ>> конструкторе делать инициализацию? Это хороший способ не забыть
HZ>> проинициализировать все нужные SFR'ы (забыв вызвать InitUART()).

OR>  Существуют компиляторы C, которым можно указать -- эти и эти
OR> функции надо вызвать! У BorlandC это #pragma startup, у gcc это

OR> void UartInit(void) __attribute__ ((section(".init3")))
OR> __attribute__ ((naked));

    Т.е. нестандартные расширения?

OR> И код UartInit будет без пролога/эпилога и вставлен в нужное место
OR> в C-шной запускалке и отработает до входа в main.
OR> Достаточно просто включить в проект Uart.c, в котором кроме функций
OR> работы с uart будет и эта UartInit.
OR> Заодно код немного уменьшается :-)

    Hу, т.е. ведет себя как конструктор глобального объекта!? В ИАРе, кстати,
тоже никаких прологов/эпилогов нет, там механизм такой: есть специальный
сегмент DI_FUNCT, в котором размещаются адреса конструкторов. Просто тупо
адреса. При старте, после инициализации всех переменных не класс-типов,
производится запуск конструкторов: из этого сегмента извлекаются адреса в
Z-pointer, и далее icall. Да, там если в одной единице трансляции есть
несколько объектов с конструкторами, то компилятор располагает их код
последовательно, а в сегмент DI_FUNCT помещает только указатель на начало этой
цепочки конструкторов. Т.е. получается, что адресов и вызовов получается не
более, чем единиц трансляции в проекте.

Bye.

### КРЕМ ПИТАТЕЛЬHЫЙ для нормальных и жирных ног. Самовымаз прямо у склада в
Москве. Тел. 217-86-14.



Re: ICC AVR и стpоки
Alexey Boyko wrote to "Harry Zhurov" <Harry Zhurov on Fri, 19 Sep 2003 16:11:50
+0400:

AB> 18 Sep 03 21:46, you wrote to Dimmy Timchenko:

HZ>> // ----------------------------------
HZ>>     ...
HZ>>     if( keySelect.IsClick() ) CurrentParameter++;
HZ>>     if( keyPlus.IsClick()   ) CurrentParameter->Increase();
HZ>>     if( keyMinus.IsClick()  ) CurrentParameter->Decrease();
HZ>>     ...
HZ>> // ----------------------------------

AB> ...

HZ>> или перепутать что-то - все формализовано. А использование очень
HZ>> простое. По затратам, кстати, получается почти то же самое, что и в
HZ>> варианте с массивами указателей на функции, ведь этот механизм
HZ>> виртуальных функций, по сути, основан на тех же массивах указателей.

AB> Поробуй сделать без указателей: на 4-х массивах - current, min, max, delta

AB> И сравни.

    Пробовал и сравнивал. Получается по сгенеренному коду примерно то же самое,
только в этом случае приходится руками создавать массивы, руками их
инициализировать, руками организовывать в _каждой_ вызываемой функции обращение
к _своей_ переменной 'Value', словом, все то, что делает компилятор (и делает
без ошибок), придется делать руками. Исходный код в этом случае выглядит,
поверь мне, не симпатично, мягко говоря. А если учесть, что сами vtbl
компилятор помещает во флеш, то для достижения того же самого исходный код на С
придется "украсить" пачкой __flash.


...so long!

### Hard disk error: (A)bort (R)etry (P)anic




Re: ICC AVR и стpоки
Hello "Harry.

22 Sep 03 20:44, you wrote to me:

 HZ>>>     вполне работоспособен, хотя это и грязный хак, имхо. С не-POD
 HZ>>> типом такое не пройдет.
 AB>> Почему?
 HZ>     Что почему? Почему грязный хак?

Вообще-то я спрашивал почему не пройдет.

 HZ> Да потому, что действует в обход
 HZ> системы типов и компилятор тут не может проверить соответствует ли
 HZ> адресуемая память типу объекта, к которому приводится.

В приведенном тобой примере - пройдет.

 HZ> И в случае
 HZ> неправильного приведения получишь безобразный баг во всей красе.

Hо ты сделал правильное приведение, не так ли?

Alexey


ICC AVR и стpоки
Alexey Boyko wrote to "Harry Zhurov" <Harry Zhurov on Tue, 23 Sep 2003 13:09:20
+0400:

AB> 22 Sep 03 20:44, you wrote to me:

HZ>>>>     вполне работоспособен, хотя это и грязный хак, имхо. С не-POD
HZ>>>> типом такое не пройдет.
AB>>> Почему?
HZ>>     Что почему? Почему грязный хак?

AB> Вообще-то я спрашивал почему не пройдет.

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

HZ>> Да потому, что действует в обход
HZ>> системы типов и компилятор тут не может проверить соответствует ли
HZ>> адресуемая память типу объекта, к которому приводится.

AB> В приведенном тобой примере - пройдет.

HZ>> И в случае
HZ>> неправильного приведения получишь безобразный баг во всей красе.

AB> Hо ты сделал правильное приведение, не так ли?

    Это слишком простой пример. А представь себе, что копирование производится
в одной единице трансляции, а приведение в другой. Тут ошибиться не так уж
сложно. И компилятор уже ничем не поможет. Поэтому это и есть хак. Хак - не
баг, работать оно, возможно, и будет, а, возможно, и нет. Язык и компилятор
ничего не гарантируют, а ведь это их прямая обязанность - отслеживать по мере
возможностей семантические ошибки.


...so long!

### Пришлите четыре крышечки от унитаза, и вы получите бесплатный рулончик
туалетной бумаги.



Re: ICC AVR и стpоки
Hello "Harry.

22 Sep 03 20:44, you wrote to me:

 AB>> Поробуй сделать без указателей: на 4-х массивах - current, min,
 AB>> max, delta
 AB>> И сравни.

 HZ>     Пробовал и сравнивал. Получается по сгенеренному коду примерно то
 HZ> же самое, только в этом случае приходится руками создавать массивы,
 HZ> руками их инициализировать, руками организовывать в _каждой_
 HZ> вызываемой функции обращение к _своей_ переменной 'Value',

По индексу в массиве. Одномерные массивы не есть чем-то очень сложным и
тяжелым для понимания.

 HZ> словом, все
 HZ> то, что делает компилятор (и делает без ошибок), придется делать
 HZ> руками.

А так руками нужно описывать разные классы. Если в программу с массивами нужно
добавить еще одно значение, нужно просто удлиннить массивы, а на С++ - создать
новый класс. Сколько еще строк понадобится?

 HZ> Исходный код в этом случае выглядит, поверь мне, не
 HZ> симпатично, мягко говоря.

void Increment(int index)
{
    current[index] += delta[index];
    if (current[index] > max[index]) current[index] = max[index];
}

Анналогично декремент, вывод на экран, конечно, немного сложнее.

 HZ> А если учесть, что сами vtbl компилятор
 HZ> помещает во флеш, то для достижения того же самого исходный код на
 HZ> С придется "украсить" пачкой __flash.

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

Обычно, без них можно обойтись. switch на 5-6 значений будет еффективнее и
по коду и по количеству строк.

Хотя, конечно, есть такие задачи, в которых С++ будет удобнее, и тогда уже
наплевать на оверхеды всякие. Мне, в принципе, такие уже попадались, только
духу не хватает перепроектировать программу. (Работает - и пусть работает)


Alexey


Re: ICC AVR и стpоки
Hello "Harry.

22 Sep 03 20:44, you wrote to me:

 AB>> Если ты не в курсе, то кодогенертор в gcc не знает ни про Си, ни
 AB>> про Си++. Он преобразует из некоторого абстрактного языка в
 AB>> ассемблер. Так что если написан кодогенератор для msp-430, то Си++
 AB>> появляется как бы автоматически. Hужно только в библиотеке
 AB>> некоторую поддержку дописать.
 HZ>     А в чем состоит поддержка в библиотеке?

Я точно не знаю, что-то про конструкторы. Hужно изучить, что в avr-libc
сделали для этого.

 OR>>>> можно сделать static struct { ... } uarts[USED_UARTS]; и всю
 OR>>>> работу делать по индексам.
 HZ>>>     А что, их (UART'ов) много что-ли? А если один?
 HZ>>>     И потом, это смахивает на проделывание вручную того, что
 HZ>>> делает ++ный компилятор.
 AB>> ++ный компилятор автоматически определит количество и тип уартов в
 AB>> контроллере и объявит массив объектов?
 HZ>     Я имел в виду не это, а то, что нужно руками индексы метать...

В библиотечных функциях - да, надо. Hо зато один раз. К тому же я
перепробовал несколько вариантов на Си, выбирая, который компилятору
понятнее и может сделать код еффективнее. Сейчас библиотека УАРТа не самая
читабельная, но я ее просто копирую из проекта в проект и не смотрю в нее.

Hа классах есть только один способ и оптимизировать там нечего. Только на
компилятор приходится надеятся.

 AB>> А в Си inline отменили?
 HZ>     А в Си inline не было от рождения! Только сейчас в С99 его, вроде
 HZ> бы, включили. То, что это есть в любимом GCC,

Повезло мне. А что в ИАР С нету inline?

 HZ>     Кстати, как в gcc размещать данные во флеши?

Вообще gcc не поддерживает разные классы памяти, поэтому с размещением
данных во флеше есть проблемы.

 HZ>     А как на gcc это сделать?

Есть макрос:
#define PROGMEM __attribute__ ((__progmem__))

А переменные объявляются как:

char buf[16] PROGMEM;

Для доступа к таки переменным есть макрос PRG_RDB
Hапример - PRG_RDB(&buf[4])

 HZ>     И еще до кучи: можно ли каким-то образом указать функции, чтобы в
 HZ> ней не сохранялись используемые регистры, типа того, что в ИАРе
 HZ> достигается с помощью __task.

Да. Что-то вроде:
void task1() __attribute__ ((noreturn));
void task1()
{
    run();
}

Есть еще интересные аттрибуты, например:
pure - результат функции зависит только от входных параметров, и не влияет
на глобальные переменные. Если в выражении такая функция вызывается несколько
раз
с одинаковыми аргументами, то компилятор вызовет ее только один раз.

format - означает, что в функцию передается строка формата, такая же, как в
printf
и компилятор может на этапе компиляции проверить соответствие передаваемых
аргументов
строке формата.

section - поместить функцию или переменную в нужный сегмент (секцию). Так
поступают
в avr-gcc с EEPROM (__progmem__ делает почти тоже самое)

deprecated - при использовании функции будет выдан варнинг, что она -
deprecated

weak - если при линковке будет обнаружена еще одна функцияс таким же именем, то
предпочтение будет отдано той, которая без аттрибута weak.

interrupt - и так понятно.

signal - почти то же, что и interrupt

naked - не имеет пролога и эпилога. Возможно - это подойдет лучше, чем noreturn


 AB>> А вот шаблоны видимо действительно хорошая вещь. Я правда не знаю,
 AB>> как ими пользоваться, но судя по примерам - это то что нужно.
 HZ>     Шаблоны - параметризованный тип. Это позволяет не писать
 HZ> одинаковый код для разных типов, а написать один раз шаблон, а потом
 HZ> инстанцировать переменные по шаблону с нужным типом. Hапример, имеем
 HZ> кольцевой буфер (FIFO), который работает с байтами. А еще нужно такой
 HZ> же буфер для интов, даблов, структур и проч. Тогда создаем шаблон:


Это я уже знаю. Такие примеры видел в STL. Я имел ввиду, что не знаю, как
ими пользоваться. Hадо будет, наверное, какую нибудь книжку по С++ купить.

 HZ>     Собран он. Есть у меня. Только после ИАРа на него что-то ломает
 HZ> переползать. :)



Alexey


ICC AVR и стpоки
Alexey Boyko wrote to "Harry Zhurov" <Harry Zhurov on Tue, 23 Sep 2003 13:26:52
+0400:


[...]

AB> Hа классах есть только один способ и оптимизировать там нечего. Только на
AB> компилятор приходится надеятся.

    С чего ты это взял?

AB>>> А в Си inline отменили?
HZ>>     А в Си inline не было от рождения! Только сейчас в С99 его, вроде
HZ>> бы, включили. То, что это есть в любимом GCC,

AB> Повезло мне. А что в ИАР С нету inline?

    В ИАР, как и положено сишному компилятору, встраиваемых функций нет.


...so long!

### Брюки важнее жены, потому что существует немало мест, куда можно пойти без
жены.



Re: ICC AVR и стpоки
24-Sep-03 14:34 Harry Zhurov wrote to Alexey Boyko:

AB>> Повезло мне. А что в ИАР С нету inline?

HZ>     В ИАР, как и положено сишному компилятору, встраиваемых функций нет.

Компилятору, соответствующему

INTERNATIONAL STANDARD ISO/IEC         ISO/IEC 9899:1999
                 Programming languages - C

inline иметь положено. Уже 3 года как.

wbr,
--
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua     */


ICC AVR и стpоки
Sep 2003 05:39:15 +0000 (UTC):

AB>>> Повезло мне. А что в ИАР С нету inline?

HZ>>     В ИАР, как и положено сишному компилятору, встраиваемых функций нет.

OR> Компилятору, соответствующему

OR> INTERNATIONAL STANDARD ISO/IEC         ISO/IEC 9899:1999
OR>                  Programming languages - C

OR> inline иметь положено. Уже 3 года как.

    IAR C - последняя версия, afaik, 1.51, вышла где-то в 99 году. И много ты
знаешь компиляторов, удовлетворяющих C99? Там, кстати, если и более
существенные вещи - локальные динамические массивы. Какие компиляторы уже
поддерживают это?

...so long!

### Заплатил налоги и сплю спокойно. На лавочках, в подвалах, на вокзале.



Site Timeline