Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR. Помогите разобраться с настройками
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
demiurg1978
Потребовалось написать проект для ATTINY c 1 kB flash. IAR. При компиляции выдал ошибку и ругнулся на CSTACK и RSTACK. На жирных МК меня эти настройки не волновали. Поставил с TINY на SMALL и все. Сейчас наступил момент подробно разобраться с этими настройками. Поясните пожалуйста так, чтобы я понял как правильно лезть в эти настройки.
При таких настройках как на картинке ошибка исчезла. Как смутно понял, так и поставил.
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 16:04) *
Как смутно понял, так и поставил.

Пока Вы сами не поймете, как работает микроконтрорллер со стеками, что это за стеки и какая глубина их ВАМ В ВАШЕЙ ПРОГРАММЕ требуется ДЛЯ РАБОТЫ, а не зачем-то какому-то там "IAR" которому нужно заткунуть предупреждения, придется учить матчасть.
demiurg1978
Цитата(zltigo @ Sep 9 2015, 20:17) *
...

Не спешите желчь изливаться. Я знаю что это за стеки. Скажем, про глубину вложений я понял. RSTACK. Здесь я полностью ориентируюсь, какая глубина вложений у меня в программе. А вот CSTACK мне непонятно, что именно означает это число, и из каких соображений исходить, чтобы изменять это число.
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 16:21) *
вот CSTACK мне непонятно

Ну так изучите так-же, как и RSTACK. Явно ведь в том-же букваре, где и про Return STACK прочитали есть и про CSTACK в принципе это "просто" стек, как "у всех" для данных. Сколько Вы данных в стеке храните и через стек передаете, это только Вы знаете.
demiurg1978
Цитата(zltigo @ Sep 9 2015, 20:29) *
...

То есть я должен исходить из максимального объема передаваемых параметров функций?
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 16:31) *
То есть я должен исходить из максимального объема параметров функций?

При этом параметры не всегда предаются через стек. Но на стеке хранятся и локальные переменные функции, опять-же те, которым места в регистрах не хватило. А любая функция может быть прервана обработчиком прерывания, которому так-же требуется стек...
Пути два - смотреть листинги, как регистровая пара указателя на стек меняется, либо ставить "побольше" до упора ругани линкера и во время работы контролировать степень использования, например по степени затирания заренее занесенной в стек информации.
demiurg_spb
Цитата(demiurg1978 @ Sep 9 2015, 16:31) *
То есть я должен исходить из максимального объема передаваемых параметров функций?

Скорее нет, чем да.
Важно тело функции - как много ему требуется на стеке для локальных переменных, не уместившихся в регистрах.
Прочитайте про стековый фрейм, применительно к конкретной архитектуре и конкретному компилятору.
Также важна и алгоритмическая часть: рекурсии например...
demiurg1978
Цитата(demiurg_spb @ Sep 9 2015, 20:59) *
...

Рекурсии пока отложим в сторону. Есть у меня функция. Как я могу понять, что у меня все будет нормально работать, хватит стека данных?
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 17:09) *
Рекурсии пока отложим в сторону. Есть у меня функция. Как я могу понять, что у меня все будет нормально работать, хватит стека данных?

Повторяю - смотрите листинг. По сишному соглашению стек восстанавливает вызываемая функция, таким образом увидите на сколько при выходе меняется указатель стека даже не вникая в содержимое кодов функции.
demiurg1978
Цитата(zltigo @ Sep 9 2015, 21:11) *
...

Я вернул настройки, когда выдало ошибку.
CODE

Building configuration: timer_easy - Debug
Updating build tree...
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\events.lst
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\events.r90
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\kbd_drv.lst
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\kbd_drv.r90
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\main.lst
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\main.r90
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\main_def_func.lst
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\main_def_func.r90
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\proc_timer.lst
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\proc_timer.r90
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\sys_timer.lst
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\sys_timer.r90
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\events.pbi
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\kbd_drv.pbi
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\main.pbi
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\main_def_func.pbi
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\proc_timer.pbi
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\sys_timer.pbi
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Exe\timer_easy.dbg
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Exe\timer_easy.eep
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Exe\timer_easy.hex
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\timer_easy.pbd

22 file(s) deleted.
Updating build tree...

main_def_func.c
iccavr.exe F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\main_def_func.c --cpu=tiny13 -mt -o F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\
-lCN F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\ --initializers_in_flash --debug -DENABLE_BIT_DEFINITIONS -e --eeprom_size 64 --clib
-Ohz

IAR C/C++ Compiler V6.12.1.50500 for Atmel AVR
Copyright 1996-2012 IAR Systems AB.

164 bytes of CODE memory
0 bytes of DATA memory (+ 2 bytes shared)

Errors: none
Warnings: none

events.c
iccavr.exe F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\events.c --cpu=tiny13 -mt -o F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\ -lCN
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\ --initializers_in_flash --debug -DENABLE_BIT_DEFINITIONS -e --eeprom_size 64 --clib -Ohz

IAR C/C++ Compiler V6.12.1.50500 for Atmel AVR
Copyright 1996-2012 IAR Systems AB.

82 bytes of CODE memory (+ 4 bytes shared)
2 bytes of DATA memory

Errors: none
Warnings: none

kbd_drv.c
iccavr.exe F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\kbd_drv.c --cpu=tiny13 -mt -o F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\ -lCN
F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\ --initializers_in_flash --debug -DENABLE_BIT_DEFINITIONS -e --eeprom_size 64 --clib -Ohz

IAR C/C++ Compiler V6.12.1.50500 for Atmel AVR
Copyright 1996-2012 IAR Systems AB.

156 bytes of CODE memory (+ 4 bytes shared)
2 bytes of DATA memory (+ 1 byte shared)

Errors: none
Warnings: none

main.c
iccavr.exe F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\main.c --cpu=tiny13 -mt -o F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\ -lCN F:\
Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\ --initializers_in_flash --debug -DENABLE_BIT_DEFINITIONS -e --eeprom_size 64 --clib -Ohz

IAR C/C++ Compiler V6.12.1.50500 for Atmel AVR
Copyright 1996-2012 IAR Systems AB.

22 bytes of CODE memory

Errors: none
Warnings: none

proc_timer.c
iccavr.exe F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\proc_timer.c --cpu=tiny13 -mt -o F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\
-lCN F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\ --initializers_in_flash --debug -DENABLE_BIT_DEFINITIONS -e --eeprom_size 64 --clib
-Ohz

IAR C/C++ Compiler V6.12.1.50500 for Atmel AVR
Copyright 1996-2012 IAR Systems AB.
Warning[Pe550]: variable "_led_blink" was set but never used F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\proc_timer.c 86
Warning[Pe550]: variable "led_1_blink_mode" was set but never used F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\proc_timer.c 87
Warning[Pe177]: variable "tmp_cnt_minutes" was declared but never referenced F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\proc_timer.c 88

106 bytes of CODE memory (+ 4 bytes shared)
4 bytes of DATA memory (+ 2 bytes shared)

Errors: none
Warnings: 3

sys_timer.c
iccavr.exe F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\sys_timer.c --cpu=tiny13 -mt -o F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\
-lCN F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\ --initializers_in_flash --debug -DENABLE_BIT_DEFINITIONS -e --eeprom_size 64 --clib
-Ohz

IAR C/C++ Compiler V6.12.1.50500 for Atmel AVR
Copyright 1996-2012 IAR Systems AB.

192 bytes of CODE memory (+ 6 bytes shared)
16 bytes of DATA memory (+ 4 bytes shared)

Errors: none
Warnings: none

Linking
xlink.exe -Ointel-standard,(CODE)=.hex -Ointel-standard,(XDATA)=.eep F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\events.r90 F:\Work\
Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\kbd_drv.r90 F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\main.r90 F:\Work\Projects\
ATMEL\IAR\C\TIMER_EASY\Debug\Obj\main_def_func.r90 F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\proc_timer.r90 F:\Work\Projects\
ATMEL\IAR\C\TIMER_EASY\Debug\Obj\sys_timer.r90 -o F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Exe\timer_easy.dbg -Fubrof8 -IC:\
Program Files\IAR Systems\Embedded Workbench 6.0\avr\LIB\ -f C:\Program Files\IAR Systems\Embedded Workbench 6.0\avr\src\template\
cfgtiny13.xcl -D_..X_HEAP_SIZE=10 -D_..X_TINY_HEAP_SIZE=0 -D_..X_NEAR_HEAP_SIZE=0 -D_..X_FAR_HEAP_SIZE=0 -D_..X_HUGE_HEAP_SIZE=0
-D_..X_CSTACK_SIZE=20 -D_..X_RSTACK_SIZE=10 -D_..X_FLASH_CODE_END=_..X_FLASH_END -f C:\Program Files\IAR Systems\Embedded
Workbench 6.0\avr\src\template\cfg0t.xcl -D_..X_FLASH_BASE=_..X_INTVEC_SIZE -H1895 -h(CODE)0-(_..X_INTVEC_SIZE-1)
-D_..X_CSTACK_BASE=_..X_SRAM_BASE -D_..X_CSTACK_END=_..X_SRAM_END -D_..X_RSTACK_BASE=_..X_SRAM_BASE
-D_..X_RSTACK_END=_..X_SRAM_END -s __program_start C:\Program Files\IAR Systems\Embedded Workbench 6.0\avr\LIB\CLIB\cl0t-ec_nomul.r90
-e_large_write=_formatted_write -e_large_read=_formatted_read

IAR Universal Linker V5.3.2.26
Copyright 1987-2012 IAR Systems AB.
Error[e16]: Segment RSTACK (size: 0x10 align: 0) is too long for segment definition. At least 0x8 more bytes needed. The problem occurred while
processing the segment placement command "-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_RSTACK_BASE-_..X_RSTACK_END", where at the
moment of placement the available memory ranges were "DATA:98-9f"
Reserved ranges relevant to this placement:
DATA:60-77 TINY_Z
DATA:78-97 CSTACK
DATA:98-9f RSTACK
Error while running Linker

Total number of errors: 1
Total number of warnings: 3



Как мне здесь понять, где смотреть? Я специально очистил проект и скомпилировал. Листинги модулей есть.
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 17:17) *
Как мне здесь понять, где смотреть?

Это НЕ листинг. Тут смотреть нечего. Ну разве только то, что не хватает 8 байт памяти и думать, рассматривая map файл, кто ее сожрал.
QUOTE
Листинги модулей есть.

Ну и изучайте В ЛИСТИНГЕ интересующую Вас функцию. Как - УЖЕ написал. Не переспрашивайте третий раз!
demiurg1978
Цитата(zltigo @ Sep 9 2015, 21:22) *
...

Я понимаю, что это не листинг. Как понять, какой именно листинг смотреть, какую функцию смотреть?

Цитата(zltigo @ Sep 9 2015, 21:22) *
Не переспрашивайте третий раз!


Так поясните ПРИНЦИП, как это понять, где смотреть?
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 17:25) *
Я понимаю, что это не листинг.

Радует.
QUOTE
Как понять, какой именно листинг смотреть, какую функцию смотреть?

Тот в котором есть интересующая Вас функция. Листинги по именам файлов. Это вообще-то более, чем очевидно.
QUOTE
Так поясните ПРИНЦИП, как это понять, где смотреть?

http://electronix.ru/forum/index.php?showt...130340&hl=#
demiurg1978
Цитата(zltigo @ Sep 9 2015, 20:29) *
Сколько Вы данных в стеке храните и через стек передаете, это только Вы знаете.

Извините за такой вопрос, вы именно с AVR работаете? Это не подначка. Работу со стеком определяет компилятор. На стек я не могу повлиять.
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 17:46) *
Извините за такой вопрос, вы именно с AVR работаете?

И еще с более, чем с десятком котроллеров.
QUOTE
Работу со стеком определяет компилятор.

Да компилятор исходя из Ваших приказов.
QUOTE
На стек я не могу повлиять.

Да ну!!! Можете. Не прямо, конечно, сказав - а займи-ка компилятор стека в два раза меньше, ну и заодно ROM и RAM раза в три поменьше. Но программу пишете Вы. Значит влияете.
В данном случае речь идет об ОБЯЗАННОСТИ выделить нужное компиляторок количество памяти под стек.
demiurg1978
Что-то диалог в тупик зашел. На ассемблере я могу контролировать. Как я могу изначально контролировать, что мне накомпилирует компилятор си? Уровень оптимизицаии да, вид оптимизации да. Но стек данных?
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 17:59) *
Но стек данных?

Данные, поростите, это компилятор сам себе придумывает, или все-же Вы ему приказываете создать??? Причем в общем даже даже говорите где и кроме всего прочего можете выказывать свое требования и/или предпочтения к размещению переменных через квалификаторы.
QUOTE
Что-то диалог в тупик зашел

И я даже знаю почему - Вы с тупым упорством не желаете заглянуть в листинг в котором видны использования стеков.
SSerge
На всякий случай уточню: листинг - это файл с расширением .lst
В этом файле, ближе к концу, есть сводная табличка по использованию стеков в функциях:
Код
   Maximum stack usage in bytes:

   CSTACK RSTACK Function
   ------ ------ --------
       8      4  Device::Check_Para()
                   8 2 -> SPI::Set_DAC_Reg(char *)
       0      2  Device::Gen_OFF()
       0      2  Device::Gen_ON()
       8      4  Device::Handler()
                   8 2 -- Indirect call
Dog Pawlowa
Цитата(demiurg1978 @ Sep 9 2015, 17:59) *
Но стек данных?

Да при чем тут стеки вообще?!
Банально не хватает памяти, данные в ОЗУ (обычные данные, не стек) заняли столько места, что даже под более чем скромный стек места нет.

Ну найдете 2 байта, дальше что? - программу дальше не увеличить.
Или уж очень криво написана, или контроллер на пределе.

Цитата(zltigo @ Sep 9 2015, 18:08) *
И я даже знаю почему - Вы с тупым упорством не желаете заглянуть в листинг в котором видны использования стеков.

А первичная причина в том, что в ИАРе по умолчанию они не выводятся, нужно галку поставить wink.gif
demiurg1978
Цитата(Dog Pawlowa @ Sep 9 2015, 23:25) *
А первичная причина в том, что в ИАРе по умолчанию они не выводятся, нужно галку поставить wink.gif

Не подскажете, что за галочка, и где в настройках?
Dog Pawlowa
Цитата(demiurg1978 @ Sep 9 2015, 19:27) *
Не подскажете, что за галочка, и где в настройках?

option/C-C++ compiler/list
zltigo
QUOTE (Dog Pawlowa @ Sep 9 2015, 19:25) *
А первичная причина в том, что в ИАРе по умолчанию они не выводятся, нужно галку поставить wink.gif

Я не в курсе галочек IAR среды, ибо пользуюсь компиляторами, в том числе и IAR, но не всякими дивными недоношенными IDE оболочками раздаваемыми в качестве халявы с компиляторами.
А то-бы я давно с ума сошел от разых IDE.
Так-что ставлю всегда ключик в командной строке выводить листинги.

Но вообще-то Автор утверждал следущее :"Листинги модулей есть." Так-что разговор и пошел про просмотреть их.
demiurg1978
Цитата(Dog Pawlowa @ Sep 9 2015, 23:25) *
Банально не хватает памяти, данные в ОЗУ (обычные данные, не стек) заняли столько места, что даже под более чем скромный стек места нет.

А первичная причина в том, что в ИАРе по умолчанию они не выводятся, нужно галку поставить wink.gif

Памяти хватает. Есть 64 байт. Компилятор пишет что занято 61 байт. Учитываем глубину вложений, прерывания. Я поставил 8 байт. Хватает. Гонял программу в симуляторе на всю глубину вложений+прерывания. Остается стек данных.

Листинг включен. Показаны CSTACK и RSTACK. Если смотреть по каждому файлу листинга криминала не вижу.

Осталось понять, как компилятор подсчитывает память. И на какие цифры в будущем смотреть, чтобы выявить проблему.
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 19:43) *
Осталось понять, как компилятор подсчитывает память.

Вообще-то осталось понять, что компилятор НЕ ПОДСЧИТЫВАЕТ ПАМЯТЬ выделемую для стеков!
demiurg1978
Цитата(zltigo @ Sep 9 2015, 23:49) *
Вообще-то осталось понять, что компилятор НЕ ПОДСЧИТЫВАЕТ ПАМЯТЬ выделемую для стеков!

