при оптимизации битовыми полями сегмента данных - страдает сегмент кода (читай производительность), за счёт большего количества операций по доступу к полям. Мало того - в зависимости от позиции битового поля в структуре - размер операций тоже может быть разным. Т.е. если с каким-то полем чаще работаем - можно также сэкономить байтики двигая поле в более выгодную позицию.
Все это зависит от архитектуры контроллера и его системы команд. Поскольку речь идет о Микрочипе, то битовые элементы структур как раз очень хорошо ложатся на битовые команды. И код получается компактным и быстрым. Правда все зависит от компилятора и уровня оптимизации. При доступе к биту может и маску применить, а может и битовую операцию. Категоричные заявления о вредности нестандартных типов из-за непереносимости кода не выдерживают никакой критики, потому что различия между платформами столь велики, что переносимыми будут лишь самые общие участки кода, что лишь запутывает программиста и не дает никаких преимуществ и экономии времени.
И как тогда мне ее, структуру, объявить, если struct pos {unsigned char x, y;}; объявлено неправильно?
лично я в подобных "подозрительных" случаях всегда объявляю пользовательский тип - ни разу сбоев не было!
Код:
typedef struct{ unsigned char x, y; } point_t;
pint_t pos;
Добавлено after 1 minute 49 seconds:
КРАМ писал(а):
Категоричные заявления о вредности нестандартных типов из-за непереносимости кода не выдерживают никакой критики
категорические утверждения о невыдерживнии критики не выдерживают никакой критики потому что если есть стандарт, то надо максимально соблюдать его требования все время, пока не попал в безвыходную ситуацию. а уж в безвыходной ситуации все средства хороши.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Третьего дня самолично в RX-GCC наткнулся. Причём директивы упаковки не спасли. Не PIC, конечно - но иметь ввиду вероятность такого сюрприза не помешает, кмк.
Siarzhuk писал(а):
скорее всего он задействует для этой цели аппаратные фичи кристалла. про PIC не скажу, а в MCS51 есть особые области ОЗУ с побитовой адресацией
Обнаружил это в PIC16F630 с XC8 когда и сам заталкивал в него побольше функционала на фоне исчерпания .data. XC8, правда, был Free версии - а в этом режиме он имеет привычку оптимизировать с прохладцей, саботажем и лёгким вредительством - и если в PRO версии с глобальными bit по другому работает - ну тогда я не прав.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Последний раз редактировалось Siarzhuk Пт ноя 18, 2016 13:38:48, всего редактировалось 1 раз.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Ещё, плюс объединений переменных в структуры - обработка в функциях. Можно передавать указатель, как аргумент, вместо кучи переменных.
Правда это удобство приводит к достаточно громоздкому скомпилированному коду в КАЖДОЙ функции, куда передается указатель на структуру. Потому как до конкретного элемента структуры нужно еще добраться.
ARV писал(а):
КРАМ писал(а):
Категоричные заявления о вредности нестандартных типов из-за непереносимости кода не выдерживают никакой критики
категорические утверждения о невыдерживнии критики не выдерживают никакой критики потому что если есть стандарт, то надо максимально соблюдать его требования все время, пока не попал в безвыходную ситуацию. а уж в безвыходной ситуации все средства хороши.
Есть стандарт языка, но нет стандарта для создаваемого кода. Все средства хороши В ЛЮБОЙ ситуации. Более того, если программист не применяет эти самые "все средства" всегда, то в "безвыходной ситуации" он оказывается достаточно беспомощным и полученный код действительно не выдержит никакой критики...
лично я в подобных "подозрительных" случаях всегда объявляю пользовательский тип - ни разу сбоев не было!
Спасибо, получилось!
ARV писал(а):
про PIC не скажу, а в MCS51 есть особые области ОЗУ с побитовой адресацией, и соответствующие однобитовые команды ассемблера. так что и тут речь скорее всего об этом - линкер отдыхает.
Именно в ПИКовом проекте объявлял биты, а потом в отладчике наблюдал, как они все оказывались в одном регистре в области общей памяти.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Поскольку использовать в подобных конструкциях более, чем 1 бит, только ухудшит конечный код (в асме добавятся маски и сдвиги, как я предполагаю), указанное выше - это просто удобство помнить только одну переменную с именем flag, в которую по необходимости можно добавлять и другие подобные флаги.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Поскольку использовать в подобных конструкциях более, чем 1 бит, только ухудшит конечный код (в асме добавятся маски и сдвиги, как я предполагаю)
На всякое категоричное утверждение найдётся аргу́́мент. Если .data уже закончился, а .text ещё полупустой - разменять таким образом RОМ на RAM будет вполне себе выходом. [pedantic mode on] Если не затруднит - гляньте sizeof(bits) пожалуйста и нам сообщите для общего развития. И да - unsigned это unsigned int, и, припоминаю, явное указание вместо int восьмибитного типа в конкретном случае оптимизации под PIC16F630 сэкономило мне в своё время, таки парочку байтов. Стоит тоже проверить, кмк. [pedantic mode off]
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
[pedantic mode on] 1. Если не затруднит - гляньте sizeof(bits) пожалуйста и нам сообщите для общего развития.
2. И да - unsigned это unsigned int, и, припоминаю, явное указание вместо int восьмибитного типа в конкретном случае оптимизации под PIC16F630 сэкономило мне в своё время, таки парочку байтов. Стоит тоже проверить, кмк. [pedantic mode off]
1. Я не волшебник, я только учусь (с) Вы только намекните где это можно увидеть, а я сразу же...
2. Вот тут я в сомнениях. Что-то написать там нужно, но что именно, чтоб они все упаковались в один байт - я не знаю. Пока времени не было уточнить.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
2. Вот тут я в сомнениях. Что-то написать там нужно, но что именно, чтоб они все упаковались в один байт - я не знаю. Пока времени не было уточнить.
Битовые поля по-честному укладываются на соответствующие биты - вопрос лишь в том, сколько займёт структура. Можно глянуть в отладчике. Можно прикинуть по map-файлу. Вот например ваши флаги в моём файле:
Ага, два байта. И во вторую банку переместилось из нулевой - в которой очевидно место закончилось.
А упаковка относится к структурам, поскольку компилятор порой раскладывает их поля по выровненным (aligned) адресам, для ускорения работы с ними. В итоге размер такой структуры будет больше нежели сумма размеров её элементов. Если вам извне придёт пакет данных без подобных "прорех" - разобрать его простым наложением структуры на указатель будет несколько затруднительно. Поэтому при объявлении нужно явно указывать:
Код:
typedef struct __attribute__ ((packed)) _USB_DEVICE_DESCRIPTOR { uint8_t bLength; // Length of this descriptor. [...]
Ну и за компанию про глобальные bit переменные. Добавим горсть малую в тестовый кот с вашим битовым полем:
Т.е. оно их даже в один байт не упаковало. Вероятно справедливо рассудив, что "места у этого поца покамест ещё хватает". Что самое забавное в режимах PRO Speed и PRO без Speed - картина не меняется.
PS: Других переменных типа bit кроме здесь показанных в программе нету если что.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Доброго времени суток. Взялся попробовать С. Ну так, самую малость, просто чтобы понять что я теряю, колупаясь в асме. Хочу значит установить предделитель Таймера0. Пишу:
В принципе устраивает (хотя я ручками покороче умею). Помню, что на асме можно удобно по именам битов устанавливать/сбрасывать. На всякий случай лезу в заголовочный файл на используемый МК, и нахожу там заветные строчки
Код:
/* OPTION bits */ volatile bit RBPU @ (unsigned)&OPTION*8+7; volatile bit INTEDG @ (unsigned)&OPTION*8+6; volatile bit T0CS @ (unsigned)&OPTION*8+5; volatile bit T0SE @ (unsigned)&OPTION*8+4; volatile bit PSA @ (unsigned)&OPTION*8+3; volatile bit PS2 @ (unsigned)&OPTION*8+2; volatile bit PS1 @ (unsigned)&OPTION*8+1; volatile bit PS0 @ (unsigned)&OPTION*8+0;
А понимать это так, что компилятор при нулевом уровне оптимизации: 1. Сгенерировал ДОСЛОВНЫЙ код. То есть сделал ровно то, что было написано на Си, включая промежуточные действия. 2. Обеспечил атомарность, выполняя п.1 Таким образом, сначала произвел действия с константами справа и лишь потом присвоил результат регистру option_reg. Как Вам передо мной уже сказали, заставить ДАННЫЙ компилятор выполнить битовую операцию при нулевой оптимизации можно макросом PS0=1.
Подскажите как реализовать такую штуку. Необходимо создавать "некие таймеры". Их число фиксировано и равно, допустим, 8. Есть один системный таймер T0. Он считает до 255 и объявляет tick. Дальше по этому tick инкрементируется rtc_timer (может быть long, тут дело не в этом).
Сам "некий таймер" представляет из себя структуру следующих параметров: -активный -начало -продолжительность -функция окончания
По определенному событию (это не важно) - таймер активируется. "активный" выставляется в 1, в начало записывается текущее значение rtc_timer.
Обработчик таймеров постоянно (каждый цикл) проверяет rtc_timer и начало и продолжительность активных таймеров. как только "начало+продолжительность">=rtc_timer - "активный"=0 и выполняется функция.
Вроде алгоритм понятен, а в структурах я чот туплю.
Заголовок сообщения: Re: Програмирование pic на СИ.
Добавлено: Ср фев 01, 2017 12:50:46
Модератор
Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4510 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Ну, примерно как то так :
Код:
typedef struct{ unsigned enabled :1; unsigned start :1; // Тут не понял, что за "начало" такое и зачем оно нужно... unsigned long time; void* call_back_func; // Тут, скорее всего будет не так, а указатель на созданный ранее тип каллбека. Это уже тонкости }Timer;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения