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

 
 
> перезапуск программы, непонятно почему.
simsim
сообщение Jan 16 2007, 21:13
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 45
Регистрация: 30-10-06
Пользователь №: 21 801



есть программа, состоит из 2-х подпрограмм А и Б, выполняемых бесконечно в while (1) {} и real-time clock по timer0.
1-я выводит массив led[32] в порт D, 2-я обновляет led[32]. Проблема - два раза цикл вывода и обновления led[32] проходит нормально, в начале 3-го происходит перезапуск контроллера, замечаю по обнулению времени и led. watchdog выключен, да и время до сброса не одно, зависит от времени выполнения циклов в А и Б, и 2 сек, и 15 сек и больше, а происходит в одной и той же точке выполнения А и Б. в чем может быть дело ? как уйти от этого сброса ?
p.s. попробую отследить в AVR Studio, поможет ? там вроде нет шагов назад.

Сообщение отредактировал simsim - Jan 16 2007, 21:17
Go to the top of the page
 
+Quote Post
5 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 60)
bodja74
сообщение Jan 16 2007, 21:33
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



SREG и регистры сохраняются в прерывании ?
Go to the top of the page
 
+Quote Post
simsim
сообщение Jan 16 2007, 21:43
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 45
Регистрация: 30-10-06
Пользователь №: 21 801



Цитата(bodja74 @ Jan 16 2007, 21:33) *
SREG и регистры сохраняются в прерывании ?

Прога на СИ. специально не забочусь о них.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 16 2007, 23:13
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(simsim @ Jan 16 2007, 22:13) *
p.s. попробую отследить в AVR Studio, поможет ? там вроде нет шагов назад.


Конечно поможет. А зачем шаги назад?
Go to the top of the page
 
+Quote Post
GDI
сообщение Jan 17 2007, 12:42
Сообщение #5


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Индексы массивов не выходят ли за границы оных, стек не переполняется? Какой компилятор? Да может и исходник бы здесь тоже не помешал..


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
_Bill
сообщение Jan 17 2007, 13:04
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(simsim @ Jan 16 2007, 21:13) *
есть программа, состоит из 2-х подпрограмм А и Б, выполняемых бесконечно в while (1) {} и real-time clock по timer0.
1-я выводит массив led[32] в порт D, 2-я обновляет led[32]. Проблема - два раза цикл вывода и обновления led[32] проходит нормально, в начале 3-го происходит перезапуск контроллера, замечаю по обнулению времени и led. watchdog выключен, да и время до сброса не одно, зависит от времени выполнения циклов в А и Б, и 2 сек, и 15 сек и больше, а происходит в одной и той же точке выполнения А и Б. в чем может быть дело ? как уйти от этого сброса ?
p.s. попробую отследить в AVR Studio, поможет ? там вроде нет шагов назад.

Код в Студию!!!
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 17 2007, 13:41
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(simsim @ Jan 17 2007, 01:13) *
есть программа, состоит из 2-х подпрограмм А и Б, выполняемых бесконечно в while (1) {} и real-time clock по timer0.
1-я выводит массив led[32] в порт D, 2-я обновляет led[32]. Проблема - два раза цикл вывода и обновления led[32] проходит нормально, в начале 3-го происходит перезапуск контроллера, замечаю по обнулению времени и led. watchdog выключен, да и время до сброса не одно, зависит от времени выполнения циклов в А и Б, и 2 сек, и 15 сек и больше, а происходит в одной и той же точке выполнения А и Б. в чем может быть дело ? как уйти от этого сброса ?
p.s. попробую отследить в AVR Studio, поможет ? там вроде нет шагов назад.
Возможно, из за переполнения стека данных, реомендую увеличить в два раза. Если пользуетесь ИАРом, то по умолчанию глубина стека данных равна 0x20 (или 32 - ИМХО для того, чтобы можно было, при входе впрерывание, сохранить все 32 регистра). Если какая то процедура в программе, кроме прерывания пользуется стеком данных, естественно, он переполнится, и корабль потонет smile.gif

Поменять значение можно в Главное меню->Project->Options->General Options->System->Data Stack (RSTACK)


--------------------
Go to the top of the page
 
+Quote Post
vesago
сообщение Jan 17 2007, 17:05
Сообщение #8


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Согласен с GDI 9:10 - криво проинициализировали индекс или выходит за пределы. У меня такое бывало. Проц тогда постоянно перегружается.
Go to the top of the page
 
+Quote Post
simsim
сообщение Jan 17 2007, 17:46
Сообщение #9


Участник
*

Группа: Новичок
Сообщений: 45
Регистрация: 30-10-06
Пользователь №: 21 801



Цитата(GDI @ Jan 17 2007, 12:42) *
Индексы массивов не выходят ли за границы оных, стек не переполняется? Какой компилятор? Да может и исходник бы здесь тоже не помешал..

Компилятор CodeVisionAVR 1.24.8, индексы в порядке, потому что два раза проходит нормально, а на третий выполняя то же самое перезапускается. Размер стека 256 байт, неужели мало? Что такое HEAP SIZE в настройках CVAVR ?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 17 2007, 18:02
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(simsim @ Jan 17 2007, 21:46) *
Цитата(GDI @ Jan 17 2007, 12:42) *

Индексы массивов не выходят ли за границы оных, стек не переполняется? Какой компилятор? Да может и исходник бы здесь тоже не помешал..

Компилятор CodeVisionAVR 1.24.8, индексы в порядке, потому что два раза проходит нормально, а на третий выполняя то же самое перезапускается. Размер стека 256 байт, неужели мало? Что такое HEAP SIZE в настройках CVAVR ?
Я не пользовал CodeVisionAVR, но для ИАРа есть два стека - первый стек данных, второй - стек программ. Первый нужен для сохранения переменных, расположенных в регистрах, второй служит для выхода из подпрограмм.

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

Допустим Вы объявили массив, как глобальную переменную - он будет создан не в куче, а на этапе запуска стартап-кода.

Если же массив будет объявлен внутри функции, то, возможно, он будет создаваться динамически, во время выполнения функции, как раз в этой самой куче.


--------------------
Go to the top of the page
 
+Quote Post
simsim
сообщение Jan 17 2007, 19:00
Сообщение #11


Участник
*

Группа: Новичок
Сообщений: 45
Регистрация: 30-10-06
Пользователь №: 21 801



Цитата(simsim @ Jan 17 2007, 17:46) *
Цитата(GDI @ Jan 17 2007, 12:42) *

Индексы массивов не выходят ли за границы оных, стек не переполняется? Какой компилятор? Да может и исходник бы здесь тоже не помешал..

Компилятор CodeVisionAVR 1.24.8, индексы в порядке, потому что два раза проходит нормально, а на третий выполняя то же самое перезапускается. Размер стека 256 байт, неужели мало? Что такое HEAP SIZE в настройках CVAVR ?

Увеличил стек до 500. Теперь перезапускается после 5-го обновления массива leds, а не 3-го как раньше. В подпрограмме обновления leds есть обращение к ассемблерной подпрограмме -
#pragma warn- // this will prevent warnings
unsigned char asm_font(unsigned char aa1, unsigned char bb1) {
#asm
.def temp =r16
.def zh =r31
.def zl =r30
.def ak =r23
.def bk =r24
.def yh =r29
.def yl =r28
..................
lpm r30,z ; результат
ret
#endasm
}
#pragma warn+ // enable warnings
Может здесь причина?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 17 2007, 19:10
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(prottoss @ Jan 17 2007, 19:02) *
Допустим Вы объявили массив, как глобальную переменную - он будет создан не в куче, а на этапе запуска стартап-кода.

