stm32 и работа со стуктурами и указателями

Кто любит RISC в жизни, заходим, не стесняемся.
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

YS, хочу еще ваших статей по Си в том же ключе разжевывания по железу, а не абстрактно для любого компа! С уклоном для STM32. Где-то читал ваш блог, там тоже много интересного. :beer:

Вот здесь тоже интересно почему?
y = *((uint8_t *)(&x));

Если ранее мы определили 4 байта и обозвали их Х. Таким образом, что в Х лежит адрес на эти 4 байта, т.е. на первый байт. Компилятор знает, что от этого адреса надо отсчитать 4 байта (32 бита), чтобы можно было добраться до "свободной" памяти не испортив то, что до этого записано.
А потом вот этот приведение к типу?
Все. Пока писал - понял. Последние три байта он выкинет (освободит) под другие задачи. Т.е. после этой конструкции у нас останется Х с одинм байтом. ?

А запись происходит, как вы указали от младшего к старшему, т.к. адреса тоже идут по порядку. Примерно так:
0хF4
0х01
0х00
0х00
Или так:
0хF4; 0х01; 0х00; 0х00.

А если к ним добавить адреса, то будет примерно так (адреса абстрактные):
0х000001 0хF4
0х000002 0х01
0х000003 0х00
0х000004 0х00

И если потом увидеть этот код в HEX файле, то читать свое число надо снизу вверх, или справа налево, чтобы вернуться к исходному?
Станислав
Реклама
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

СКАЗОЧНИК wrote:Последние три байта он выкинет (освободит) под другие задачи. Т.е. после этой конструкции у нас останется Х с одинм байтом. ?
нет!

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

x - это "коробочка, достаточного размера для 4 горошин". Когда вы говорите компилятоу "достань из коробочки 'х' одну горошину" - это ведь не означает, что коробочка должна уменьшиться?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

Т.е. переопределение типа или как оно там называется, тупо ничего не меняет, кроме возвращаемого значения? Или как понятнее выразиться, переменная Х так и осталась 4 байтная, просто мы вытаскиваем из нее один байт?
И если после той конструкции я обращусь к Х как раньше, то он мне вернет все 32 бита?
Станислав
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

СКАЗОЧНИК wrote:переменная Х так и осталась 4 байтная, просто мы вытаскиваем из нее один байт?
совершенно верно!

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

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

Мой уютный бложик... заходите!
Реклама
Эиком - электронные компоненты и радиодетали
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

При копировании в меньшую по размеру теряются старшие разряды?


И тогда так и получается, что я могу к 4 байтной переменной обратиться как массиву с четырьмя однобайтными элементами. Или как к массиву с двумя двухбайтными. Используя просто адрес и сдвиг, ну или номер элемента.
Last edited by СКАЗОЧНИК on Tue Apr 02, 2019 09:46:12, edited 1 time in total.
Станислав
Реклама
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

да

Добавлено after 39 seconds:
только не путайте копирование и взятие данных с принудительным приведением типа
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

Про второе подробнее. )))
Станислав
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

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

Code: Select all

long x = 0x12345678;
то результат

Code: Select all

int y = x;
всегда будет один и тот же (копирование только младших разрядов) 0x5678;
а результат

Code: Select all

int y = (int*)&x;
будет разным в зависимости от того, как размещены в памяти данные.

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

Мой уютный бложик... заходите!
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

Почему в указателях звездочку ставят то там, то там?
Есть, где *Х, а есть где int *

Это путает. И чего это напридумывали разную последовательность адресов? Мой мозг сопротивляется. :oops:

но про разные по размеру переменные сверху Х и У понятно, что в меньшую не влезет все.

И как я теперь понимаю
long y = (long*)&x;
Тоже неоднозначно скопирует. Может перевернуть все как попало.
Короче, не тоже самое, что и
long Y = X;

А разве компилятор не присваивает Х адрес младшего байта переменной?
Станислав
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

СКАЗОЧНИК wrote:И как я теперь понимаю
int y = (long*)&x;
Тоже неоднозначно скопирует.
да, если абстрактно, то скопирует неоднозначно. но в рамках одной конкретно выбранной вами платформы однозначность гарантируется :)
код с принудительным приведением типов является плохопереносимым, поэтому и не приветствуется на постоянной основе...
СКАЗОЧНИК wrote:И чего это напридумывали разную последовательность адресов?
конкуренция производителей... исторически так сложилось.
СКАЗОЧНИК wrote:Почему в указателях звездочку ставят то там, то там?
следует разделять 2 случая: описание типа данных для указателя и разыменование указателя (тоже тот еще термин, имхо).
в первом случае звездочка является признаком типа, т.е. логично прилеплять её к "основному" типу: int*, long* и т.п. во втором случае безусловно звездочка прилеплена к указателю, т.е. *x, *ptr.

Добавлено after 2 minutes 23 seconds:
СКАЗОЧНИК wrote:А разве компилятор не присваивает Х адрес младшего байта переменной?
компилятор "помечает" идентификатором Х адрес ПЕРВОГО байта участка памяти под данные заданного типа. а то, в каком порядке байты этих данных будут там размещаться, зависит от конкретной платформы, и может быть разным.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

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