Вот что вы нервничаете? Мы знакомы? Ни я вам ни вы мне ничего не сделали, чтобы вы позволяли себе такую резкость. Я на си пишу не так давно. До этого писал на асме. Ессно, некоторые вещи представляют для меня некоторую трудность. Терминология опять же. Для вас-то что-то можеть быть уже пройденный вдоль и поперек этап. А мне пока некоторые вещи еще в новинку. Скажите спасибо, что не на ардуине или CVAVR проекты пишу...
demiurg_spb
Цитата(demiurg1978 @ Sep 9 2015, 19:55) *
Вот что вы нервничаете?
Да ладно. Вы тоже не переживайте))) Это у него стиль общения такой. Без zltigo на форуме последние пару лет было даже как-то пусто...
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 19:55) *
Вот что вы нервничаете?

Зачем?
QUOTE
чтобы вы позволяли себе такую резкость.

Это Вы себе позволяете НЕ читать и НЕ понимать того, что Вам пишут, причем неоднократно.
QUOTE
Я на си пишу не так давно. До этого писал на асме.

Вынужден Вам сообщить, что стеки это не Си и не ACM, это контроллер. И память под эти стеки должна быть выделена, и указатели проинициализированы, хоть на чем пишите, хоть в кодах, хоть на суахили. Так-что как Вы "писали" на АСМ, сейчас видно как Вы пишите на Си sad.gif
QUOTE
Скажите спасибо, что не на ардуине или CVAVR проекты пишу...

Спасибо. Спасибо мне ничего не стоит, в отличие от затрат времени на объяснения и повторения.




QUOTE (demiurg_spb @ Sep 9 2015, 20:43) *
Без zltigo на форуме последние пару лет было даже как-то пусто...

Увы, не могу обещать, что надолго вернулся sm.gif
demiurg1978
Цитата(zltigo @ Sep 10 2015, 02:06) *
Так-что как Вы "писали" на АСМ, сейчас видно как Вы пишите на Си

Не собираюсь вам что-то доказывать.
Позволили себе фи в мою сторону, хлебайте теперь. Покажите делом. Поступим просто. Я собрал проект из единственного модуля. Покажите здесь криминал. Исходные данные: ATTINY13. 64 байта ОЗУ. Настройки CSTACK 0x20. RSTACK 8. Найдите криминал в листинге:
CODE

###############################################################################
# #
# IAR C/C++ Compiler V6.12.1.50500 for Atmel AVR 10/Sep/2015 01:38:52 #
# Copyright 1996-2012 IAR Systems AB. #
# #
# Source file = F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\sys_timer.c #
# Command line = F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\sys_timer.c #
# --cpu=tiny13 -mt -o F:\Work\Projects\ATMEL\IAR\C\TIMER_E #
# ASY\Debug\Obj\ -lC F:\Work\Projects\ATMEL\IAR\C\TIMER_EA #
# SY\Debug\List\ -lA F:\Work\Projects\ATMEL\IAR\C\TIMER_EA #
# SY\Debug\List\ --initializers_in_flash --debug #
# -DENABLE_BIT_DEFINITIONS -e --eeprom_size 64 --clib -Ohz #
# List file = F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\sys_t #
# imer.lst #
# Object file = F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\sys_ti #
# mer.r90 #
# #
# #
###############################################################################

F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\sys_timer.c
1 //========================================================================
2 #include "sys_timer.h"

\ In segment ABSOLUTE, at 0x59
\ union <unnamed> volatile __io _A_TIMSK0
\ _A_TIMSK0:
\ 00000000 DS8 1

\ In segment ABSOLUTE, at 0x56
\ union <unnamed> volatile __io _A_OCR0A
\ _A_OCR0A:
\ 00000000 DS8 1

\ In segment ABSOLUTE, at 0x53
\ union <unnamed> volatile __io _A_TCCR0B
\ _A_TCCR0B:
\ 00000000 DS8 1

\ In segment ABSOLUTE, at 0x52
\ union <unnamed> volatile __io _A_TCNT0
\ _A_TCNT0:
\ 00000000 DS8 1
3 //========================================================================
4
5 //========================================================================
6 u08 sys_tick;
7 //========================================================================
8
9 //========================================================================
10 #pragma vector = TIM0_COMPA_vect

\ In segment CODE, align 2, keep-with-next
11 __interrupt void Timer0Comp(void)
\ Timer0Comp:
12 {
\ 00000000 93EA ST -Y, R30
\ 00000002 931A ST -Y, R17
\ 00000004 930A ST -Y, R16
\ 00000006 B71F IN R17, 0x3F
13 ST_OCR += SYS_TIME;
\ 00000008 B706 IN R16, 0x36
\ 0000000A 560A SUBI R16, 106
\ 0000000C BF06 OUT 0x36, R16
14 set_bit (sys_tick, SYS_TICK);
\ 0000000E .... LDI R30, Timers_Queue
\ 00000010 8904 LDD R16, Z+20
\ 00000012 6001 ORI R16, 0x01
\ 00000014 8B04 STD Z+20, R16
15 }
\ 00000016 BF1F OUT 0x3F, R17
\ 00000018 9109 LD R16, Y+
\ 0000001A 9119 LD R17, Y+
\ 0000001C 91E9 LD R30, Y+
\ 0000001E 9518 RETI
\ 00000020 REQUIRE _A_OCR0A
16 //========================================================================
17
18 //========================================================================