Если же массив будет объявлен внутри функции, то, возможно, он будет создаваться динамически, во время выполнения функции, как раз в этой самой куче.


Для IAR даже если массив объявлен внутри ф-ции, то он всё равно будет создан "на этапе запуска стартап-кода". Даже если он и будет создан динамически (не программистом а компилятором), то он будет создан за счёт памяти выделенной под это на этапе линковки. А куча полностью предоставлена программисту. (Как в С++ не знаю). Я могу выделить память и освободить её. М/у моими действиями ничего происходить с кучей не должно. Ничего без моего участия.
Таким образом учитывая, что парень не слышал о таком слове smile.gif - куча не занята, и она явно к этому не имеет никакого отношения.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 17 2007, 19:25
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(SasaVitebsk @ Jan 17 2007, 23:10) *
Цитата(prottoss @ Jan 17 2007, 19:02) *

Допустим Вы объявили массив, как глобальную переменную - он будет создан не в куче, а на этапе запуска стартап-кода.

Если же массив будет объявлен внутри функции, то, возможно, он будет создаваться динамически, во время выполнения функции, как раз в этой самой куче.


Для IAR даже если массив объявлен внутри ф-ции, то он всё равно будет создан "на этапе запуска стартап-кода".
А я Вам говорю, что в куче, давайте поспорим smile.gif Ваши аргументы какие?


--------------------
Go to the top of the page
 
+Quote Post
GDI
сообщение Jan 17 2007, 19:32
Сообщение #14


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата
индексы в порядке, потому что два раза проходит нормально


это ничего не значит...

Цитата
Теперь перезапускается после 5-го обновления массива leds


...и это тому подтверждение

Цитата
#pragma warn- // this will prevent warnings
unsigned char asm_font(unsigned char aa1, unsigned char bb1) {
#asm
.def temp =r16
.def zh =r31
.def zl =r30
.def ak =r23
.def bk =r24
.def yh =r29
.def yl =r28
..................
lpm r30,z ; результат
ret
#endasm
}
#pragma warn+ // enable warnings


Что то я не вижу сохранение в стеке используемых регистров и, соответственно, последующего их восстановления, вполне может быть, что проблема в этом. А что показала проверка в AVR Studio?


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
simsim
сообщение Jan 17 2007, 19:35
Сообщение #15


Участник
*

Группа: Новичок
Сообщений: 45
Регистрация: 30-10-06
Пользователь №: 21 801



Для IAR даже если массив объявлен внутри ф-ции, то он всё равно будет создан "на этапе запуска стартап-кода". [/quote] А я Вам говорю, что в куче, давайте поспорим smile.gif Ваши аргументы какие?
[/quote]
Куча в нуле. Пробовал делать ее 100 - безрезультатно. Похоже что стек выбивает. AVR написала что "AVR Simulator: Stack pointer changed after subroutine call", не заметил после какой, долго идет симуляция, похоже после asm_font()
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 17 2007, 19:36
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(simsim @ Jan 17 2007, 20:00) *
Цитата(simsim @ Jan 17 2007, 17:46) *

Цитата(GDI @ Jan 17 2007, 12:42) *

Индексы массивов не выходят ли за границы оных, стек не переполняется? Какой компилятор? Да может и исходник бы здесь тоже не помешал..

Компилятор CodeVisionAVR 1.24.8, индексы в порядке, потому что два раза проходит нормально, а на третий выполняя то же самое перезапускается. Размер стека 256 байт, неужели мало? Что такое HEAP SIZE в настройках CVAVR ?

Увеличил стек до 500. Теперь перезапускается после 5-го обновления массива leds, а не 3-го как раньше. В подпрограмме обновления leds есть обращение к ассемблерной подпрограмме -
#pragma warn- // this will prevent warnings
unsigned char asm_font(unsigned char aa1, unsigned char bb1) {
#asm
.def temp =r16
.def zh =r31
.def zl =r30
.def ak =r23
.def bk =r24
.def yh =r29
.def yl =r28
..................
lpm r30,z ; результат
ret
#endasm
}
#pragma warn+ // enable warnings
Может здесь причина?

Если у Вас зависит от числа вызывов, то это однозначно указывает, что у Вас плывёт указатель стэка. Одного или другого.
Зачем Вы замыливаете причину??? Просто найдите и устраните! Как собирались. Верните всё как было (всё таки два цикла меньше чем 5 гнать) и прогоните в Studio. Обратите внимание на указатель стэка в одном и том же месте.

Теперь вопрос 2. Зачем Вы путаете Си и Asm если Вы ещё в самом начале пути??? Вы уверены что регистры которые Вы портите в Asm не использует компилятор??? Простите, но для меня Ваша прога, просто лишена смысла. Как можно результат занести в регистр? И что? А если при следующей компиляции компилятор поменяет использование регистров??? Это же его право! Я понимаю ещё если бы Вы с переменной работали, а используемые регистры сохраняли. И то! Зачем Вам вообще это. Используйте чистый Си. Я уверен, - то что Вы хотите сделать на Asm можно реализовать и в рамках языка! Просто спросите в форуме - как это сделать.

Приведу пример. В начале своего последнего проекта, я хотел делать ассемблерные п/п. Чтобы ускорить работу в некоторых местах. Но решил сделать это после отладки проекта. А, сначала, всё реализовать на Си. Теперь проект закончен. И, наверное я уже просто не буду этим заниматься. У меня просто банально всё работает. Производительность отличная. Так зачем этот цирк?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 17 2007, 19:38
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(simsim @ Jan 17 2007, 23:00) *
В подпрограмме обновления leds есть обращение к ассемблерной подпрограмме ...

Может здесь причина?
С этого и надо было начинать. А весь код то посмотреть мона?


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 17 2007, 20:14
Сообщение #18


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Чтобы все не спорили. Массивы, объявленные внутри функции(локальные), равно как и локальные переменные, и в С и в С++ размещаются на стеке. В ИАРе на стеке данных (CSTACK). В куче в С++ размещаются объекты созданные через вызов operator new. В "голом" С в куче "само" не размещается ничего. Программист может зарезервировать себе кусочек памяти в куче библиотечными функциями malloc, calloc и в этот кусочек разместить что захочет. Иначе никак.

Цитата(SasaVitebsk @ Jan 17 2007, 18:36) *
Как можно результат занести в регистр? И что? А если при следующей компиляции компилятор поменяет использование регистров??? Это же его право!
В защиту автора функции: В данном случае речь идет о CV, а он использует именно R30:R31 для передачи параметров и возврата значений. Это описано в его доке и просто так не поменяется.

Цитата(SasaVitebsk @ Jan 17 2007, 18:36) *
Приведу пример. В начале своего последнего проекта, я хотел делать ассемблерные п/п. Чтобы ускорить работу в некоторых местах. Но решил сделать это после отладки проекта. А, сначала, всё реализовать на Си. Теперь проект закончен. И, наверное я уже просто не буду этим заниматься. У меня просто банально всё работает. Производительность отличная. Так зачем этот цирк?
Вот тут полностью согласен. Но если автор настаивает, то можно порекомендовать вместо этой функции вставить затычку, типа такой:
Код
unsigned char pass;
unsigned char asm_font(unsigned char aa1, unsigned char bb1) {
    return ++pass;
}
и посмотреть как будет работать. Если вешаться перестанет, то написать простую программу:
Код
void main() {
    for(;;)
        asm_font(1,2);
}
и прогнать ее в avrstudio, обращая внимание на стек, на изменяющуюся память, на регистры. А можно и сюда текст функции выложить - коллективом ошибки ловятся быстрее.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AndryG
сообщение Jan 17 2007, 20:21
Сообщение #19


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

Группа: Свой
Сообщений: 139
Регистрация: 23-05-05
Из: UA
Пользователь №: 5 317



Не вчитывался в посты народа ... звыняйте .. в АСМ-вставке Вы используете R30 - в CVAVR - это самый главный регистр - указатель стека!!! Вот с ним Вы беду и делаете.
Если Ваша вставка - функция - подавно все развалится - прочтите раздел хелпа по функциям асемблерным - там указано что и как сохранять на примере кода.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 17 2007, 20:27
Сообщение #20


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(prottoss @ Jan 17 2007, 19:25) *
Цитата(SasaVitebsk @ Jan 17 2007, 23:10) *
[quote name='prottoss' Если же
Для IAR даже если массив объявлен внутри ф-ции, то он всё равно будет создан "на этапе запуска стартап-кода".
А я Вам говорю, что в куче, давайте поспорим smile.gif Ваши аргументы какие?

Вы оба неправы smile.gif
Если массив объявлен внутри функции, место для него будет выделено в CSTACK
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Jan 17 2007, 20:37
Сообщение #21


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(AndryG @ Jan 17 2007, 20:21) *
Не вчитывался в посты народа ... звыняйте .. в АСМ-вставке Вы используете R30 - в CVAVR - это самый главный регистр - указатель стека!!! Вот с ним Вы беду и делаете.
Если Ваша вставка - функция - подавно все развалится - прочтите раздел хелпа по функциям асемблерным - там указано что и как сохранять на примере кода.

Цитата из хелпа CV -
"The registers R0, R1, R22, R23, R24, R25, R26, R27, R30 and R31 can be freely used in assembly routines."
R30,R31 используются для возврата результата функции. Указатель стека - R28,R29.
Go to the top of the page
 
+Quote Post
simsim
сообщение Jan 17 2007, 21:06
Сообщение #22


Участник
*

Группа: Новичок
Сообщений: 45
Регистрация: 30-10-06
Пользователь №: 21 801



Заменил ассемблерную функцию на СИ-шную
unsigned char asm_font(unsigned char aa1, unsigned char bb1)
{ unsigned int tp;
tp=(aa1*8)+bb1;
return font8[tp];
}
но теперь другая проблема- при отладке в AVR Studio аа1=207, tp получается равным 121 !!! не поддается осмыслению ...
p.s. ОТ перезапуска избавился.спасибо.

Сообщение отредактировал simsim - Jan 17 2007, 21:08
Go to the top of the page
 
+Quote Post
simsim
сообщение Jan 17 2007, 21:35
Сообщение #23


Участник
*

Группа: Новичок
Сообщений: 45
Регистрация: 30-10-06
Пользователь №: 21 801



Цитата(simsim @ Jan 17 2007, 21:06) *
Заменил ассемблерную функцию на СИ-шную
unsigned char asm_font(unsigned char aa1, unsigned char bb1)
{ unsigned int tp;
tp=(aa1*8)+bb1;
return font8[tp];
}
но теперь другая проблема- при отладке в AVR Studio аа1=207, tp получается равным 121 !!! не поддается осмыслению ...
p.s. ОТ перезапуска избавился.спасибо.

Спасибо, нашел - tp=aa1; tp*=8; tp+=bb1; (СИ это вам не математика :-)
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 18 2007, 00:49
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(SasaVitebsk @ Jan 17 2007, 20:10) *
Для IAR даже если массив объявлен внутри ф-ции, то он всё равно будет создан "на этапе запуска стартап-кода". Даже если он и будет создан динамически (не программистом а компилятором), то он будет создан за счёт памяти выделенной под это на этапе линковки. А куча полностью предоставлена программисту. (Как в С++ не знаю). Я могу выделить память и освободить её. М/у моими действиями ничего происходить с кучей не должно. Ничего без моего участия.
Таким образом учитывая, что парень не слышал о таком слове smile.gif - куча не занята, и она явно к этому не имеет никакого отношения.


2 defunct поясни пожалуйста, что я сказал неправильно. Я не для спора, а для своего понимания. Смею предположить, что неверна лишь выдержка из поста Prottoss "на этапе запуска стартап-кода". Но я её просто как выдержку привёл, а имелл ввиду что сама прога полностью сгенерирована к моменту запуска. И место под переменные уже выделены. Это так не только в Си. С динамической памятью работать приходилось. Посмотри пожалуйста следующую за вырванной фразу. Я пишу, "Даже если он и будет создан динамически (не программистом а компилятором), то он будет создан за счёт памяти выделенной под это на этапе линковки." То есть я как раз и описываю этот вариант. В моём сообщении не это главное. Опишу чуть ниже.

2 Сергей Борщ по поводу первого раздела, именно это я и хотел сказать но у меня не получилось. smile.gif Но я говорю немного уклончиво потому, что полностью компилятор не знает никто кроме разработчиков, а в полной мере проверить не удаётся. А в документах, можно кое что упустить. Пример специально для Вас Сергей Борщ. smile.gif В библиотеках которые я выкладывал по поводу 18b20 применено динамическое распределение памяти. И там же использован массив локальный. приведу текст для понимания.
Код
//Чтение температуры
int8_t    read_scratchpad(uint8_t tip)
{
uint8_t    scratchpad[8];
uint8_t    crc    = 0;

OW_write_byte(READ_SCRATCHPAD);                // читаем scratchpad 0xBE
for    (uint8_t c1    = 0; c1    < 8; c1++)
{
    scratchpad[c1] = OW_read_byte();            // Принять данные с    1 Wire шины
    crc    =  OW_crc8(crc, scratchpad[c1]);        // Посчитать CRC8  для 1 Wire шины
}
crc=OW_crc8(crc, OW_read_byte());
OW_reset();
if (crc == 0)                                    // Проверить CRC8  для 1 Wire шины
{
   if(tip==DS18B20TIP)
     return ((scratchpad[1] << 4) | ((scratchpad[0]+8) >> 4));
   else    
     return ((scratchpad[1] & 0x80) |    ((scratchpad[0]+1) >> 1));
}
else return ( ERROR_CRC);                        // Message -80
}

Возможно Вы будете удивлены, но IAR данный массив размещает в регистрах. (Оптимизирует)


2 defunct. Главное, о чём я писал в своём сообщении, что если бы компилятор произвольно использовал бы кучу, то как с ней работать? А если я её освобождаю ниже занятого уровня? Я уверен, что она не занята. Потому, что мной она не занята. Он меня ещё может контролировать. Я его - нет. Поэтому я и высказал сомнение. Этого нет даже на PC.
Go to the top of the page
 
+Quote Post
Dan_Dima
сообщение Jan 18 2007, 03:43
Сообщение #25


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 18-01-07
Пользователь №: 24 530



Всем привет.
Я можнт что-то не понимаю скажите а разве между этими строками есть разница.
tp=(aa1*8)+bb1;
и
tp=aa1; tp*=8; tp+=bb1;
Go to the top of the page
 
+Quote Post
dimka76
сообщение Jan 18 2007, 08:27
Сообщение #26


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Цитата(Dan_Dima @ Jan 18 2007, 03:43) *
Всем привет.
Я можнт что-то не понимаю скажите а разве между этими строками есть разница.
tp=(aa1*8)+bb1;
и
tp=aa1; tp*=8; tp+=bb1;


aa1 объявлена как char и при умножении aa1*8 вероятно происходит переполнение,
а tp объявлена как int и при tp=aa1; tp*=8; так как tp это int переполнения не происходит. Сделай простую проверку, объяви aa1 как int и посмотри результат своего первого выражения tp = (aa1*8) + bb1;


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
satellite-plus
сообщение Jan 18 2007, 09:19
Сообщение #27


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-01-07
Из: Одесса
Пользователь №: 24 196



Цитата(Dan_Dima @ Jan 18 2007, 02:43) *
Всем привет.
Я можнт что-то не понимаю скажите а разве между этими строками есть разница.
tp=(aa1*8)+bb1;
и
tp=aa1; tp*=8; tp+=bb1;


tp=(int)aa1*8+bb1;


--------------------
Опыт - это та чудесная штука, которая позволяет вам узнать ошибку, когда вы ее повторите.
Go to the top of the page
 
+Quote Post
Dan_Dima
сообщение Jan 18 2007, 12:28
Сообщение #28


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 18-01-07
Пользователь №: 24 530



Цитата(dimka76 @ Jan 18 2007, 08:27) *
Цитата(Dan_Dima @ Jan 18 2007, 03:43) *

Всем привет.
Я можнт что-то не понимаю скажите а разве между этими строками есть разница.
tp=(aa1*8)+bb1;
и
tp=aa1; tp*=8; tp+=bb1;


aa1 объявлена как char и при умножении aa1*8 вероятно происходит переполнение,
а tp объявлена как int и при tp=aa1; tp*=8; так как tp это int переполнения не происходит. Сделай простую проверку, объяви aa1 как int и посмотри результат своего первого выражения tp = (aa1*8) + bb1;


Насколько я помню подобные преобразования компилятор делает сам ( только проверил) так как преобразование идет к "большему" типу. Поэтому эти две записи эквивалентны.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 18 2007, 13:00
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Dan_Dima @ Jan 18 2007, 13:28) *
Насколько я помню подобные преобразования компилятор делает сам ( только проверил) так как преобразование идет к "большему" типу. Поэтому эти две записи эквивалентны.