Вот этой конструкцией:
z = *(((uint8_t *)(&x)) + 1);

если вместо +1 поставить +6 вылетит за приделы переменной Х и запишет в Z то, что находится дальше по памяти? Или компилятор это отследит и ограничит (выдаст ошибку)?
Станислав
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

указатели в Си - это та самая бритва, о котоой писал Керниган :) это источник практически всех уязвимостей в ОС :) так что не удивительно, что начинающему это представляется ужасным и манящим...
СКАЗОЧНИК wrote:Вот этой конструкцией:
z = *(((uint8_t *)(&x)) + 1);

если вместо
хотите совет любителю от любителя? никогда не пользуйтесь такими конструкциями! пишите так, как вам понятно. современный компилятор все равно оптимизирует 99% вашей писанины в наиболее подходящий код. вы же не на конкурсе виртуозов Си пишите?

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

Добавлено after 3 minutes 21 second:
СКАЗОЧНИК wrote:если вместо +1 поставить +6 вылетит за приделы переменной Х и запишет в Z то, что находится дальше по памяти? Или компилятор это отследит и ограничит (выдаст ошибку)?
компилятор никогда не отслеживает и не блокирует доступ по указателю - не его это дело. в лучшем случае вы получите варнинг при компиляции.

а что произойдет при доступе "за пределы" - сильно зависит от платформы. например, в Windows может произойти исключение и падение программы. в AVR не произойдет ничего - будет считан следующий "за переменной" байт ОЗУ с неизвстно акаим содержимым. что будет в STM32, увы, не знаю...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

Скорее всего будет тоже самое, что и в AVR.

Я просто клоню к тому, что есть например светодиоды WS2812, им надо выплевывать по 3 байта данных, чтобы зажечь. А все МК оперируют четным количеством байт (простите, я уже мыслю больше чем 8 бит МК в данном случае). И если у меня есть массив данных (очень много), и еще пулять его через DMA (ПДП), то там никто не будет вычислять какой байт пропустить или чего еще. Там просто тупо начиная с одного адреса будут лететь байт за байтом. И это очень удобно.
А вот если ручками слать, то это долго, да еще и надо как-то выслеживать на каком байте какой переменной обновился один светодиод, и что оставшиеся надо отправить тут же на следующий светодиод и добить еще парой байт со следующей переменной. Как-то туго выполнимо это. Тем более, что МК займется в это время основной программой.

И если по ПДП писать в память тоже надо размерять не попадет ли относительно начального адреса какая-нибудь цифра на те переменные, которые нельзя трогать ибо все рухнет, если вылезти за пределы.
Ну и тому подобное...
Станислав
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

СКАЗОЧНИК wrote:Ну и тому подобное...
по-моему, вы сильно преувеличиваете. либо, не совсем разобравшись, вообще все путаете.

для линейки WS-ок вам потребуется массив - вы его один раз описали (выделили память), и все - больше никто в эту память не залзет. если вы DMA настроите на выдачу этого массива, то пока DMA не будет остановлен, никто не влезет в процесс выдачи.
а то, что в это самое время в массив можно "без DMA" писать - совсем не страшно! во-первых, процесс чаще всего последовательный, т.е. сначала "нарисовали" в массив, потом массив выдали. во-вторых, обновление ленты при динамических эффектах ведется очень часто, и если в процессе выдачи вы измените содержимое массива, на следующем выводе статус-кво восстаноится - никто и не заметит, что долю секунды один из светиков мигнул не тем оттенком...

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

Мой уютный бложик... заходите!
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

Менять массив все же буду. Ну, типа тетрис... :oops: не дает он мне покоя...
Да, пока не совсем понимаю, как это будет реализовано. :dont_know: но по чуть-чуть потихоньку разберусь, задавая глупые вопросы на форуме. :roll: :beer:

ну и если учесть, что вывод данных через Таймер с помощью ШИМ (по ПДП), то с памяти очень много данных будет выплевываться.
Станислав
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

СКАЗОЧНИК wrote:Менять массив все же буду. Ну, типа тетрис...
да и на здоровье! для игр всегда важна синхронизация, поэтому у вас автоматически будет разделены процессы обновления данных в массиве и вывод данных из него. более того, основное время ваш код вообще будет простаивать в ожидании момента синхронизации. ну или МК спать будет...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

Про МК и спать тоже у меня не укладывается... Если механизм завел двигатель и стоит на светофоре, то двигатель же не глушат... А в МК мне не понятно становится, зачем его усыплять на миллисекунды, если опять будить потом для выполнения задачи, которая продлится пару миллисекунд, а потом опять усыплять. И дергать его туда-сюда.
Станислав
User avatar
ARV
Ум, честь и совесть. И скромность.
Posts: 18675
Joined: Thu Dec 28, 2006 08:19:56
Location: Новочеркасск
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by ARV »