\ In segment CODE, align 2, keep-with-next
19 void init_sys_timer (void)
\ init_sys_timer:
20 {
21 sys_tick = 0;
\ 00000000 E000 LDI R16, 0
\ 00000002 .... LDI R30, Timers_Queue
\ 00000004 8B04 STD Z+20, R16
22 ST_TCNT = 0;
\ 00000006 BF02 OUT 0x32, R16
23 set_bit (ST_TIMSK, ST_OCIE);
\ 00000008 B709 IN R16, 0x39
\ 0000000A 6004 ORI R16, 0x04
\ 0000000C BF09 OUT 0x39, R16
24 ST_OCR = SYS_TIME;
\ 0000000E E906 LDI R16, 150
\ 00000010 BF06 OUT 0x36, R16
25 ST_TCCR |= ((1<<CS0) | (1<<CS1));
\ 00000012 B703 IN R16, 0x33
\ 00000014 6003 ORI R16, 0x03
\ 00000016 BF03 OUT 0x33, R16
26 }
\ 00000018 9508 RET
\ 0000001A REQUIRE _A_TCNT0
\ 0000001A REQUIRE _A_TIMSK0
\ 0000001A REQUIRE _A_OCR0A
\ 0000001A REQUIRE _A_TCCR0B

\ In segment TINY_Z, align 1, keep-with-next
\ 00000000 REQUIRE `?<Segment init: TINY_Z>`
27 //------------------------------------------------------------------------
28
29 //------------------------------------------------------------------------
30 struct tmrs_queue Timers_Queue [TMRS_QUANTITY];
\ Timers_Queue:
\ 00000000 DS8 20
\ sys_tick:
\ 00000014 DS8 1
31

\ In segment CODE, align 2, keep-with-next
32 void service_timers(void)
\ service_timers:
33 {
34 if (sys_tick & (1<<SYS_TICK))
\ 00000000 .... LDI R30, Timers_Queue
\ 00000002 8904 LDD R16, Z+20
\ 00000004 FF00 SBRS R16, 0
\ 00000006 C01A RJMP ??service_timers_0
35 {
36 clr_bit (sys_tick, SYS_TICK);
\ 00000008 7F0E ANDI R16, 0xFE
\ 0000000A 8B04 STD Z+20, R16
37
38 u08 i;
39
40 for (i = 0; i < TMRS_QUANTITY; i++)
\ 0000000C E000 LDI R16, 0
41 {
42 if (Timers_Queue [i]. tmr_flags & (1<<TMR_UNLOCK))
\ ??service_timers_1:
\ 0000000E 2F10 MOV R17, R16
\ 00000010 0F11 LSL R17
\ 00000012 0F11 LSL R17
\ 00000014 0F10 ADD R17, R16
\ 00000016 .... LDI R30, Timers_Queue
\ 00000018 0FE1 ADD R30, R17
\ 0000001A 8110 LD R17, Z
\ 0000001C FF10 SBRS R17, 0
\ 0000001E C00B RJMP ??service_timers_2
43 {
44 Timers_Queue [i]. tmr_cnt--;
\ 00000020 8121 LDD R18, Z+1
\ 00000022 8132 LDD R19, Z+2
\ 00000024 5021 SUBI R18, 1
\ 00000026 4030 SBCI R19, 0
\ 00000028 8321 STD Z+1, R18
\ 0000002A 8332 STD Z+2, R19
45
46 if (Timers_Queue[i]. tmr_cnt == 0)
\ 0000002C 8121 LDD R18, Z+1
\ 0000002E 2B23 OR R18, R19
\ 00000030 F411 BRNE ??service_timers_2
47 set_bit (Timers_Queue[i]. tmr_flags, TIME_OUT);
\ 00000032 6012 ORI R17, 0x02
\ 00000034 8310 ST Z, R17
48 }
49 }
\ ??service_timers_2:
\ 00000036 9503 INC R16
\ 00000038 3004 CPI R16, 4
\ 0000003A F348 BRCS ??service_timers_1
50 }
51 }
\ ??service_timers_0:
\ 0000003C 9508 RET
52
53 //------------------------------------------------------------------------
54
55 //------------------------------------------------------------------------

\ In segment CODE, align 2, keep-with-next
56 void set_timer(u08 num_tmr, u16 time)
\ set_timer:
57 {
58 set_bit (Timers_Queue [num_tmr]. tmr_flags, TMR_UNLOCK);
\ 00000000 .... RCALL ?Subroutine1
\ ??CrossCallReturnLabel_5:
\ 00000002 6001 ORI R16, 0x01
\ 00000004 8300 ST Z, R16
59 Timers_Queue [num_tmr]. tmr_cnt = time;
\ 00000006 8321 STD Z+1, R18
\ 00000008 8332 STD Z+2, R19
60 }
\ 0000000A 9508 RET

\ In segment CODE, align 2, keep-with-next
\ ?Subroutine1:
\ 00000000 .... RCALL ?Subroutine2
\ ??CrossCallReturnLabel_1:
\ 00000002 .... LDI R30, Timers_Queue
\ 00000004 0FE0 ADD R30, R16
\ 00000006 REQUIRE ?Subroutine3
\ 00000006 ; // Fall through to label ?Subroutine3

\ In segment CODE, align 2, keep-with-next
\ ?Subroutine3:
\ 00000000 8100 LD R16, Z
\ 00000002 9508 RET

\ In segment CODE, align 2, keep-with-next
\ ?Subroutine2:
\ 00000000 2F10 MOV R17, R16
\ 00000002 0F00 LSL R16
\ 00000004 0F00 LSL R16
\ 00000006 0F01 ADD R16, R17
\ 00000008 9508 RET
61 //------------------------------------------------------------------------
62
63 //------------------------------------------------------------------------

\ In segment CODE, align 2, keep-with-next
64 u08 wait(u08 num_tmr)
\ wait:
65
66 {
67 if(Timers_Queue [num_tmr]. tmr_flags & (1<<TIME_OUT))
\ 00000000 .... RCALL ?Subroutine1
\ ??CrossCallReturnLabel_6:
\ 00000002 FF01 SBRS R16, 1
\ 00000004 C004 RJMP ??wait_0
68 {
69 clr_bit (Timers_Queue [num_tmr]. tmr_flags, TIME_OUT);
\ 00000006 7F0D ANDI R16, 0xFD
\ 00000008 8300 ST Z, R16
70 return 1;
\ 0000000A E001 LDI R16, 1
\ 0000000C 9508 RET
71 }
72 else
73 return 0;
\ ??wait_0:
\ 0000000E E000 LDI R16, 0
\ 00000010 9508 RET
74 }
75 //========================================================================
76

\ In segment CODE, align 2, keep-with-next
77 void set_timer_time_out (u08 a)
\ set_timer_time_out:
78 {
79 set_bit (Timers_Queue [a] .tmr_flags, TIME_OUT);
\ 00000000 .... RCALL ?Subroutine0
\ ??CrossCallReturnLabel_2:
\ 00000002 6002 ORI R16, 0x02
\ 00000004 REQUIRE ?Subroutine4
\ 00000004 ; // Fall through to label ?Subroutine4
80 }

\ In segment CODE, align 2, keep-with-next
\ ?Subroutine4:
\ 00000000 8300 ST Z, R16
\ 00000002 9508 RET

\ In segment CODE, align 2, keep-with-next
\ ?Subroutine0:
\ 00000000 .... RCALL ?Subroutine2
\ ??CrossCallReturnLabel_0:
\ 00000002 2FE0 MOV R30, R16
\ 00000004 .... SUBI R30, (-(Timers_Queue) & 0xFF)
\ 00000006 .... RJMP ?Subroutine3
81

\ In segment CODE, align 2, keep-with-next
82 void set_timer_active (u08 a)
\ set_timer_active:
83 {
84 set_bit (Timers_Queue [a] .tmr_flags, TMR_UNLOCK);
\ 00000000 .... RCALL ?Subroutine0
\ ??CrossCallReturnLabel_3:
\ 00000002 6001 ORI R16, 0x01
\ 00000004 .... RJMP ?Subroutine4
85 }
86

\ In segment CODE, align 2, keep-with-next
87 void set_timer_no_active (u08 a)
\ set_timer_no_active:
88 {
89 clr_bit (Timers_Queue [a] .tmr_flags, TMR_UNLOCK);
\ 00000000 .... RCALL ?Subroutine0
\ ??CrossCallReturnLabel_4:
\ 00000002 7F0E ANDI R16, 0xFE
\ 00000004 .... RJMP ?Subroutine4
90 }

\ In segment INTVEC, offset 0xc, root
\ `??Timer0Comp??INTVEC 12`:
\ 0000000C .... RJMP Timer0Comp

Maximum stack usage in bytes:

CSTACK RSTACK Function
------ ------ --------
3 2 Timer0Comp
0 2 init_sys_timer
0 2 service_timers
0 2 set_timer
0 2 set_timer_active
0 2 set_timer_no_active
0 2 set_timer_time_out
0 2 wait


Segment part sizes:

Bytes Function/Label
----- --------------
2 ??Timer0Comp??INTVEC 12
8 ?Subroutine0
6 ?Subroutine1
10 ?Subroutine2
4 ?Subroutine3
4 ?Subroutine4
32 Timer0Comp
21 Timers_Queue
sys_tick
1 _A_OCR0A
1 _A_TCCR0B
1 _A_TCNT0
1 _A_TIMSK0
26 init_sys_timer
62 service_timers
12 set_timer
6 set_timer_active
6 set_timer_no_active
4 set_timer_time_out
18 wait
4 -- Other


4 bytes in segment ABSOLUTE
198 bytes in segment CODE
4 bytes in segment INITTAB
2 bytes in segment INTVEC
21 bytes in segment TINY_Z

198 bytes of CODE memory (+ 6 bytes shared)
21 bytes of DATA memory (+ 4 bytes shared)

Errors: none
Warnings: none

zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 22:44) *
Не собираюсь вам что-то доказывать.

А я и не спрашивал от Вас "доказательств" чего-либо по причине нахренненужности.
QUOTE
Позволили себе фи в мою сторону

Это констатация факта, так-что включайте мозг, а не эмоции.
QUOTE
Покажите здесь криминал.

Криминал Вам уже ПОКАЗАЛ линкер, кторый сказал, что RAM затребованной Вами при написании этой программы замного будет.
http://electronix.ru/forum/index.php?showt...t&p=1363816
demiurg1978
Цитата(zltigo @ Sep 10 2015, 03:23) *
...

Без эмоций уже не получится, вы пришли, на две страницы затроллили нахер тему, информации до сих пор я не получил. Хорошо, вы вытрепнулись. Я вам выложил листинг. Покажите мне пальцем, ткните носом, в каком месте не хватает ОЗУ. Если вы мне не ответите на этот вопрос, идите мимо, по хорошему вас прошу.
zltigo
QUOTE (demiurg1978 @ Sep 9 2015, 23:37) *
Без эмоций уже не получится, вы пришли, на две страницы затроллили нахер тему, информации до сих пор я не получил.

Получили, но не смогли заставить себя понять, завязнув в упорном убеждении, что компилятор все распределение памяти должен сделать за Вас.
QUOTE
Я вам выложил листинг. Покажите мне пальцем, ткните носом, в каком месте не хватает ОЗУ. Если вы мне не ответите на этот вопрос, идите мимо, по хорошему вас прошу.