Конечно сам, но на каком этапе?
Отличие в записях в моменте преобразования.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
satellite-plus
сообщение Jan 18 2007, 13:25
Сообщение #30


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-01-07
Из: Одесса
Пользователь №: 24 196



Насколько я помню подобные преобразования компилятор делает сам ( только проверил) так как преобразование идет к "большему" типу. Поэтому эти две записи эквивалентны.
[/quote]

IAR компилятору все равно к какому типу вы приравниваете. Если в выражении берут участие 8-ми битные данные, то будет применена 8-ми битная арифметика. Для оптимизации программы. А за переполнением следите сами.


--------------------
Опыт - это та чудесная штука, которая позволяет вам узнать ошибку, когда вы ее повторите.
Go to the top of the page
 
+Quote Post
Dan_Dima
сообщение Jan 18 2007, 14:35
Сообщение #31


Участник
*

Группа: Новичок
Сообщений: 19
Регистрация: 18-01-07
Пользователь №: 24 530



Цитата(Dog Pawlowa @ Jan 18 2007, 13:00) *
Цитата(Dan_Dima @ Jan 18 2007, 13:28) *

Насколько я помню подобные преобразования компилятор делает сам ( только проверил) так как преобразование идет к "большему" типу. Поэтому эти две записи эквивалентны.

Конечно сам, но на каком этапе?
Отличие в записях в моменте преобразования.


Преобразование происходит по ходу выполнения вычислений если говорить о том как это делаеться в обычном С. В IAR может действительно надо принудительно описывать привидение типов в том же gcc такого нет.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 18 2007, 18:08
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Dan_Dima @ Jan 18 2007, 15:35) *
Преобразование происходит по ходу выполнения вычислений если говорить о том как это делаеться в обычном С.

В приведенной формуле tp=(aa1*8)+bb1 компилятор IAR хранит временные результаты вычисления (aa1*8) того же типа, что и aa1 и ничего не нарушает. Переполнение происходит, так как программист не учел, что оно может произойти, а не по той причине, что IAR - это не "обычный С".

Цитата(Dan_Dima @ Jan 18 2007, 15:35) *
В IAR может действительно надо принудительно описывать привидение типов в том же gcc такого нет.

GCC действительно по другому работает, чем IAR - сталкивался с этим. Но, подчеркиваю, разобранный пример - не свидетельство ненормальной работы IAR.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 18 2007, 18:56
Сообщение #33


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *
Но я говорю немного уклончиво потому, что полностью компилятор не знает никто кроме разработчиков, а в полной мере проверить не удаётся.
Для того и существуют стандарты, чтобы точно описывать "как оно должно быть","как оно не должно быть" и "а вот это хз". Последнее отдано на откуп разработчикам компиляторов. Не больше.
Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *
Пример специально для Вас Сергей Борщ. smile.gif В библиотеках которые я выкладывал по поводу 18b20 применено динамическое распределение памяти. И там же использован массив локальный.
Здесь вы путаетесь в терминах. В языке С динамическим распределением памяти называется именно работа с кучей. Локальные переменные, под которые память выделяется на стеке, в терминах С называются автоматическими. Переменные, под которые память выделяется на этапе запуска программы, называются статическими. К статическим относятся глобальные переменные и локальные переменные, объявленные с квалификатором static. В вашем примере динамического распределения я не увидел.
Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *
Возможно Вы будете удивлены, но IAR данный массив размещает в регистрах. (Оптимизирует)
Ненаказуемо smile.gif Но если вы попытаетесь взять адрес такой переменной и передать куда-либо указатель на нее, она сразу же из регистров окажется в памяти.

Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *
2 defunct. Главное, о чём я писал в своём сообщении, что если бы компилятор произвольно использовал бы кучу, то как с ней работать? А если я её освобождаю ниже занятого уровня? Я уверен, что она не занята. Потому, что мной она не занята. Он меня ещё может контролировать. Я его - нет.
я не defunct, но попытаюсь ответить: вы не можете "освободить ниже занятого уровня". Вы говорите сколько вам памяти надо, malloc выделяет в куче участок такого размера и выдает вам указатель на него. Этот участок в вашем полном распоряжении и никто на него не покусится. Когда вы хотите освободить этот участок - вы передаете free указатель на участок. Размер освобождаемого участка менеджер памяти определит сам. Повторное освобождение какого-либо участка - это ошибка в программе. Но ничего не мешает другой части программы (другой функции, задаче, другому потоку) получить из этой же кучи другой участок.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 18 2007, 19:40
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



defunct был прав - массив, объявленный в функции, создается не в куче, а в стеке данных (я говрю про ИАР). Проверил листинг ассемблера - все так и есть. Единственное, в чем я был прав - массив, объявленный в функции - создается динамически!!! Так что, ребята, учитывайте это при создании приложений для АВР на ИАР angry.gif .


--------------------
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 18 2007, 20:15
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(prottoss @ Jan 18 2007, 18:40) *
Единственное, в чем я был прав - массив, объявленный в функции - создается динамически!!!

Нет, не "динамически" а "автоматически" - Сергей уже обьяснял!!!
Цитата
Так что, ребята, учитывайте это при создании приложений для АВР на ИАР angry.gif .

Ни AVR, ни IAR здесь ни причем. "С", просто "С" стандартное поведение.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 18 2007, 20:39
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(zltigo @ Jan 19 2007, 00:15) *
Цитата(prottoss @ Jan 18 2007, 18:40) *