СКАЗОЧНИК wrote:Про МК и спать тоже у меня не укладывается...
это уже из разряда философии выбора МК: можно взять МК, коорый в поту будет молотить, едва успевая сделать вши задумки, а можно взять МК, который все ваши задумки сделает быстро и потом ему просто нечего будет делать. а нечего делать - это либо пустой цикл, либо сходить в интернет... сон. сон имеет преимущество в том, что снижает энергопотребление. зачем снижать? не ко мне вопрос :)

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

Мой уютный бложик... заходите!
User avatar
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Posts: 5000
Joined: Thu Apr 21, 2011 17:55:50
Location: Иркутск

Re: stm32 и работа со стуктурами и указателями

Post by СКАЗОЧНИК »

stm32f103 на частоте 72 МГц.
Вот и очередной вопрос, который пока мало мне где попадался под осознание. Как вычислять производительность под конкретные задачи? Пусть даже мощный МК будет. Значит как-то надо уметь вычислять сколько он будет занят чем-то, а сколько будет тупить. Чтобы можно было адекватно подумать и выключить его... и для экономии электричества в том числе.
Но иной раз на фоне кучи ампер потребления светодиодами на панели его личное потребление на уровне потерь в проводах не сделает погоды...
Станислав
User avatar
YS
Друг Кота
Posts: 7518
Joined: Sun Mar 29, 2009 22:09:05
Contact:

Re: stm32 и работа со стуктурами и указателями

Post by YS »

YS, хочу еще ваших статей по Си в том же ключе разжевывания по железу, а не абстрактно для любого компа! С уклоном для STM32. Где-то читал ваш блог, там тоже много интересного.
:))

Когда-то, когда я был моложе, меня удивлял вопрос - куда деваются онлайн-авторы? А теперь я понял.

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

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

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

Например, если много и интересно писать про контроллеры, в какой-то момент можно обнаружить, что все девушки вокруг кончились, и твои способности ответить на любой вопрос по Си вообще и применительно к STM32 в частности не помогут тебе вернуть упущенное.

Ссылка на блог есть в моем профиле. Но я уже практически забросил его.
Вот здесь тоже интересно почему?
y = *((uint8_t *)(&x));
ARV верно объяснил про горошины. Как я писал два года назад, тип - это по сути правило обращения к области памяти. Приводя тип, мы инструктируем компилятор временно, для конкретно этого доступа, поменять это правило.
И как я теперь понимаю
long y = (long*)&x;
Тоже неоднозначно скопирует. Может перевернуть все как попало.
В рамках одной платформы скопирует однозначно, а как код может выполняться на нескольких платформах одновременно, мне понять сложно. :)

Разберем эту запись.

x - именованная область памяти, переменная. Пускай она будет типа int16_t. Т.е., компилятор где-то заготовил два байта, и знает, что к ним надо обращаться как к двухбайтному числу.

&x - извлечь стартовый адрес, начиная с которого эти два байта расположены.

(long *)(&x) - переопределить правило доступа, как если бы по этому адресу лежало значение long, то есть, число четыре байта длиной.

long y = *((long *)(&x)) - фактически, скопировать четыре байта, начиная с адреса &x, в переменную y. Да, в x у нас два байта. Но мы принуждаем компилятор работать с &x как с long, и он повинуется. В старших байтах y будет что-то, что лежит за x в памяти.
если вместо +1 поставить +6 вылетит за приделы переменной Х и запишет в Z то, что находится дальше по памяти? Или компилятор это отследит и ограничит (выдаст ошибку)?
Компилятор Си - не ограничит. Он сделает то, что заказано - в этом заключается сила Си, этот язык дает полную свободу программисту. Правда, при этом требуется, чтобы программист знал, что делает.
что будет в STM32, увы, не знаю...
В чипах без MMU или, вообще, без использования MMU - то же самое. Прочтет.
а то, что в это самое время в массив можно "без DMA" писать - совсем не страшно!
Не страшно, конечно.

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

Во-вторых, DMA в STM32 поддерживает кольцевой режим - буфер делится на два, и пока одна часть улетает куда-то при помощи DMA, второй может заниматься ядро (потом наоборот). Есть специальное прерывание, которое вызывается, когда блок DMA добрался до половины. В нем удобно менять указатели на части массива.
Если механизм завел двигатель и стоит на светофоре, то двигатель же не глушат... А в МК мне не понятно становится, зачем его усыплять на миллисекунды, если опять будить потом для выполнения задачи, которая продлится пару миллисекунд, а потом опять усыплять.
На то, чтобы запустить двигатель, тратится время и моторесурс. На включение/выключение МК не тратится почти ничего.

Надо ли усыплять МК или нет, определяется в каждом случае индивидуально - в зависимости от того, сколько энергии сэкономим и стоит ли оно того. Но смысл, конечно, в энергосбережении, чтобы увеличить время работы от батарей, например.
Last edited by YS on Tue Apr 02, 2019 13:12:44, edited 1 time in total.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Post Reply

Return to “ARM”