Doque Embedded
Ir al canal en Telegram
3 569
Suscriptores
+124 horas
+117 días
+3830 días
Archivo de publicaciones
3 569
Repost from Меня заставили создать канал
Только что случился исторический момент.
В dev-ветку прошивки Flipper Zero влили пулл реквест с поддержкой FAP.
FAP — Flipper Application Package.
Эта фича позволяет скачивать неограниченное количество приложений на SD-карту Флиппера и запускать их оттуда, не перепрошивая устройство каждый раз. Раньше, чтобы добавить приложение, нужно было вкомпилировать его в ядро, в саму прошивку.
Считаю, что это один из самых важных шагов в развитии Флиппера, благодаря которому появятся сотни приложений от сторонних разработчиков. Ну помните, как на iPhone только через пару лет появился App Store? Кстати, «стор» тоже будет. Правда все приложения в нём будут бесплатными и с открытым исходным кодом.
3 569
Repost from Меня заставили создать канал
PayPal нагло отжал у нас $1,300,000 и отказывается возвращать, несмотря на соблюдение нами всех требований.
Мы далеко не первый бизнес, страдающий от этого мошенничества.
В 2022 году есть множество современных средств оплаты вроде Apple Pay и Google Pay, которые удобны и безопасны для всех участников транзакций. Банки и страховые компании успешно обеспечивают сохранность средств, взимая за свою работу меньшие комиссии, чем PayPal.
Использовать PayPal сегодня — вредная привычка, и лучше бросить её сегодня.
https://twitter.com/flipper_zero/status/1567194641610465281
3 569
Чуваку не понравилось как в играх звучат моторы, и он за пару месяцев написал физически точный симулятор звука двигателя.
Мякотка в том что ему для этого понадобилось написать физически (достаточно) точный симулятор работы двигателя, с физикой твердого тела, газодинамикой и виртуальным диностендом.
https://youtu.be/RKT-sKtR970
3 569
Да, оно работает.
let thread = fficall(arg.pointer, "furi_thread_get_current");
let thread_id = fficall(arg.pointer, "furi_thread_get_id", arg.pointer, thread);
let thread_name = fficall(arg.string, "furi_thread_get_name", arg.pointer, thread_id);
print(thread_name);
66332 [I][JS] {
66333 [I][JS] FFI: furi_thread_get_current = 0x08010601
66335 [I][JS] FFI: args count 0
66338 [I][JS] FFI: ret pointer 0x20002E68
66340 [I][JS] }
66342 [I][JS] {
66343 [I][JS] FFI: furi_thread_get_id = 0x08010591
66346 [I][JS] FFI: args count 1
66348 [I][JS] FFI: arg 0 ptr = 20002e68
66350 [I][JS] FFI: ret pointer 0x20009BE0
66352 [I][JS] }
66353 [I][JS] {
66355 [I][JS] FFI: furi_thread_get_name = 0x08010845
66357 [I][JS] FFI: args count 1
66359 [I][JS] FFI: arg 0 ptr = 20009be0
66361 [I][JS] FFI: ret string Java Script
66363 [I][JS] }
"Java Script"3 569
Портирую кусочек компилятора Kotlin’a чтобы JavaScript мог вызывать нативные Cишные функции через внутренний механизм ELF Loader’а. Хорошо что наш ДМС покрывает психиатра.
3 569
Взрывает мозг. ELF файл загруженный с СД карты в память загружает в память JS-скрипт и выполняет его.
3 569
Чилийский художник PEPEGR∆PHIX - большой любитель ретро игр. Он придумал своего персонажа и таким образом пародирует рекламу со старых японских журналов 80-х. Выглядит очень атмосферно. 🔥🧡
3 569
Repost from Бодя в Проде | Геймификация и спецпроекты
Неочевидных игровых механик пост
Взрыв эмоций каждый раз, когда натыкаюсь на гениальные и простые игровые механики, переосмысляющие привычные нам вещи.
Пример — вот вроде бы клавиатура, используется для управления в играх, wasd и все дела. А что если изменить привычный UX и сделать клавиатуру частью геймплея? — БУМ, магия 🧚♀️
Поиграться можно тут
Увидел тут
За наводку спасибо Витале Веберу 😘
3 569
Repost from Меня заставили создать канал
Дельфин унижает робо-собаку без регистрации и смс:
https://twitter.com/d0tslash/status/1555326302462394370
3 569
Как обмануть и унизить компилятор.
На заре прошивки Flipper Zero нам понадобилось перенести функцию strdup (выделение места и копирование в него строки) в наш код, чтобы эффективнее использовать heap операционной системы.
На днях я решил что неплохо бы добавить рантайм-проверку на разыменование NULL, через MPU и столкнулся с тем что при передаче в strdup NULL - ловится разыменование в strlen. Вот это поворот подумал я, давайте посмотрим на исходник функции.
char* strdup(const char* s) {
const char* s_null = s;
if(s_null == NULL) {
return NULL;
}
size_t siz = strlen(s) + 1;
char* y = pvPortMalloc(siz);
memcpy(y, s, siz);
return y;
}
Как видно, в начале странным образом (напомню, это код написанный нами) производится проверка на NULL и выполнение дальше идти не должно. Еще одна зацепка к происходящему получилась когда я попробовал явно передать NULL в strdup:
error: null argument where non-null requiredОкей, давайте обманывать компилятор.
void* absolutely_not_null(){ return NULL; }
strdup(absolutely_not_null());
Компилятор теперь не ругается, но выполнение опять падает на strlen с ошибкой разыменования NULL. Проверка явно есть в коде но не производится. Кстати, почему она так странно реализована? Давайте напрямую проверим аргумент.
if(s == NULL) return NULL; error: 'nonnull' argument 's' compared to NULLАга, вот почему оно было так странно написано, и вот ответ на наши странности. Аргумент функции в недрах stdlib помечен как nonnull, так что компилятор выкидывает ненужную по его мнению проверку. Но мы же его уже обманывали, давайте обманем еще раз:
void* absolutely_not_null(){ return NULL; }
if(s == absolutely_not_null) return NULL;
К сожалению компилятор и это детектит как ненужную проверку. Что мы еще можем сделать?
if(1 / ((uint32_t)s + 1) == 1) {
return NULL;
}
И это тоже детектируется как проверка на NULL.
if(((uint32_t)s << 1) == 0) {
return NULL;
}
А вот сдвиг оказался более странной для компилятора операцией, и эта проверка не была выкинута.
Теперь я сделал ассерт в этом месте, и пофиксил места где была возможная протечка NULL в strdup, надеюсь больше с подобными странностями у нас не будет проблем.
¡Ya disponible! Investigación de Telegram 2025 — los principales insights del año 
