• Можете объяснить код на STM32?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    uint8_t led_state = 0x03; Данной командой мы завели переменную, которая равна 3

    В коде написано 2.

    что под этим подразумевается?

    2 -- это вот такое 8-битное двоичное число: 00000010. А если 2 заменить на 3, то число станет таким: 00000011. Улавливаешь связь с количеством и номерами включенных светодиодов?

    HAL_GPIO_WritePin(GPIOE, led_state << 8, GPIO_PIN_SET); Это я так понимаю мы сначала устанавливаем самый первый светодиод, т.е. 8, но на практике ни так.

    Нет, светодиоды на схеме подключены к битам 8..15, а led_state ты выше видел какое. Этой командой мы сдвигаем биты 0..7 led_state в биты 8..15.

    led_state = led_state >> 1 | led_state << 7;Эту строку совсем не понимаю.

    Это циклический сдвиг вправо на 1. Т.е. биты "выдвигаемые" вправо за пределы led_state появляются слева.
    т.е. двоичное число abcdefgh превращается в 0abcdefg | h0000000 = habcdefg.
    Ответ написан
    Комментировать
  • Как исправить "неопределённая ссылка на «http::server::server::run()"?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Взял первый пример HTTP сервера на официальном сайте Boost
    add_executable(main main.cpp)

    В "первом примере HTTP сервера" по твоей ссылочке файлов-то существенно больше, не один только main.cpp. Ты бы их добавил как-нибудь в список исходников, а то немного странно получается, ты не находишь? Глядишь среди них где-то найдётся и исходник определяющий http::server::server::server.
    Ответ написан
    3 комментария
  • Как ос генерируют виртуальные адреса, по которым будет поиск, не физические? Почему программы с одних адресов начинаются?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему программы с одних адресов начинаются?

    Потому что часть программ просто линкуется в одни и те же адреса. Это т.н. position-dependent executable, их в принципе невозможно загрузить для исполнения по другому адресу, и до недавнего времени (по крайней мере в linux) это было поведением по умолчанию. Но вот уже лет 10 во многих дистрибутивах по умолчанию используются PIE -- position-independent executables, и если не выключен ASLR, то при каждой загрузке часть адреса выбирается случайно. Но это сделано не для улучшения поведения TLB а для безопасности, поскольку это затрудняет атаки использующие известные адреса загрузки кода.

    Вот есть Tlb, представим это как линейный массив, или c , если все адреса будут одинаковы. То Очевидно что tlb будет работать в 1% своего множества

    Нет, не очевидно. Потому что никто не делает процессоры с пропорциональным отображением всего адресного пространства на все записи TLB. Обычно индексом записи TLB являются младшие биты номера страницы. Т.е. две соседние страницы могут использовать два соседних индекса в TLB, а канал TLB на 256 записей может быть полностью использован всего-то непрерывным мегабайтом памяти в 4-КБайтных страницах.
    Ответ написан
    Комментировать
  • Ошибка С2360, initialization of 'hInstanse' is skipped by 'case' label, почему?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    initialization of 'hInstanse' is skipped by 'case' label, почему?
    switch (uMsg)
    {
    ...
    case WM_CREATE:
    //получаем дескриптор приложения
    HINSTANCE hInstance = GetModuleHandle(0);
    ...
    break;
    
    case WM_MOUSEMOVE:
    //устанавливаем тот или иной курсор в зависимости от местонахождения мыши
    ...

    Потому что -- посмотри в этот код -- это фактически так: перейдя на метку WM_MOUSEMOVE код попадёт в область где hInstance определён, но минует его инициализацию. Компилятор туповат, чтобы понять, что hInstance дальше не используется. Простейший фикс -- обернуть код обработчиков в блоки:
    switch (uMsg)
    {
    ...
    case WM_CREATE:
    {
      //получаем дескриптор приложения
      HINSTANCE hInstance = GetModuleHandle(0);
      ...
    }
    break;
    
    case WM_MOUSEMOVE:
    {
      //устанавливаем тот или иной курсор в зависимости от местонахождения мыши
      ...
    }
    ...
    Ответ написан
    1 комментарий
  • Почему в git нет последовательного номера редакции по аналогии с svn?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В svn было довольно удобно ориентироваться на последовательные номера редакций.

    В git точно так же можно ориентироваться на вывод git describe, в котором присутствует ближайшая метка (или выбранная метка, если делать git describe --match 'mask'), количество коммитов после этой метки и хеш последнего коммита. Например, в одном и том же дереве linux я вижу:
    $ git describe
    xtensa-6.8-rc2-esp32-spi-8-gb25ff15921c2
    $ git describe --match 'v*'
    v6.8-rc2-52-gb25ff15921c2
    $ git describe --match 'v?.?'
    v6.7-13495-gb25ff15921c2

    голова отстоит на 8 коммитов от последней метки xtensa-6.8-rc2-esp32-spi, или на 52 коммита от последней официальной метки v6.8-rc2 или на 13495 коммитов от последнего релиза v6.7.
    Ответ написан
    Комментировать
  • Ошибка в подсчете символов, что делать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    считать количество русских букв, однако он не правильно это делает, что не так?

    считать русские буквы сложно, твой код зависит от кодировки и в любой не-однобайтной кодировке этот код не будет работать правильно. Проще всего, мне кажется, выкинуть charVector и весь код связанный с ним, а оставшееся переписать следующим образом:
    setlocale(LC_ALL, "");
    
    const char *str = input.c_str();
    
    while (*str) {
        wchar_t c;
        int n = mbtowc(&c, str, MB_CUR_MAX);
    
        if (n < 0)
            break;
        if (wcschr(L"абвгд...юя", c))
            ++count;
        str += n;
    }
    Ответ написан
    1 комментарий
  • Есть ли способ быстро выравнивать адреса?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    можно посчитать остаток от деления адреса на выравнивания, и затем прибавить его к адресу, но можно ли сделать это как-то быстрее? Например с помощью битовых операций.

    Можно, если выравнивание по степени двойки. addr = (addr + alignment - 1) & -alignment
    Ответ написан
  • Почему нет инфы о библиотеках в procfc файле maps, которые в сишном коде подключены и используются?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Компилирую gcc -o outfile source.c -lpthread. То есть собираю без всяких статиков, чтобы были зависимости к подключенным библиотекам. Далее запускаю процесс, чекаю /proc/pid/maps. Там нет ни единого упоминания к libpthread.

    100500 лет назад libpthread объединилась с glibc и теперь хоть и существует отдельно, чтобы программы использующие -lpthread продолжали собираться, внутри пустая. Короче, ты выбрал неудачного кандидата для экспериментов.
    Ответ написан
    Комментировать
  • Почему появляется ошибка make: *** [Makefile:15: leak] Ошибка 1 при выполнении Makefile на C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    make: *** [Makefile:15: leak] Ошибка 1

    В linux это код ошибки "нет доступа". Начни с проверки что $(NAME) доступен для чтения и выполнения.
    Кроме того, для полноты картины стоит показывать полный лог выполнения команды make, а не только последнее сообщение об ошибке.
    Ответ написан
  • Почему в Си после main() не ставят ;?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему в Си после main() не ставят ;?

    в С при определении функции не ставят ; между объявлением и телом функции, не только для main, но и для любой другой функции. Согласно стандарту языка, например С99 приводит следующий синтаксис определения функции:
    function-definition:
        declaration-specifiers declarator declaration-list<opt> compound-statement
    declaration-list:
        declaration
        declaration-list declaration


    Этот синтаксис включает в себя также старый формат определения функции (без прототипа), в котором все аргументы должны быть объявлены между закрывающей круглой скобкой и открывающей фигурной, например (из того же стандарта):
    extern int max(a, b)
    int a, b;
    {
        return a > b ? a : b;
    }

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

    эта строка работает на другом языке?

    о каком "другом" языке речь?
    Ответ написан
    2 комментария
  • HEX значение возвращается неправильно, почему?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему

    Потому что Serial.println печатает то, что ты передаёшь ей на вход, а ты передаёшь ей на вход values[0][0] -- это один символ, '8'.

    как это решить?

    Понять, что ты хочешь напечатать и организовать данные для печати правильным образом. Сейчас определение массива values говорит о полном непонимании того, что происходит. Если ты хотел инициализировать массив кодами символов, то не нужно было брать коды в одиночные кавычки, это превратило их в символьные литералы. Значения типа char не могут вместить больше чем 8 битов, а 0xe918 -- 16-битное число. Если это симовл unicode в кодировке utf-8, то его байты должны идти как отдельные символы. Если ты собираешься печатать отдельные байты закодированных utf-8 символов, то не нужно делать этого функцией println, потому что она вставит символ конца строки после печати каждого символа.
    Если ты хотел напечатать шестнадцатеричные значения, ты мог сделать это так:
    unsigned int values[][6] = {
      {0xE918, 0x14, 0xE918, 0x49, 0xE918, 0x48}
    };
    …
    Serial.println(values[0][0], HEX);


    Короче, начни с того чтобы понять, что ты хочешь напечатать.
    Ответ написан
    Комментировать
  • Как реализовать кроссплатформенную поддержку Unicode в аргументах командной строки в C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Соответственно, мне нужно конвертировать массив wchar_t в массив char перед шифрованием, а после дешифровки выполнять обратную конвертацию.

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

    Я поменял сигнатуру функции main() на int main(int argc, wchar_t* argv[]) (пытался исправлять на wmain, но тогда ругается ld и сборка падает с ошибкой).

    То, что ты меняешь прототип main, никак не влияет на то, как она будет реально вызвана. В стандарте языка C написано, каким может быть прототип main: int main(void), int main(int argc, char *argv[]) или эквивалентным. Там же написано, что набор символов во время выполнения программы -- implementation defined, поэтому нет гарантии, что их можно обработать кросплатформенно.

    Для конвертации wchar_t* в char* я пробовал использовать функцию wcstombs, однако почему-то у меня она совершенно не работает (при попытке преобразовать строку, содержащую только латиницу, я получаю null).

    wcstombs не занимается выделением памяти, если ты "получаешь null" -- это происходит в каком-то другом месте. Ну и если ты это делаешь внутри main принимающего wchar_t* argv[], то твой код интерпретирует строку char как строку wchar_t, что добавляет хаоса.
    Ответ написан
  • Скомпилированный в GCC exe файл вылетает досрочно?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Но в режиме отладки всё, как я уже писал выше, работает.

    Да не, это только видимость. Смотри:

    $ gcc -std=c99 -O2 -g3 -fsanitize=address main.c acp.c md5.c -o main
    $ ./main
    Base64('Hello') = "SGVsbG8="
    MD5('Hello') = "8b1a9953c4611296a827abf8c47804d7"
    =================================================================
    ==1045705==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000000071 at pc 0x7fb0d46486f8 bp 0x7ffd0affb580 sp 0x7ffd0affad30
    WRITE of size 33 at 0x604000000071 thread T0
        #0 0x7fb0d46486f7 in __interceptor_strcat ../../../../src/libsanitizer/asan/asan_interceptors.cpp:377
        #1 0x564b2388c0de in prepareKeys /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:263
        #2 0x564b2388cac4 in acraw /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:319
        #3 0x564b2388d8c2 in acraws /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:401
        #4 0x564b2388d8c2 in acraws_basic /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:409
        #5 0x564b2388a62e in testSimpleEncryption /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main.c:20
        #6 0x564b2388a368 in main /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main.c:111
        #7 0x7fb0d44461c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
        #8 0x7fb0d4446284 in __libc_start_main_impl ../csu/libc-start.c:360
        #9 0x564b2388a440 in _start (/home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main+0x3440)
    
    0x604000000071 is located 0 bytes to the right of 33-byte region [0x604000000050,0x604000000071)
    allocated by thread T0 here:
        #0 0x7fb0d46b89cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
        #1 0x564b2388fee7 in md5StringHash /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/md5.c:227
    Ответ написан
  • Как исправить ошибку worktree при удалении ветки с локального пк?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    git говорит тебе о том, что ветка которую ты хочешь удалить вычекнута в отдельный рабочий каталог. Если она тебе действительно не нужна, удали рабочий каталог (git worktree remove C:/Projects/web_test), после чего повтори команду удаления ветки.
    Ответ написан
    3 комментария
  • Не работает код, что не так?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    что не так
    mov ecx, 5 ; Загружает количество гласных

    inc ecx ; Увеличивает счетчик гласных

    loop checkVowels ; Переходит к проверке следующей гласной

    test ecx, ecx ; Проверяет, содержится ли гласная буква в слове

    ты используешь ecx для двух разных целей, и, похоже, не догадываешься об этом. Из цикла поиска гласных ecx выходит со значением 0 если последняя буква слова -- не гласная.
    Ответ написан
    Комментировать
  • Не могу залить прошивку на ESP-32 CAM?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Никак не пойму в чём дело
    Brownout detector was triggered

    Контроллер перезагружается по защите из-за недостаточного питания.
    Ответ написан
    5 комментариев
  • Как прошить ESP32 CAM программатором ESP-32-CAM-MB?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    правильно ли, что на программаторе уже замкнуты контакты?

    Нет, неправильно. Нижняя сопля соединяющая GND и U0TX точно не нужна, она тупо не даёт esp32 отвечать по UART. Верхняя сопля соединяет GPIO0 и GND, что нужно для начала прошивки, но на плате программатора и так есть кнопка с той же самой функцией.
    Вообще для начала прошивки нужно выполнить сброс (кнопкой RST) и на момент сброса соединить GPIO0 и GND (кнопкой IO0 на программаторе). После такого сброса контроллер можно прошивать.
    Я рекомендую убрать обе сопли с программатора и попробовать описанную выше процедуру.
    Ответ написан
    8 комментариев
  • Может ли язык Си работать на условной stack-based машине?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Может ли язык Си работать на условной стековой машине? … В виде стековой машины я имею в виду условную машину Тьюринга

    Есть такая штука, тезис Чёрча — Тьюринга, которая говорит, что любой алгоритм может быть реализован машиной Тьюринга.

    Будут ли какие-то проблемы для генерации кода из Си в ассемблер для подобной машины?

    Для этого надо уточнить, что такое "проблемы".
    Ответ написан
  • Какое ядро использует Debian?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В оригинальном ядре linux есть несвободные прошивка и блобы

    Это неверное заявление. Ядро Торвальдса (вы же его называете "оригинальным"?) доступно в виде исходников под набором свободных лицензий. Но часть этих исходников -- это драйвера устройств, для работы которых требуется firmware, возможно проприетарное. Если собрать такое ядро, то оно будет полностью свободным, но ряд устройств для работы потребует проприетарных блобов, не являющихся частью ядра. Несвободные компоненты в принципе не могут стать частью этого ядра из-за конфликта лицензий.

    какое ядро всё-таки использует Debian ?

    Можно тупо взять и посмотреть, например для debian 12: https://packages.debian.org/source/bookworm/linux
    Внизу страницы есть ссылки на архив с исходниками ядра (это копия ядра из ветки stable) и на архив исходников debian-пакета, а также ссылка на git последнего.
    Ответ написан
    Комментировать
  • Как создать правило make для компиляции списка .c в список .out?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    У меня имеется список исходных файлов и список файлов в которые они должны быть скомпилированы.

    SRCS = ./a/prog1.c ./a/b/prog2.c ./a/b/c/prog3.c
    OUTS = ./outs/prog1.out ./outs/prog2.out ./outs/prog3.out

    Это не очень удачная конфигурация, в том смысле, что немного изменив условия можно сильно упростить Makefile, но если очень хочется именно такого, то можно сделать так:

    .PHONY: all
    
    SRCS = ./a/prog1.c ./a/b/prog2.c ./a/b/c/prog3.c
    OUTS = ./outs/prog1.out ./outs/prog2.out ./outs/prog3.out
    
    all: $(OUTS)
    
    define make_rule =
    $(firstword $(1)): $(firstword $(2))
            @echo compile $$< to $$@
            gcc $$< -o $$@
    $(if $(wordlist 2,$(words $(1)),$(1)),
         $(eval $(call make_rule,
                       $(wordlist 2,$(words $(1)),$(1)),
                       $(wordlist 2,$(words $(2)),$(2)))))
    endef
    
    $(eval $(call make_rule,$(OUTS),$(SRCS)))


    Здесь происходит вот что: макрос make_rule принимает на вход два списка, создаёт правило, что первое слово из первого списка зависит от первого слова из второго списка, а потом вызывает сам себя со списками из которых удалены первые слова, если эти списки не пустые.
    Ответ написан
    6 комментариев