kochevkv 0 22 декабря, 2015 Опубликовано 22 декабря, 2015 · Жалоба Пишем программу для нового прибора. Коллега создает вот такие структуры: typedef struct { REC_HEADER Header; WORD NoPT; WORD NoPL; WORD NoAD; WORD StationID; WORD ModelID; WORD ManufactID; char Ident[9]; char Descript[41]; WORD StatTime; WORD NoFR; WORD NoRT; WORD NoBL; BYTE NoKY; BYTE NoPR; BYTE UnitsCal[7]; float Units0dB[7]; char KeyId[3][5]; char KeyDescr[3][41]; BYTE KeyGrade[3]; float Factor[3]; BYTE KeyTStamp[3][8]; float KeyNom[3]; float RPM[3]; char KeyNotes[3][241]; char PrId[12][9]; char PrDescr[12][41]; char Units[12][7]; BYTE PrGrade[12]; BYTE PrTStamp[12][8]; float PrNom[12]; float PrVal[12]; char PrNotes[12][241]; } RTN; и вот в таком вот месте программа "виснет" void make_TA(void) { BYTE get_status(BYTE); RTN train=TRAIN; // ТУТ ЗАВИСАЕТ Увеличил размер стека и все заработало. Был 3кБ сделал 10кБ. Правда, из SCRTACHPAD пришлось перенести в L1 из-за размера. Контроллер Blackfin BF-548. Теперь вопросы: 1. Как вы контролируете переполнение стека? 2. Какой размер считаете оптимальным? 3. В какой памяти его лучше располагать? 4. Как реально происходит приравнивание структур? Это спрятанное от глаз memcpy? И используется ли при этом динамическое выделение памяти? 5. Мириться ли с тем, что коллега создает такие огромные структуры или надо сменить подход? Можно ли их располагать в функции или лучше глобально? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 22 декабря, 2015 Опубликовано 22 декабря, 2015 · Жалоба 1) Заполнением стека константой перед запуском программы и проверкой, что наверху стека осталось какое-то количество ячеек с этой незатертой константой. Работает не всегда, но чаще всего работает. 2) Достаточный. 4) Да, memcpy. Нет, куча не используется. А зачем она могла бы при этом понадобиться? 5) Если нужна именно такая структура, то что вы тут сможете поменять? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
quarter 1 22 декабря, 2015 Опубликовано 22 декабря, 2015 · Жалоба при вызове Си-шной функции все параметры, которые получает и возвращает функция, передаются через стек. если не побоитесь, то можно работать с указателями на эти структуры, тогда лишнего копирования можно избежать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kochevkv 0 22 декабря, 2015 Опубликовано 22 декабря, 2015 · Жалоба 4) Да, memcpy. Нет, куча не используется. А зачем она могла бы при этом понадобиться? Не знаю. Подумал, может создается копия, а потом копируется для случая memcpy с перекрывающимися областями памяти. 5) Если нужна именно такая структура, то что вы тут сможете поменять? Ну как-то сделать свою часть программы такой, чтобы не было таких огромных локальных переменных. Пусть они будут, но не локальными переменными же. Если подойти к этому с размахом то там и мегабайтные маассивы начнут локально объявлять. Так никакого стека не хватит. А про размер - ну просто из опыта работы. Какой делали максимальным на приборе с МК такого класса и 32-64 МБ ОЗУ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 22 декабря, 2015 Опубликовано 22 декабря, 2015 · Жалоба А про размер - ну просто из опыта работы. Какой делали максимальным на приборе с МК такого класса и 32-64 МБ ОЗУ А что у вас за прибор? Стек он в дивайсах с реальным временем на вес золота. Ибо организуется в быстрой внутренней RAM, даже TCM RAM. А все такие структуры сносятся в медленную внешнюю RAM в heap. Имея такие ресурсы как у вас всегда применяют RTOS. А у развитых RTOS всегда есть механизмы наблюдения за стеком. Причем в реальном времени. У меня даже на платах с 128 МБ памяти стек задач никогда не превышал 5 Кб. Если нужно больше, то это уже какие-то проблемы с софтом. Только когда речь шла о слишком замороченном стороннем софте например задачах клиентских сессий со встроенным WEB сервером стек увеличивал до 10 кб. А коллегу вашего надо переучивать. Факт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 199 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба 1. Как вы контролируете переполнение стека? 2. Какой размер считаете оптимальным? 3. В какой памяти его лучше располагать? 4. Как реально происходит приравнивание структур? Это спрятанное от глаз memcpy? И используется ли при этом динамическое выделение памяти? 5. Мириться ли с тем, что коллега создает такие огромные структуры или надо сменить подход? Можно ли их располагать в функции или лучше глобально? 5. Коллеге за такое в embedded без внешней памяти, надо не просто по рукам бить, а ампутировать их. Лучше не данные, а коллегу расположить где-нить в вынь-программинге. 2. Оптимальных размеров стека нет, есть необходимые. 1. Контроль - заполнением шаблоном. 3. Лучше внутренней, особенно касаемо DSP с его огромными контекстами. 4. Согласно языка си: поэлементно. Распределение памяти и инициализация - вещи суть разные и почти несвязанные. при вызове Си-шной функции все параметры, которые получает и возвращает функция, передаются через стек. ложь. Стек он в дивайсах с реальным временем на вес золота. Ибо организуется в быстрой внутренней RAM, даже TCM RAM. В принципе можно и во внешней памяти стек располагать, даже на устройствах где есть жёсткий реалтайм. Всё зависит от требуемого быстродействия данной задачи ОС и архитектуры CPU. Если архитектура такова, что при возникновении прерывания контекст сохраняется на другом стеке (как на Cortex) или вообще не сохраняется (как в ARM TDMI), то стек некоей медленной задачи расположенный во внешней ОЗУ никак не затормозит ISR, но может затормозить переключение контекста данной медленной задачи ОС. Как обстоит дело с сохранением контекста в Блэкфинах я не знаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба void make_TA(void){ RTN train=TRAIN; // ТУТ ЗАВИСАЕТ у вас в стеке создается копия статической или глобальной структуры. Лучше использовать указатель void make_TA(RTN* train){ train->NoPt = ...; или ссылку, если это С++ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SlavaV 0 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба Вообще конструкция тип НовыйОбъект = Объект говорит создать временный объект типа "тип" (вот он видимо и создаётся на стеке) и скопировать его в НовыйОбъект (именно скопировать, если не перегружен оператор= происходит почленное копирование) PS это утверждение верно для С++ так как там структуры и классы одна сущность только с разными свойствами по умолчанию Другого использование стека в приведённом коде я не вижу PPS все функции работы с памятью memcpy malloc работают с кучей Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба PPS все функции работы с памятью memcpy malloc работают с кучей А это не закон. Как в программе переопределено так и будет. Скажем RTOS-ы сразу переопределяют эти функции. А там у кого как, у кого куча, а у кого и много куч. Но все со своими оригинальными движками. Кстати не додумал, но коллега действительно мог использовать стек именно для ускорения своей процедуры. Либо вообще копипастить из среды моделирования один в один. Тогда это оправдано и придираться к нему нельзя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 199 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба Вообще конструкция тип НовыйОбъект = Объект говорит создать временный объект типа "тип" (вот он видимо и создаётся на стеке) и скопировать его в НовыйОбъект (именно скопировать, если не перегружен оператор= происходит почленное копирование) Не обязательно. Если TRAIN - имеет тип RTN и перегружен оператор присваивания: RTN & RTN::operator =(RTN &); то (имхо) компилятор сделает вызов конструктора по умолчанию RTN::RTN(), а затем для созданного объекта вызовет этот перегруженный оператор присваивания: train(TRAIN) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SlavaV 0 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба Не обязательно. Если TRAIN - имеет тип RTN и перегружен оператор присваивания: RTN & RTN::operator =(RTN &); то (имхо) компилятор сделает вызов конструктора по умолчанию RTN::RTN(), а затем для созданного объекта вызовет этот перегруженный оператор присваивания: train(TRAIN) вот этот объект и создаётся на стеке (вернее в автоматической памяти, а она обычно на стеке) здесь можно обойтись без стека (автоматической памяти) Вы правильно сказали используя конструктор, но в коде нет этого, да и вопрос был почему не работает, а не как сделать чтоб работало Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kochevkv 0 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба ... Имея такие ресурсы как у вас всегда применяют RTOS. А у развитых RTOS всегда есть механизмы наблюдения за стеком. ... Решили не использовать, т.к. задача одна, а библиотека драйверов наличия ОС не требует. Забыл упомянуть - пишем на СИ без плюсов. ... Кстати не додумал, но коллега действительно мог использовать стек именно для ускорения своей процедуры. Либо вообще копипастить из среды моделирования один в один. Тогда это оправдано и придираться к нему нельзя. Не думаю, что для ускорения. Пишет под WIN32, потом передает мне те части, которые платформо-независимы Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба у вас в стеке создается копия статической или глобальной структуры. Лучше использовать указательКому лучше? Если там создается копия - наверное программисту нужна именно копия, он хочет ее менять, а содержимое оригинала потом потребуется в другом месте. А если можно работать с содержимым оригинальной струкьтуры, то и в этом случае указатель не нужен - можно работать прямо с самой структурой. PPS все функции работы с памятью memcpy malloc работают с кучейКаким местом memcpy связан с кучей? Вы правильно сказали - используя конструктор,Судя по "typedef struct" там голый Си, без плюсов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба Не думаю, что для ускорения. Пишет под WIN32, потом передает мне те части, которые платформо-независимы Ну так бы сразу и сказали. А то вводите публику в заблуждение. В Win32 он может писать как ему вздумается, и ничего ему за это не будет. Вы портируете эти куски, вы и отвечаете за стек. Просто портировать лень, да? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 199 23 декабря, 2015 Опубликовано 23 декабря, 2015 · Жалоба Судя по "typedef struct" там голый Си, без плюсов. Никто не мешает использовать "typedef struct" под с++. В Win32 он может писать как ему вздумается, и ничего ему за это не будет. Вы портируете эти куски, вы и отвечаете за стек. Именно так, согласен. Я сразу и написал, что это виндузятный подход, а не ембеддед. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться