электроника сәнгате
646 subscribers
632 photos
71 videos
56 files
319 links
сәлам дуслар! здесь схемотехника, pcb дизайн, микроконтроллеры, линукс встроенный и десктопный
Download Telegram
Forwarded from Канал схемотехника-программиста (Дмитрий Кузьмичев)
Особенности микроконтроллеров от Espressif💎

Речь пойдёт именно о серии ESP32.
- ESP32 - только у него есть классический Bluetooth, годится для многих классических применений, в частности, для Bluetooth-аудиосистем
- ESP32S2 - может удерживать подключение к WiFi даже находясь в некоторых спящих режимах, но одноядерный во всех вариациях; первый контроллер с поддержкой Flash до 128 МБ, интерфейсом под дисплей и USB
- ESP32S3 - 2 ядра и варианты с бОльшим количеством Flash и PSRAM (PSRAM до 16 МБ); даа варианта ULP-сопроцессора: FSM (который на ассемблере), и RISC-V
- ESP32C3 - первый контроллер на RISC-V-ядре; как правило, имеют встроенную Flash на 4 МБ
- ESP32C6 - первый контроллер с поддержкой WiFi 6 (но только в 2.4 ГГц)
- ESP32H2 - контроллер с беспроводным интерфейсом, но без WiFi, только BLE/ZigBee/Thread
- ESP32P4 - первый контроллер со вторым USB 2.0, есть MIPI-интерфейсы под дисплей и камеру, Ethernet, но нет своего беспроводного интерфейса (если нужен, подключается внешний контроллер с беспроводным интерфейсом и используется esp-hosted)
- ESP32C5 - первый контроллер с 5 ГГц
🔥6👍1
#bootloader #bluepill
Поправил амурский бутлоадер для того чтоб он подходил для BluePill-MIK32 🔥

В файле bootloader.c добавил дефайн, для ELBEAR'a - BOOT_UART_0, для BluePill - BOOT_UART_1 👈

В Makefile в OPENOCD_CFG необходимо выбрать m-link для ELBEAR’a или blue_prog для BluePill 🙃

Заморочки были с флеш памятью, разобрался наконец-то, для BluePill выставил режим QSPI, для ELBEAR'а подходит QPI 🤷‍♂

Ну и основной нюанс, это то что на "таблетке" нет ноги DTR на TTL-конвертере, это значит что в начале загрузки нужно жать кнопку ресет, главное вовремя попасть. Я быстро приловчился и у вас получится 😉
🔥3
Сегодня попался, наверное, самый подробный гайд по основам проектирования для 3D-печати (FDM/FFF) из всех какие я видел.

Монументальный, отлично структурированный и красиво оформленный пост в блоге (с чеклистом!), который построен по принципу: золотое правило + его иллюстрированное объяснение. Таких правил там больше 40 штук.

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

Если честно, некоторые кусочки я бы предложил почитать даже тем инженерам по механике, которые проектируют под субтрактивные способы производства и даже литьё. А то бывает такое начертят, что потом стыдно китайцам показывать. 😀

Уверен: каждый найдёт там для себя что-то новое и полезное. Страница отлично сохраняется в pdf, если вы такое любите.

https://blog.rahix.de/design-for-3d-printing/
3👍104
Forwarded from Embedded Doka (Dmitry Murzinov)
Чувак заморочился и полностью разреверсил Raspberry Pi Compute Module 5 gen

🐱https://github.com/schlae/cm5-reveng

Fun facts:

▫️Для выполнения работы использовались: сканер 9600 DPI, LCR-метр и VNA
▫️Схематик и PCВ выполнены в KiCad 9.
▫️PCВ 10-ти слойная (использованы buried via и microvia)
▫️Резисторы задания размера RAM & FLASH не 0-омные: каждая потенциальная позиция должна иметь специфический номинал и образует делитель, напряжение с которого считывается встроенным в RP1 АЦП
▫️Между BCM2712 и RP1 используется загадочный интерфейс на диффпарах (автор проекта предполагает что это PCIe)
▫️Использован очень навороченный PMIC (хотя кажется это тенденция последних лет 10), автор намерен похекать его I2C карту регистров
▫️Не использовать для воспроизводства: для высокоскоростных цепей не везде учтён Signal Integrity, некоторые футпринты "приблизительные"

@embedoka
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8
Вот нам с вами повезло работать на рынке, на котором государство разбрасывает деньги с вертолёта, чтобы потом пересажать, всех, кто эти деньги неосторожно забирал.

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

На рынке, где в коммерческом сегменте ты конкурируешь с дешеёвыми и быстрыми китайцами, а в госсекторе — с теми, кто взял денег у государства и госбанков.

