Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Вопросы по С/С++ (СИ)

Чт дек 26, 2019 23:05:37

uldemir, да если еще дальше по ссылке пройти, всё объяснено. Но вы ведь разобрались уже как размер стека увеличить. Раз в вашем камне осталась еще память для кучи, значит и стек можно еще увеличивать.
Вы размер карты на этапе компиляции будете ведь знать - так и задавайте там, чтобы в стеке лежало. Динамическое распределение памяти и malloc() выгодны на ПК, где памяти много и процесс может динамически запрашивать и освобождать память. На МК такую роскошь себе позволить нельзя. Надо понимать, что свопа никто не добавит, когда закончится физическая память. Поэтому буфер должен быть максимально такого размера, сколько может быть данных и хватает памяти. Ротацию данных внутри буфера можно и без динамической памяти устроить.

Re: Вопросы по С/С++ (СИ)

Пт дек 27, 2019 07:57:42

Увы и нет. Размер карты выясняется на этапе выполнения (смотреть самый конец сообщения). Но, конечно, я лукавлю. Не нужен мне реально malloc(). Меня интересует метод, как разместить массив в любом месте памяти и с ним комфортно работать. Потому как функция создающая карту использует глобальную переменную для которой статически уже выделена память, затем, эта карта переносится во флеш память для хранения и только потом я из флеш памяти её достаю для отображения. Так что, реально, я могу просто использовать уже выделенный кусок памяти или, хочется научиться использовать данные, которые сохранил во флеш-памяти не вытаскивая оттуда. Ваше предложение создать массив указателей сейчас обдумывается.

Конечно, исходная проблема, как узнать, что размер стека маловат - до сих пор не выяснена. И в той, теме, куда была приведена ссылка, этот вопрос так и не был решен. Была распальцовка, было указание увеличить стек, потом опять распальцовка, а вот как проконтролировать - так и не было сказано. Возможно, это недостаток Кейла, но в нём я так и не нашел репорт, где написано "max stack usage". С другой стороны, если бы Кейл знал это, что ему мешало бы самому выделить под стек необходимую память.

Re: Вопросы по С/С++ (СИ)

Пт дек 27, 2019 10:58:09

Возможно, это недостаток Кейла, но в нём я так и не нашел репорт, где написано "max stack usage".
--info=stack

Re: Вопросы по С/С++ (СИ)

Сб дек 28, 2019 21:49:10

Всем добрый вечер. Пытаюсь откомпилировать код, найденный на просторах интернета. Сижу в AtmelStudio. Код для МКонтроллера AVR. МКонтроллер Attiny (малолапчатый)
main.cpp
shiftreg.h
shiftreg.c
macros.h
В данном случае хочу разобраться в структурах, типах передаваемых данных, ссылках и указателях в аргументах и параметрах функции.
При компиляции в AtmelStudio ошибка:
Error undefined reference to
"SHIFTREG_InitRegister(unsigned char volatile*, unsigned char volatile*, unsigned char, unsigned char, unsigned char)"
Ошибка неопределенной ссылки на ...

Фрагмент кода с прототипом функции
Код:
/* ---------- Function prototypes ----------*/
SHIFTREG_register SHIFTREG_InitRegister(volatile uint8_t *ddr_addr, volatile uint8_t *port_addr,uint8_t ds_pin, uint8_t st_cp_pin, uint8_t sh_cp_pin);
В функцию необходимо передать в качестве параметров DDRB, PORTB, PB0, PB1, PB3 (порт и пины к которым подключается регистр 74HC595)
ErrorList.png
ErrorList
(17.29 KiB) Скачиваний: 51
Attinu_74HC595.png
(20.23 KiB) Скачиваний: 60

И что за unsigned char - ясно же сказано uint8_t
Может быть преобразование типов в компиляторе происходит не корректно? :dont_know:
Ссылка -> Подобная ошибка, но машинный перевод
P.S. Аксиома "Код, скачаный из интернета, никогда сразу не работает"
Последний раз редактировалось Эйлер Леонард Сб дек 28, 2019 22:45:29, всего редактировалось 2 раз(а).

Re: Вопросы по С/С++ (СИ)

Сб дек 28, 2019 22:40:25

unsigned char и uint8_t - одно и то же.

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