Единственное, в чем я был прав - массив, объявленный в функции - создается динамически!!!

Нет, не "динамически" а "автоматически" - Сергей уже обьяснял!!!
Цитата
Так что, ребята, учитывайте это при создании приложений для АВР на ИАР angry.gif .

Ни AVR, ни IAR здесь ни причем. "С", просто "С" стандартное поведение.


А в чем разница между "динамически" и "автоматически"???

1. Если уж говорить по русски - я считаю что "динамически" - это на этапе исполнения кода, а Вы о чем глаголите???

2. Про стандартное поведение Си согласен, здесь все четко


--------------------
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 18 2007, 21:15
Сообщение #37



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(Dan_Dima @ Jan 18 2007, 14:35) *
Цитата(Dog Pawlowa @ Jan 18 2007, 13:00) *

Цитата(Dan_Dima @ Jan 18 2007, 13:28) *

Насколько я помню подобные преобразования компилятор делает сам ( только проверил) так как преобразование идет к "большему" типу. Поэтому эти две записи эквивалентны.

Конечно сам, но на каком этапе?
Отличие в записях в моменте преобразования.

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

По стандарту все операнды с разрядностью, меньшей int, в целочисленных выражениях обрабатываются как int, и к разрядности lvalue приводится только результат. Обработка операндов с меньшей разрядностью без приведения к int - интимное дело оптимизатора. Для проверки можете посмотреть асм листинг без оптимизации.
Цитата(prottoss @ Jan 18 2007, 19:40) *
defunct был прав - массив, объявленный в функции, создается не в куче, а в стеке данных (я говрю про ИАР). Проверил листинг ассемблера - все так и есть.

И как следствие - задание соответствующего размера стека.
Цитата
Единственное, в чем я был прав - массив, объявленный в функции - создается динамически!!!

Как уже заметил Сергей Борщ, такие переменные называются автоматическими, и в полном соответствии со стандартом языка создаются при входе в функцию и уничтожаются при выходе из нее. По умолчанию размещаются на стеке, но при включенном оптимизаторе легко могут оказаться в регистрах.

PS: извините за невольный частичный повтор - писАлось больше часа, задергали звонками и неотложными проблемами.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 18 2007, 21:43
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Канешна, это все здорово очень, объясните тада, умные сотоварищи, зачем мне указывать размер стека данных, еслиФ все равно компилятор и иже с ними, создаст массив в этом самом стекеданных, то бишь нарушит мое НЕОСПОРИМОЕ правило???


--------------------
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 18 2007, 21:44
Сообщение #39



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(prottoss @ Jan 18 2007, 20:39) *
Цитата(zltigo @ Jan 19 2007, 00:15) *
Цитата(prottoss @ Jan 18 2007, 18:40) *

Единственное, в чем я был прав - массив, объявленный в функции - создается динамически!!!

Нет, не "динамически" а "автоматически" - Сергей уже обьяснял!!!
Цитата
Так что, ребята, учитывайте это при создании приложений для АВР на ИАР angry.gif .

Ни AVR, ни IAR здесь ни причем. "С", просто "С" стандартное поведение.

А в чем разница между "динамически" и "автоматически"???

Автоматическая переменная будет удалена автоматически при выходе из функции, в которой она была определена.
Удаление динамических переменных по мере их ненадобности - задача программера. Распространненость подобных ошибок (неосвобождение памяти) приводилась как аргумент за корявость всего языка.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 18 2007, 21:52
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(xemul @ Jan 19 2007, 01:44) *
Автоматическая переменная будет удалена автоматически при выходе из функции, в которой она была определена.
А что, она будет создана не динамически?


--------------------
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 18 2007, 21:59
Сообщение #41



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(prottoss @ Jan 18 2007, 21:43) *
Канешна, это все здорово очень, объясните тада, умные сотоварищи, зачем мне указывать размер стека данных, еслиФ все равно компилятор и иже с ними, создаст массив в этом самом стекеданных, то бишь нарушит мое НЕОСПОРИМОЕ правило???

Не понял про "мое НЕОСПОРИМОЕ правило".
Вы же можете среднепотолочно прикинуть требуемый размер стека с учетом вложенности подпрограмм (и их потребностей для локальных переменных) и прерываний.
А у компилятора по стеку правило одно: сказали "Отсель", значит так и будет.

Цитата(prottoss @ Jan 18 2007, 21:52) *
Цитата(xemul @ Jan 19 2007, 01:44) *
Автоматическая переменная будет удалена автоматически при выходе из функции, в которой она была определена.
А что, она будет создана не динамически?

Вы просили объяснить разницу между автоматическими и динамическими объектами в терминологии С.
А в жизни вообще все относительно - статические объекты с точки зрения программы существуют всегда, а с точки зрения ОС - только пока живет программа. Считать их динамическими?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 18 2007, 22:04
Сообщение #42


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(xemul @ Jan 19 2007, 01:59) *
Цитата(prottoss @ Jan 18 2007, 21:43) *

Канешна, это все здорово очень, объясните тада, умные сотоварищи, зачем мне указывать размер стека данных, еслиФ все равно компилятор и иже с ними, создаст массив в этом самом стекеданных, то бишь нарушит мое НЕОСПОРИМОЕ правило???

Не понял про "мое НЕОСПОРИМОЕ правило".
Вы же можете среднепотолочно прикинуть требуемый размер стека с учетом вложенности подпрограмм (и их потребностей для локальных переменных) и прерываний.
А у компилятора по стеку правило одно: сказали "Отсель", значит так и будет.
Угу, а тада зафига мне куча в Си??? Без плюсиков...

Цитата(xemul @ Jan 19 2007, 01:59) *
Вы же можете среднепотолочно прикинуть требуемый размер стека
Гон всезнайки????????????????????????


--------------------
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 19 2007, 00:20
Сообщение #43



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(prottoss @ Jan 18 2007, 22:04) *
Цитата(xemul @ Jan 19 2007, 01:59) *
Цитата(prottoss @ Jan 18 2007, 21:43) *

Канешна, это все здорово очень, объясните тада, умные сотоварищи, зачем мне указывать размер стека данных, еслиФ все равно компилятор и иже с ними, создаст массив в этом самом стекеданных, то бишь нарушит мое НЕОСПОРИМОЕ правило???

Не понял про "мое НЕОСПОРИМОЕ правило".
Вы же можете среднепотолочно прикинуть требуемый размер стека с учетом вложенности подпрограмм (и их потребностей для локальных переменных) и прерываний.
А у компилятора по стеку правило одно: сказали "Отсель", значит так и будет.
Угу, а тада зафига мне куча в Си??? Без плюсиков...

Повторюсь за всех, уже говоривших об этом: куча используется для динамического выделения памяти, автоматические переменные обычно размещаются на стеке.
Цитата
Цитата(xemul @ Jan 19 2007, 01:59) *
Вы же можете среднепотолочно прикинуть требуемый размер стека
Гон всезнайки????????????????????????

Вам не доводилось этим заниматься и установки стека по умолчанию достаточно? Ну и слава богу и разработчикам используемых Вами компиляторов.
Если помните, причина возникновения этого треда крылась в некорректной работе со стеком. Подобные треды возникают достаточно регулярно, и в них неоднократно обсуждались способы контроля переполнения и оценки требуемой глубины стека. Кста, Вы в них активно участвовали. Не отложилось?
И, плз, если Вы чего-то не знаете, не выставляйте это напоказ несколько агрессивным образом.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 19 2007, 01:32
Сообщение #44


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Сергей Борщ @ Jan 18 2007, 18:56) *
...