С другой стороны, никто не обещал, что будет легко. Вот в какой-нибудь Киргизии или Нигерии вообще никакой электроники нет, всё везут из Китая.
💯106💩22
Принято считать, что язык Си очень простой. Оригинальная книжечка Кернигана и Ритчи — это всего 200 страниц. Однако, учитывая специфику применения Си (низкоуровневые приложения), здесь можно найти немало тонкостей, о которых мало где слышно.

Я решил написать несколько заметок о неочевидных приколах языка Си.
🔥72👍1
⚡️Битовые поля.
Часто одна байтовая переменная содержит несколько значащих бит, обозначающих что-то сепаратное, и эти биты обычно приходится выделять масками. Не приходится, если использовать битовые поля.
Пример.
typedef union
{
uint8_t all;
struct
{
uint8_t idle_state : 1;
uint8_t erase_reset : 1;
uint8_t illegal_command : 1;
uint8_t crc_error : 1;
uint8_t erase_sequence_error : 1;
uint8_t address_error : 1;
uint8_t parameter_error : 1;
uint8_t __res : 1;
};
} MIK32SD_R1_Response_TypeDef;

Ответ SD-карты типа R1 легко разобрать побитово, если байтовый ответ присвоить члену all, а затем в отдельных if'ах проверить каждый бит.
🔥7
⚡️alignment

В большинстве современных систем минимальный адресуемый объём информации — один байт. Как удобно было работать с восьмиразрядками, у которых машинное слово — тоже один байт! Можно было безболезненно и просто обращаться к любой ячейке памяти.

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

Выход: сделать систему чтения памяти, которая всегда читала бы 32-разрядное слово, чей адрес описывается битами A31-A2. При команде lw (чтение 32 бит) слово сразу бы передавалось в регистр. При команде lb (чтение 8 бит) конкретный байт выбирался бы битами A1 и A0 и передавался бы в младший значащий байт регистра. При команде lh (чтение 16 бит) нужное полуслово выбиралось бы битом A1 и следовало бы в младшее значащее полуслово регистра.

Собственно, так и сделано в RISC-V.

Из минусов: команда lw применима только к двоичным адресам, которые оканчиваются на 2 нуля. То есть, обратиться в ячейку 0x1234 можно, а 0x1235 — нет, процессор выкинет исключение "load address misaligned", "адрес загрузки не выровнен". Аналогичная ситуация с командой lh, она неприменима к нечетным адресам.

Компилятор, зная данную особенность процессора, размещает переменные в памяти как надо, чтобы не вызывать конфликтов выравнивания при обращении и использовать статическую память оптимально.

Однако есть 2 вещи, где порядок переменных пользователь определяет сам: структуры и аргументы функций. Аргументы функций сейчас трогать не будем, а вот структуры рассмотрим подробнее.

Я создал тип данных-структуру:
typedef struct
{
uint32_t dummy1; //4
uint8_t dummy2; //1
uint32_t dummy3; //4
uint8_t dummy4; //1
uint8_t dummy5; //1
} my_struct_t;

И вроде бы она должна занимать в памяти 4+1+4+1+1=11 байт, но если посмотреть размер через sizeof, получим:
Size of struct: 16
Object address: 02003FE0

На поле dummy1 компилятор выделяет 4 байта. Адрес начала объекта-структуры делится на 4 нацело. Если бы на dummy2 был выделен 1 байт, то абсолютный адрес dummy3 уже не был бы кратен 4, и процессор не смог бы быстро читать поле dummy3. Поэтому на dummy2 выделяется аж 4 байта, где 3 байта никак не используются, это пустышки. Чтобы адреса переменных за структурой были так же выровнены, после полей dummy4 и dummy5 идут еще 2 байта-пустышки. Итого получаем 16.

5 байт драгоценной ОЗУ улетели в трубу. Ужас!
Иногда экономия памяти важнее производительности, и на этот случай в компиляторах GCC существует атрибут packed:
typedef struct __attribute__((packed))
{
uint32_t dummy1; //4
uint8_t dummy2; //1
uint32_t dummy3; //4
uint8_t dummy4; //1
uint8_t dummy5; //1
} my_struct_t;

В этом случае структура будет плотно "сжата", и пустышек не будет:
Size of struct: 11
Object address: 02003FE4

Но в то же время обращение к полю dummy3 очень сильно усложнится. Для простого чтения поля процессору придется дважды читать 32-разрядные ячейки, дважды применять инструкцию сдвига и еще применить инструкцию логического ИЛИ. Атрибут packed — это очень радикальная вещь, и лучше его не использовать. Вместо этого предлагается оптимальнее расставлять переменные в структуре.
typedef struct
{
uint32_t dummy1; //4
uint32_t dummy3; //4
uint8_t dummy2; //1
uint8_t dummy4; //1
uint8_t dummy5; //1
} my_struct_t;

Здесь компилятору приходится вводить лишь одну пустышку, и память удается сэкономить.
Size of struct: 12
Object address: 02003FE4
🔥4
⚡️alignment-2

Собственно, слово "alignment" означает "выравнивание". В 16-разрядных машинах адреса переменных выравниваются по 2 байта, в 32-разрядных — по 4 байта. Но иногда нам нужно выровнять переменные так, чтобы их адреса были кратны какой-то большей степени двойки. Для этого в GCC существует атрибут aligned.

Рассмотрим на примере.
typedef struct __attribute__((aligned(8)))
{
uint32_t dummy1; //4
uint32_t dummy3; //4
uint8_t dummy2; //1
uint8_t dummy4; //1
uint8_t dummy5; //1
} my_struct_t;

Size of struct: 16
Object address: 02003FE0

Структура начала занимать 16 байт, хотя поля расположены в правильном порядке. Обращаем внимание на адрес: он кратен 8. Для наглядности попробуем выровнять по большему значению.
typedef struct __attribute__((aligned(128)))
{
uint32_t dummy1; //4
uint32_t dummy3; //4
uint8_t dummy2; //1
uint8_t dummy4; //1
uint8_t dummy5; //1
} my_struct_t;

Size of struct: 128
Object address: 02003F00

Адрес действительно выравнивается, теперь он стал кратен 128.
Кстати, интересно, что абсолютное значение адреса уменьшилось. Это потому что я создаю объект в теле функции main, не помечая его ключевыми словами volatile или static, и этот объект лоцируется в область стека, которая растет сверху вниз. То, что адрес стал меньше, значит, что под объект было выделено больше памяти в стеке.

P.S. Кстати, атрибут aligned сильнее, чем атрибут packed. Если написать так:
typedef struct __attribute__((aligned(128), packed))
{
uint32_t dummy1; //4
uint32_t dummy3; //4
uint8_t dummy2; //1
uint8_t dummy4; //1
uint8_t dummy5; //1
} my_struct_t;

Результат будет тот же, что и раньше.
Size of struct: 128
Object address: 02003F00
🔥5
⚡️restrict-указатели

Появились в Си не сразу, в 1999 году, оттого почему-то малораспространены.

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

Можно сравнить 3 вида указателей:
volatile-указатели;
• обычные указатели;
restrict-указатели.

Рассмотрим случай, когда имеем дело с указателем на структуру, внутри которой есть поле "счетчик". Каждое обращение через volatile-указатель неизбежно ведет к обращению в память. При использовании restrict-указателя при частых обращениях к счетчику поле будет скопировано в регистр, и при обращении к нему будет применяться регистровая адресация, гораздо более быстрая, нежели обращение в память. При использовании обычного указателя будет что-то среднее — в одних случаях то, в других это. В целом надо учиться по-максимуму использовать restrict-указатели там, где можно, особенно в однозадачных приложениях.
int mik32fat_wheels_single_read(void *__restrict cookie, uint32_t sector_addr, uint8_t *dst);
🔥6
«Кошечка» — советский мультфильм, созданный в 1968 году с помощью машины БЭСМ-4. Один из первых примеров компьютерной анимации.

Кадры фильма формировались путём печати символов БЭСМ-4 на бумаге с помощью алфавитно-цифрового печатающего устройства АЦПУ-128, затем их готовил к «плёнке» профессиональный художник-мультипликатор. Именно ему принадлежат кадры (следующие за титрами), когда кошка строит рожицы и выгибает спину.

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

Другим важным техническим нововведением мультфильма было представление трёхмерного анимируемого объекта в виде иерархической структуры данных, напоминающей октодерево. На западе подобные техники анимации были переоткрыты только в 1980-х годах, хотя в биомеханике такие расчёты движения велись и раньше — с начала 1970-х годов.

Уравнения мультфильма не выводились исходя из физических моделей мышц и суставов животного, они составлены «на глазок», чтобы воспроизводить типичную походку кошки. Тем не менее, авторам удалось достигнуть реализма движений, который отметил, к примеру, профессор Университета Огайо Рик Парент, автор фундаментальной книги «Компьютерная анимация: алгоритмы и технология».

В комментариях будет полная статья по данной научной работе.
17👍311
Сегодня на канале опубликован обзор на BUSY Bar - девайс, помогающий сконцентрироваться на важных задачах.
В обзоре вас ждут:
- фишки и особенности
- создание интеграции с девайсом с помощью chatGPT и HTTP API
- бесплатное приложение BUSY
- разборка девайса
- средства отладки
- железячная эстетика

Приятного просмотра!

BUSY Bar. Большой обзор
https://youtu.be/rHnStTAFY_c
🔥4🥰1🤔1