Повторю ответ уже в который раз, но ведь Вы так и не поймете.
Не хватает байта. 25 байт Вы выделеили под переменные, 32 байта под один стек и 8 под другой (это с Ваших слов, ибо скрипта линкера Вы не показли). Теперь, если не верите линкеру в его диагнозе, и не можете посчитать в уме, то возьмите калькулятор.
На вопрос очередной раз - ответил, но все равно пойду, ибо жаль бестолку время тратить.
Dog Pawlowa
Цитата(demiurg1978 @ Sep 9 2015, 23:37) *
на две страницы затроллили нахер тему, информации до сих пор я не получил.

я советую Вам сменить отношение к дающим Вам советы, иначе не останется форумов в рунете, где Вас не банят wink.gif
Непомнящий Евгений
Цитата(demiurg1978 @ Sep 9 2015, 17:09) *
Рекурсии пока отложим в сторону. Есть у меня функция. Как я могу понять, что у меня все будет нормально работать, хватит стека данных?


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

Также неплохо, как уже посоветовал zltigo, забить область cstack/rstack 0xff при старте программы (только аккуратно, не полностью, чтобы не обрушить текущее содержимое стека sm.gif ), а во время исполнения смотреть, сколько места осталось

Цитата(demiurg1978 @ Sep 9 2015, 22:44) *
Покажите здесь криминал. Исходные данные: ATTINY13. 64 байта ОЗУ. Настройки CSTACK 0x20. RSTACK 8. Найдите криминал в листинге:


Вы ж примерно представляете, куда девается RAM? Глобальные переменные, статические переменные, CSTACK, RSTACK, куча (надеюсь, отключена?)

Судя по листингу, 25 байт - глобальные переменные. + 32 CSTACK + 8 RSTACK = 65. Сколько нужно CSTACK / RSTACK - компилятор может сказать очень примерно, ибо не знает, какие прерывания в каких местах могут сработать.

В map файл можно добавить анализ стека, покопайте в настройках

demiurg1978
Цитата(Непомнящий Евгений @ Sep 10 2015, 12:24) *
...

Евгений, спасибо за ответ. Теперь картина более-менее ясна.

Цитата(Dog Pawlowa @ Sep 10 2015, 06:51) *
...

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

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

Тема закрыта.
dxp
QUOTE (demiurg1978 @ Sep 9 2015, 20:46) *
Извините за такой вопрос, вы именно с AVR работаете? Это не подначка. Работу со стеком определяет компилятор. На стек я не могу повлиять.

Повлиять можете. Жёстко контролировать его расход компилятором - да, не можете, но это решается выделением размера стека с некоторым (обычно небольшим запасом). Но основное потребление стека всё-таки определяется вашей программой. Пример (пусть размер int на данной платформе 16 бит):
CODE
int a[100];

void f()
{
    int b[10];
    ...
}

int g()
{
    int c[20];
    
    f();

    ...
}


В этом примере массив 'a' выделяется в статической памяти, а массивы 'b' и 'c' - в т.н. автоматической или, другими словами, в стеке. Т.е. при вызове функции f() компилятор "откусит" в стеке 10*2 = 20 байт для размещения в нём массива 'b'. Аналогично, при вызове функции 'g' компилятор выделит в стеке 20*2 = 40 байт. Учитывая, что функция 'g' вызывает функцию 'f', суммарное потребление стека только под эти массивы может составить 20 + 40 = 60 байт. Но это при условии, что внутри функции 'f' время жизни массива 'b' длится дольше, чем наступит момент вызова функции 'g', иначе память, выделенная под массив 'b' к моменту вызова 'g' будет уже не нужна и может быть использована.

Как это реально будет происходить, зависит от реализации, т.е. поведения компилятора, оптимизации, плюс к этому ещё компилятор может сохранять (и так это обычно и происходит) часть регистров в стеке при вызовах (т.н. прологи/эпилоги функций) и т.д. Но вы всегда можете оценить максимально потребное количество памяти для стека и выделить так, чтобы хватило для ваших функций и "служебных" целей компилятора (их потребность можно оценить отдельно, посмотрев, что он передаёт через стек при вызовах функций, какие прологи/эпилоги, т.е. сколько регистров сохраняет в стеке и т.д.). И уже тут вы можете решить, сколько выделить памяти под стек. Если не хватает, то это повод и причина подумать, как и что изменить в программе - например, не заводить внутри функции локальных массивов, а использовать какой-нибудь другой приём для решения задачи. Компилятор не может охватить эту картину целиком, да и не его это задача. Тут только автор дизайна имеет полное представление и инструменты для руления. Немного опыта, и будете оценивать потребный размер стека на раз. sm.gif

Успехов!
Сергей Борщ
А ИАР при выводе расхода стека в листинг случайно не учитывает и расход стека вложенных функций? В этом случае стоит посмотреть расход стека функцией main() и добавить к нему самый большой расход стека из всех обработчиков прерываний. И все - "задача решена, землекопов - полтора". При условии, что в программе нет вызова функций по указателю - в этом случае компилятор навряд ли сможет учесть в вызывающей функции их расход стека.
demiurg1978
Цитата(Сергей Борщ @ Sep 11 2015, 12:51) *
...

Здравствуйте!
Код
__C_task main (void)


CODE

###############################################################################
# #
# IAR C/C++ Compiler V6.12.1.50500 for Atmel AVR 10/Sep/2015 13:15:22 #
# Copyright 1996-2012 IAR Systems AB. #
# #
# Source file = F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\main.c #
# Command line = F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\main.c #
# --cpu=tiny13 -mt -o F:\Work\Projects\ATMEL\IAR\C\TIMER_E #
# ASY\Debug\Obj\ -lC F:\Work\Projects\ATMEL\IAR\C\TIMER_EA #
# SY\Debug\List\ -lA F:\Work\Projects\ATMEL\IAR\C\TIMER_EA #
# SY\Debug\List\ --initializers_in_flash --debug #
# -DENABLE_BIT_DEFINITIONS -e --eeprom_size 64 --clib -Ohz #
# List file = F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\List\main. #
# lst #
# Object file = F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\Debug\Obj\main.r #
# 90 #
# #
# #
###############################################################################

F:\Work\Projects\ATMEL\IAR\C\TIMER_EASY\main.c
1 //========================================================================
2 #include "main_def_func.h" // Заголовочные файлы, глобальные определения, общие функции.
3 //========================================================================
4
5 //========================================================================

\ In segment CODE, align 2, keep-with-next
6 __C_task main (void)
\ main:
7 {
8 wdt_enable (WDTO_15_MS);
\ 00000000 E000 LDI R16, 0
\ 00000002 .... RCALL wdt_enable
9
10 init_sys_timer ();
\ 00000004 .... RCALL init_sys_timer
11
12 __enable_interrupt ();
\ 00000006 9478 SEI
13
14 Init_Events ();
\ 00000008 .... RCALL Init_Events
15
16 while (1)
17 {
18 __watchdog_reset ();
\ ??main_0:
\ 0000000A 95A8 WDR
19
20 service_timers ();
\ 0000000C .... RCALL service_timers
21
22 kbd_drv (); // Обработка кнопки.
\ 0000000E .... RCALL kbd_drv
23
24 proc_timer (); // Таймер.
\ 00000010 .... RCALL proc_timer
25
26 Process_Events ();
\ 00000012 .... RCALL Process_Events
\ 00000014 CFFA RJMP ??main_0
27 }
28 }
29 //========================================================================

Maximum stack usage in bytes:

CSTACK RSTACK Function
------ ------ --------
0 2 main
0 2 -> Init_Events
0 2 -> Process_Events
0 2 -> init_sys_timer
0 2 -> kbd_drv
0 2 -> proc_timer
0 2 -> service_timers
0 2 -> wdt_enable


Segment part sizes:

Bytes Function/Label
----- --------------
22 main


22 bytes in segment CODE

22 bytes of CODE memory

Errors: none
Warnings: none

Непомнящий Евгений
Цитата(Сергей Борщ @ Sep 11 2015, 08:51) *
А ИАР при выводе расхода стека в листинг случайно не учитывает и расход стека вложенных функций?


Учитывает, только в мап-файле, в разделе call graph. И надо какие-то галки поставить в настройках проекта
Сергей Борщ
Цитата(demiurg1978 @ Sep 11 2015, 09:07) *
Здравствуйте!
Код
__C_task main (void)
Это что? Типа "Дал г-на, дай и ложку"? Вы предлагаете мне за вас почитать ваш листниг, а потом посоветовать в какую-нибудь из функций добавить расходующий стек код и сравнить? Или выводы тоже нам озвучивать придется?
esaulenka
Цитата(Сергей Борщ @ Sep 11 2015, 08:51) *
А ИАР при выводе расхода стека в листинг случайно не учитывает и расход стека вложенных функций? В этом случае стоит посмотреть расход стека функцией main() и добавить к нему самый большой расход стека из всех обработчиков прерываний. И все - "задача решена, землекопов - полтора".


Учитывает, и пишет во вполне читаемом виде.



У меня чуть другой вопрос к общественности. Какая-нибудь утилита для gcc есть, чтобы вот это
Код
CFwUpdData.cpp:16:1:CFwUpdData::CFwUpdData()    0    static
CFwUpdData.cpp:42:34:static const CFwUpdData::TFirmwareHdr* CFwUpdData::GetHdrPtr()    0    static
CFwUpdData.cpp:23:6:static bool CFwUpdData::CheckUpdData()    16    static
CFwUpdData.cpp:48:6:bool CFwUpdData::WriteHdr(const CFwUpdData::TFirmwareHdr*)    8    static
CFwUpdData.cpp:55:17:static const uint8_t* CFwUpdData::GetDataPtr()    0    static
CFwUpdData.cpp:63:6:bool CFwUpdData::WriteData(const void*, uint32_t)    24    static
CFwUpdData.cpp:86:6:static bool CFwUpdData::Erase()    8    static
CFwUpdData.cpp:101:6:static bool CFwUpdData::CopyFw()    24    static

и табличку вызовов в единое целое связать?
demiurg1978
Цитата(Сергей Борщ @ Sep 11 2015, 14:01) *
...

main не вызывается. Соответственно, стек main не использует.
Сергей Борщ
Цитата(demiurg1978 @ Sep 11 2015, 10:04) *
main не вызывается. Соответственно, стек main не использует.
Это из серии "Крокодилы не летают, поэтому они зеленые"? Какая связь между использованием стека и вызовом main? Кстати, если вы просмотрите полный листинг вашей программы начиная от вектора сброса - вы увидите, что main таки вызывается... из cstartup.

Возможно возникло некоторое недопонимание: меня интересовало, учитывается ли в листинге main расход стека остальных вызываемых из main функций. По логике должен.
demiurg1978
Цитата(Сергей Борщ @ Sep 11 2015, 14:21) *
main таки вызывается

Хм, действительно. Только что посмотрел. Я как-то увидел этот способ, и мне тогда объяснили, что __C_task для того, чтобы не вызывать main а переход на него. Можно ли в IAR сделать так, или это противоречит стандартам Си? И можно ли функции в main таким же макаром сделать?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.