Respect!
Сомневаюсь, что у меня получилось бы лучше раскрыть вопрос.

Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *
2 defunct. Главное, о чём я писал в своём сообщении, что если бы компилятор произвольно использовал бы кучу, то как с ней работать? А если я её освобождаю ниже занятого уровня? Я уверен, что она не занята. Потому, что мной она не занята. Он меня ещё может контролировать. Я его - нет.

Компилятор с кучей не работает вовсе.
"Куча" - это просто куча - доступная в run-time память. Для того чтобы с ней работать нужен также run-time менеджер памяти.

Попробую продемонстрировать динамическое распределение памяти на простейшем примере. Допустим нам надо выделять массивы объемом 64 байта (например для хранения подготовленного к отправке пакета данных того же modbus), сколько их потребуется - неизвестно, каким будет их время жизни тоже низвестно. Представьте, что у Вас есть статический массив MyHeap, элементами которого являются некоторые структуры, например такие:

Код
typedef U8 PSTORAGE[64];
typedef U8 *PTR;

typedef struct __tagHeapPart
{
   U8 Busy;
   PSTORAGE storage;
} THEAP_PART, *PHEAP_PART;

THEAP_PART MyHeap[ 16 ];
#define COUNT( somearray )  (sizeof(somearray) / sizeof(somearray[0]))


пишем фукции динамического выделения и освобождения блока памяти:

Код
PTR my_alloc_part(void)
{
    U8 i;
    PTR retval = NULL;
    for (i = 0; i < COUNT(MyHeap); i++)
    {
        if (!MyHeap[i].Busy) // блок не занят
        {
             MyHeap[i].Busy = TRUE; // занимаем его
             retval = MyHeap[i].storage;
             break;
        }    
    }
    return retval;
}

void my_free_part(PSTORAGE pPart)
{
    if (pPart)
    {
        pPart[-1] = 0; // освобождаем блок (Busy = false)
    }
}


Т.о. с помощью my_alloc_part вам будет выделен кусочек статического массива, который Вы смело можете использовать столько сколько нужно. Когда этот кусочек будет ненужен - достаточно вызвать my_free_part и он опять вернется в "кучу".
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 19 2007, 02:21
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Сергей Борщ @ Jan 18 2007, 19:56) *
Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *

Но я говорю немного уклончиво потому, что полностью компилятор не знает никто кроме разработчиков, а в полной мере проверить не удаётся.
Для того и существуют стандарты, чтобы точно описывать "как оно должно быть","как оно не должно быть" и "а вот это хз". Последнее отдано на откуп разработчикам компиляторов. Не больше.
Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *
Пример специально для Вас Сергей Борщ. smile.gif В библиотеках которые я выкладывал по поводу 18b20 применено динамическое распределение памяти. И там же использован массив локальный.
Здесь вы путаетесь в терминах. В языке С динамическим распределением памяти называется именно работа с кучей. Локальные переменные, под которые память выделяется на стеке, в терминах С называются автоматическими. Переменные, под которые память выделяется на этапе запуска программы, называются статическими. К статическим относятся глобальные переменные и локальные переменные, объявленные с квалификатором static. В вашем примере динамического распределения я не увидел.
Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *
Возможно Вы будете удивлены, но IAR данный массив размещает в регистрах. (Оптимизирует)
Ненаказуемо smile.gif Но если вы попытаетесь взять адрес такой переменной и передать куда-либо указатель на нее, она сразу же из регистров окажется в памяти.

Цитата(SasaVitebsk @ Jan 17 2007, 23:49) *
2 defunct. Главное, о чём я писал в своём сообщении, что если бы компилятор произвольно использовал бы кучу, то как с ней работать? А если я её освобождаю ниже занятого уровня? Я уверен, что она не занята. Потому, что мной она не занята. Он меня ещё может контролировать. Я его - нет.
я не defunct, но попытаюсь ответить: вы не можете "освободить ниже занятого уровня". Вы говорите сколько вам памяти надо, malloc выделяет в куче участок такого размера и выдает вам указатель на него. Этот участок в вашем полном распоряжении и никто на него не покусится. Когда вы хотите освободить этот участок - вы передаете free указатель на участок. Размер освобождаемого участка менеджер памяти определит сам. Повторное освобождение какого-либо участка - это ошибка в программе. Но ничего не мешает другой части программы (другой функции, задаче, другому потоку) получить из этой же кучи другой участок.


Я не путаюсь в терминах. Я пишу "В библиотеках которые я выкладывал по поводу 18b20 применено динамическое выделение памяти. И там же использован массив локальный." и это так и есть! Просто п/п пример, которой я привёл не использует динамического выделения, а использует локальный массив. Динамическое выделение исп. в другом месте этой же библиотеки.

Код
uint8_t OW_cnt_device(void)
{
uint8_t    Cnt_Device;                                // Число устройств на шине

Cnt_Device=0;
if(!OW_reset())                                // Начинается когда импульс присутствия обнаружен
{
   lastDiscrep = 0;                                // восстановите последнее несоответствие rom поиска глобальное
   OW_Rom_Device=CurrentAddr=malloc(8);            // Зарезервировать память под ROM
   while (Next())                                // Продолжить пока все дополнительные устройства не будут обнаружены
   {
     Cnt_Device++;
   }
}  return(Cnt_Device);
}


void OW_free(void)                                // Освободить память занятую под датчики
{
  free(OW_Rom_Device);                            // Освободить память
}


Я определяю колличество 1-wire устройств на шине (Cnt_Device) и их адреса в объёме Cnt_Device*7+1 сохраняю в куче.

Это было выложено в библиотеках для всеобщего 18.10.2006, что явно раньше этой дискусии.

А примером по локальному массиву, я возразил что он не всегда ложится на стэк. В моём случае компилятор при оптимизации разместил его в регистрах.

По поводу высказывания.
Цитата
я не defunct, но попытаюсь ответить: вы не можете "освободить ниже занятого уровня". Вы говорите сколько вам памяти надо, malloc выделяет в куче участок такого размера и выдает вам указатель на него. Этот участок в вашем полном распоряжении и никто на него не покусится. Когда вы хотите освободить этот участок - вы передаете free указатель на участок. Размер освобождаемого участка менеджер памяти определит сам. Повторное освобождение какого-либо участка - это ошибка в программе. Но ничего не мешает другой части программы (другой функции, задаче, другому потоку) получить из этой же кучи другой участок.


Вы меня не поняли. Я имел в виду следующее. Представьте что я выполнил процедуру определения датчиков OW_cnt_device() и получил указатель на свободное место в куче. После этого компилятор без моего ведома разместил там ещё какое-то колличество переменных. Не зная об этом я беру и выполняю операцию OW_free(). В результате происходит крах проги. Поэтому я и высказал сомнение о реальности.

Я редко высказываюсь категорично. Приведу пример. В серьёзных (во всяком случае я об этом читал) системах/компиляторах (В винде этого нет) существуют так называемые "сборщики мусора". Которые убирают дыры образующиеся в куче при выполнении операций new/free. Таким образом менеджер памяти там очень мощный. Он может перераспределять данные, в том числе от разных пользователей/потоков. Здесь менеджер - один указатель и пара сравнений. Написано пользователь сам должен. Оно и понятно "обеднённая" система.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 19 2007, 11:11
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(xemul @ Jan 19 2007, 04:20) *
Цитата(prottoss @ Jan 18 2007, 22:04) *