Re: Вопросы по С/С++ (СИ)

Сб дек 28, 2019 22:51:38

Нет, все файлы подключены.
Файлы проекта ....
2019-12-29_004423.png
(20.08 KiB) Скачиваний: 96
Первоначально файл shiftreg был типом .C , а у меня проект как CPP. Изменил тип файла на CPP и вроде бы как скомпилировалось без ошибок.

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 08:35:53

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

Вот пример хидер-файла:
Код:
#ifdef __cplusplus
extern "C" {
#endif

int sumI(int a, int b);
float sumF(float a, float b);

#ifdef __cplusplus
} // end extern "C"
#endif

Эти ifdef/endif разделяют способ, как компиляторы его будут видеть.
компилятор C:

Код:
int sumI(int a, int b);
float sumF(float a, float b);

компилятор C++ :

Код:
extern "C" {

int sumI(int a, int b);
float sumF(float a, float b);

} // end extern "C"

Т.е. main.cpp должен видеть второй вариант.

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 10:47:02

ОК! Всё фурычит.
Test-30(1)_74HC595.png
Тестирование 74HC595 (счетчик)
(35.8 KiB) Скачиваний: 75
Поправил main.cpp

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 11:39:39

Мне думается, что, cli() и sei() внутри ISR - лишнее.

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 12:19:57

Вот, вот! Существуют разные мнения на сей счет. Остановка прерывания внутри прерывания. Типа того "а вдруг бы чего не вышло не того". Ко мне давно подкрадывался этот вопрос. И, все таки я так же считаю cli() и sei() внутри ISR - лишними. К тому же где то находил убедительные разъяснения по этому поводу.
Я называю это "Копипастинг кусает за пятки". :))

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 13:19:13

cli() внутри ISR, вероятнее всего лишнее, а вот sei() может быть оправдано.

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 13:42:41

а вот sei() может быть оправдано.
А можно узнать, как тогда вы попадаете в прерывание, если они у вас были запрещены? :dont_know:

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 13:53:28

VladislavS писал(а):А можно узнать, как тогда вы попадаете в прерывание, если они у вас были запрещены?
любознательность - это очень похвально! :)
в обработчик прерывания я попадаю уже при запрещенных прерываниях, хотя до момента установки флага запроса прерывания они были разрешены

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 14:12:13

ARV писал(а):а вот sei() может быть оправдано.
такое может понадобиться, если есть необходимость, чтобы другое прерывание (более важное) могло прервать ход выполняемого прерывания.

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 14:38:21

Частный случай;
Код:
ISR(INT0_vect)//External Interrupt
{
   ips++;//На порт PB2 подаем импульсы  _П_П_П_П_П_
};
ISR(TIM0_COMPA_vect)//прерывание по совпадению
{   
MAX7219_display_number(ips);//выводим на дисплей цифры 
   ips=0;
};
С внешнего прерывания считаем (инкрементируем) импульсы. Далее, через определенный период тиков, установленных в таймере-компараторе, подаем их на цифровой дисплей, обнуляем инкремент. Сначала я тренировался на чипе MAX7219, но и с 74HC595 так же считаю необходимым подружиться. А в ISR(TIM0_COMPA_vect){ /* необходимо добавить немного if-ов для усреднения значений */}. Ну и какое из прерываний кого хочет перебороть? Да вроде бы всё мирно должно быть.

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 15:07:12

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

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 15:49:15

-->приоритет прерываний AVR. Пока для меня этот вопрос не столь актуален. Если что, подкуюсь теорией и Гугли. :))

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 16:47:39

Внутри ISR() прерывания запрещены и так, так что cli() не нужен. Равно как и sei() в конце - после выхода из обработчика прерывания и без этого включатся.

А вот если нужно неблокирующее прерывание (так, чтобы другие были разрешены), есть ISR_NOBLOCK:
Код:
ISR(TIM0_COMPA_vect, ISR_NOBLOCK)

avr-libc обо всём позаботится.

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 18:02:48

Есть такое дело.
ISR_NOBLOCK.png
ISR_NOBLOCK в interrupt.h
(15.02 KiB) Скачиваний: 68

Re: Вопросы по С/С++ (СИ)

Вс дек 29, 2019 19:26:50

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