Цитата(xemul @ Jan 19 2007, 01:59) *
Цитата(prottoss @ Jan 18 2007, 21:43) *

Канешна, это все здорово очень, объясните тада, умные сотоварищи, зачем мне указывать размер стека данных, еслиФ все равно компилятор и иже с ними, создаст массив в этом самом стекеданных, то бишь нарушит мое НЕОСПОРИМОЕ правило???

Не понял про "мое НЕОСПОРИМОЕ правило".
Вы же можете среднепотолочно прикинуть требуемый размер стека с учетом вложенности подпрограмм (и их потребностей для локальных переменных) и прерываний.
А у компилятора по стеку правило одно: сказали "Отсель", значит так и будет.
Угу, а тада зафига мне куча в Си??? Без плюсиков...

Повторюсь за всех, уже говоривших об этом: куча используется для динамического выделения памяти, автоматические переменные обычно размещаются на стеке.
Цитата
Цитата(xemul @ Jan 19 2007, 01:59) *
Вы же можете среднепотолочно прикинуть требуемый размер стека
Гон всезнайки????????????????????????

Вам не доводилось этим заниматься и установки стека по умолчанию достаточно? Ну и слава богу и разработчикам используемых Вами компиляторов.
Если помните, причина возникновения этого треда крылась в некорректной работе со стеком. Подобные треды возникают достаточно регулярно, и в них неоднократно обсуждались способы контроля переполнения и оценки требуемой глубины стека. Кста, Вы в них активно участвовали. Не отложилось?
И, плз, если Вы чего-то не знаете, не выставляйте это напоказ несколько агрессивным образом.
Извиняюсь, был не прав smile.gif


--------------------
Go to the top of the page
 
+Quote Post
makc
сообщение Jan 19 2007, 11:58
Сообщение #47


Гуру
******

Группа: Админы
Сообщений: 3 621
Регистрация: 18-10-04
Из: Москва
Пользователь №: 904



Предложение ко всем участникам форума - квотить меньше и аккуратнее дабы не подпадать под предупреждение по пункту правил 3.4 (оверквотинг).


--------------------
BR, Makc
В недуге рождены, вскормлены тленом, подлежим распаду. (с) У.Фолкнер.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 19 2007, 12:06
Сообщение #48


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SasaVitebsk @ Jan 19 2007, 01:21) *
Я не путаюсь в терминах. Я пишу "В библиотеках которые я выкладывал по поводу 18b20 применено динамическое выделение памяти.
Да, после приведенного кода снимаю все возражения и обвинения smile.gif Извиняюсь, не смотрел ваши библиотеки, ограничился лишь анализом приведенного куска. Подумал, что раз уж вы выложили кусочек кода, то решили облегчить мне задачу поиска исходников этих библиотек и в представленном коде есть все, что необходимо для обсуждения.
Цитата(SasaVitebsk @ Jan 19 2007, 01:21) *
Это было выложено в библиотеках для всеобщего 18.10.2006, что явно раньше этой дискусии.
Бывает, что некоторые темы я пропускаю wink.gif
Цитата(SasaVitebsk @ Jan 19 2007, 01:21) *
А примером по локальному массиву, я возразил что он не всегда ложится на стэк. В моём случае компилятор при оптимизации разместил его в регистрах.
Это да, с этим я не спорю. Я пытался спорить с чьим-то утверждением, что компилятор может разместить его в куче.
Цитата(SasaVitebsk @ Jan 19 2007, 01:21) *
Вы меня не поняли. Я имел в виду следующее. Представьте что я выполнил процедуру определения датчиков OW_cnt_device() и получил указатель на свободное место в куче. После этого компилятор без моего ведома разместил там ещё какое-то колличество переменных.
Где там? В куче? Зарадибога. Заметьте, вы получили указатель не "на свободное место в куче", а на свободный участок указанного вами размера. В этот участок никто больше не залезет. Но и вы не имеете права лезть за границы этого участка.
Цитата(SasaVitebsk @ Jan 19 2007, 01:21) *
Не зная об этом я беру и выполняю операцию OW_free(). В результате происходит крах проги. Поэтому я и высказал сомнение о реальности.
Никакого краха. В кучу возвращается выделенный вам участок, на который указывал OW_Rom_Device. Остальные участки если и были выделены кому-то без вашего ведома продолжают существовать.

Цитата(SasaVitebsk @ Jan 19 2007, 01:21) *
Я редко высказываюсь категорично. Приведу пример. В серьёзных (во всяком случае я об этом читал) системах/компиляторах (В винде этого нет) существуют так называемые "сборщики мусора".
Тут я тоже не буду утверждать категорично - изучал вопрос довольно поверхностно и для аргументированной беседы мне нужно обратиться к литературе, а литература в данный момент не доступна (она на работе, я-дома). Если есть желание - можем продолжить в понедельник, можно в отдельной ветке.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 19 2007, 12:21
Сообщение #49


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(prottoss @ Jan 18 2007, 19:39) *
А в чем разница между "динамически" и "автоматически"???

"динамически" == "в куче", "автоматически" == "в стеке/регистрах", "статически" == "в специально зарезервированном линкером участке памяти, не в стеке и не в куче".
Цитата(prottoss @ Jan 18 2007, 19:39) *
1. Если уж говорить по русски - я считаю что "динамически" - это на этапе исполнения кода, а Вы о чем глаголите???
Пытаемся обсуждать тематический вопрос с применением принятой в этой области терминологии. Чтобы избежать несуразностей, вызванных неправильной трактовкой "пимпочек", "загогулин" и "фИгни" biggrin.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 19 2007, 12:36
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Сергей Борщ @ Jan 19 2007, 16:21) *
Цитата(prottoss @ Jan 18 2007, 19:39) *

А в чем разница между "динамически" и "автоматически"???

"динамически" == "в куче", "автоматически" == "в стеке/регистрах", "статически" == "в специально зарезервированном линкером участке памяти, не в стеке и не в куче".
Цитата(prottoss @ Jan 18 2007, 19:39) *
1. Если уж говорить по русски - я считаю что "динамически" - это на этапе исполнения кода, а Вы о чем глаголите???
Пытаемся обсуждать тематический вопрос с применением принятой в этой области терминологии. Чтобы избежать несуразностей, вызванных неправильной трактовкой "пимпочек", "загогулин" и "фИгни" biggrin.gif
Да, я стараюсь избегать создания массивов внутри функции... Тем паче, что, посмотрев код, на самом деле убедился в том, что ИАР выделил место под массив в стеке данных - он просто в начале функции взял, и увеличил значение регистра Y на размер моего объявленного массива! В принципе, в х86 компиляторах делается то же самое, но там размер памяти 4 Gb, здесь же иногда приходится крутится в 128 байтах да еще с практически всеми возможными задействованными прерываниями



НО, зачем тогда в опциях ИАРа стоит heap size для Си (без плюсиков) ? Оператор new использовать нет возможности, зачем же тогда куча?


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 19 2007, 12:57
Сообщение #51


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(prottoss @ Jan 19 2007, 11:36) *
НО, зачем тогда в опциях ИАРа стоит heap size для Си (без плюсиков) ? Оператор new использовать нет возможности, зачем же тогда куча?
Чтобы размещать в ней различные данные, используя функции malloc, calloc, free и т.д. из stdlib.h. Динамическое распределение памяти


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 19 2007, 13:29
Сообщение #52


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Сергей Борщ @ Jan 19 2007, 16:57) *
Цитата(prottoss @ Jan 19 2007, 11:36) *

НО, зачем тогда в опциях ИАРа стоит heap size для Си (без плюсиков) ? Оператор new использовать нет возможности, зачем же тогда куча?
Чтобы размещать в ней различные данные, используя функции malloc, calloc, free и т.д. из stdlib.h. Динамическое распределение памяти
Вы сами то эти функции применяете в проектах? smile.gif


--------------------
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jan 19 2007, 13:55
Сообщение #53


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(prottoss @ Jan 19 2007, 12:29) *
Цитата(Сергей Борщ @ Jan 19 2007, 16:57) *
Цитата(prottoss @ Jan 19 2007, 11:36) *

НО, зачем тогда в опциях ИАРа стоит heap size для Си (без плюсиков) ? Оператор new использовать нет возможности, зачем же тогда куча?
Чтобы размещать в ней различные данные, используя функции malloc, calloc, free и т.д. из stdlib.h. Динамическое распределение памяти
Вы сами то эти функции применяете в проектах? smile.gif

Я, например, применяю.
Работает.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 19 2007, 13:57
Сообщение #54


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(prottoss @ Jan 19 2007, 12:29) *
Вы сами то эти функции применяете в проектах? smile.gif
На ARM - да, но там я пользую ++ и они "обернуты" в new и delete. В аврах - нет, не было необходимости. Когда для РС писал (еще под ДОСом) - тоже применял.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 19 2007, 14:12
Сообщение #55


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(IgorKossak @ Jan 19 2007, 17:55) *
Цитата(prottoss @ Jan 19 2007, 12:29) *

Цитата(Сергей Борщ @ Jan 19 2007, 16:57) *
Цитата(prottoss @ Jan 19 2007, 11:36) *

НО, зачем тогда в опциях ИАРа стоит heap size для Си (без плюсиков) ? Оператор new использовать нет возможности, зачем же тогда куча?
Чтобы размещать в ней различные данные, используя функции malloc, calloc, free и т.д. из stdlib.h. Динамическое распределение памяти
Вы сами то эти функции применяете в проектах? smile.gif

Я, например, применяю.
Работает.
Интересно, что делает контроллер, когда узнает, указатель равен NULL??? наверное начинает истерично мигать лампочками smile.gif


--------------------
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 19 2007, 15:42
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(prottoss @ Jan 18 2007, 19:39) *
а Вы о чем глаголите???

Я об ОБЩЕПРИНЯТОЙ терминологии идущей от Авторов языка.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jan 19 2007, 15:47
Сообщение #57


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(prottoss @ Jan 19 2007, 13:12) *
Интересно, что делает контроллер, когда узнает, указатель равен NULL??? наверное начинает истерично мигать лампочками smile.gif

Равенство нулю указателя легко проверить и уж потом принять решение.
Как один из вариантов - вызвать функцию истеричного мигания лампочками.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 19 2007, 15:55
Сообщение #58


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(zltigo @ Jan 19 2007, 19:42) *
Цитата(prottoss @ Jan 18 2007, 19:39) *

а Вы о чем глаголите???

Я об ОБЩЕПРИНЯТОЙ терминологии идущей от Авторов языка.
Хорошо, хорошо, признаю - я заблуждался


--------------------
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 19 2007, 15:55
Сообщение #59


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(prottoss @ Jan 19 2007, 12:29) *
Вы сами то эти функции применяете в проектах? smile.gif

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 20 2007, 04:48
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Prottoss последний мой проект целиком построен на динамической памяти. Именно AVR правда m640 (8к озу)

Фишка в том что программа в МК - это продолжение железа. И Вы и я это понимаем. NULL не может быть получен. Это говорит о том, что у Вас в проге что-то не верно. Если даже менеджер и не полный, значит вы сами должны контролировать.

Я работаю с данными типа файл. Этот файл приходит с PC. Внутри данных идут упорядоченные структуры. Они нескольких типов и разной длины. Длина файла не известна. Как можно с этим работать? Только куча и указатели. Причём Вы не поверите. Я сам не поверил. Удобно до безобразия. Наглядно и красиво. Вырву кусочек.

Код
  KomXx    = (struct AddrKomXx*) AdrActiveKom[i];            // Прочитать адрес текущей активной    команды
  if(KomXx->TimeStart>TekTime) continue;                // Если    не подошло время для исполнения    команды, то    пропустить данную команду
  switch (KomXx->Name) {
.........
  /* Команда "OUTG"    - "Вывод статической графики" */
  case 'G':
             KomG =    (struct    AddrKomG*) AdrActiveKom[i];    // Прочитать адрес текущей активной    команды
             KomG->TimeMashtabTek++;                    // Следующий такт
             if(KomG->TimeMashtabTek >=    KomG->TimeMashtab)// если    подошёл, то
               KomG->TimeMashtabTek=0;                    // иначе начать    заново
             OutPict(KomG->BegX,KomG->BegY,KomG->SizeX,KomG->SizeY,&KomG->Pict[0]);    // Вывести картинку
             if(KomG->TimeMashtabTek ==    0){                // если    подошёл, то
               KomG->TimeLife--;                        // Уменьшить время жизни
               KomG->BegX += KomG->VecX;                // Сместить    объект
               KomG->BegY += KomG->VecY;                // Сместить    объект
             }
             break;
  /* Команда "ANIMATE" - "Вывод    анимированной графики" */
  case 'M':
             KomM =    (struct    AddrKomM*) AdrActiveKom[i];    // Прочитать адрес текущей активной    команды
.....
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 20 2007, 05:12
Сообщение #61


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Сергей Борщ @ Jan 19 2007, 13:06) *
Где там? В куче? Зарадибога. Заметьте, вы получили указатель не "на свободное место в куче", а на свободный участок указанного вами размера. В этот участок никто больше не залезет. Но и вы не имеете права лезть за границы этого участка.
Цитата(SasaVitebsk @ Jan 19 2007, 01:21) *

Не зная об этом я беру и выполняю операцию OW_free(). В результате происходит крах проги. Поэтому я и высказал сомнение о реальности.
Никакого краха. В кучу возвращается выделенный вам участок, на который указывал OW_Rom_Device. Остальные участки если и были выделены кому-то без вашего ведома продолжают существовать.


smile.gif Усложним задачу.

Давайте в цифрах. Для простоты начальный уровень 0. Потом я занял 100. Компилятор выделил 10.

Я освободил до нуля. И опять забрал кусок, на этот раз 200. И запортил его. Крах?


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

Теперь ещё один момент. Конечно чисто теоретически поставленная мной задача(новая) вполне разрешима с хорошим менеджером кучи. Но мы то говорим о AVR.

Если брать например DELFI (C для PC я не пользую), то там я имею право например выделить память под A,B,C,D а потом освободить место из под B. Потом если я выделю память под переменную E, то я не знаю где её расположит менеджер кучи. Он может её расположить за D, а может (если размеры подойдут на место дырки cool.gif. Я не в праве гадать. Если эти переменные использовать правильно, то разницы ведь нет. А объём оставшейся свободной памяти я получаю исправно.

Но в IAR AVR под С такого нет! Я был удивлён. Процедурой free, я могу только освободить одну или несколько переменных от конца кучи. Я не могу освободить B! Могу только B,C,D. Да и занять я могу просто место, а не создать переменную. Вроде это есть в C++. Не знаю. Не работал ещё.

Но это реально указывает на то, что менеджер очень упрощённый. Что в принципе обосновано. Если для МК делать что-то мощнее, то это будет слабо востребовано.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 10:03
Рейтинг@Mail.ru


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