README.md

    mik32_picolibc


    Зачем?

    Собственно для использования Picolibc в проектах для MIK32 “Амур”


    Сборка

    Понадобится установленная сборочная система meson
    Понадобится установленный инструментарий riscv64-unknown-elf (например, установить пакет gcc-riscv64-unknown-elf)
    Подготовка к сборке

    • создать временный директорий, например mkdir -p ${HOME}/temp
    • перейти в созданный директорий, например cd ${HOME}/temp
    • склонировать проект, например git clone https://gitflic.ru/project/rabidrabbit/mik32_picolibc.git
    • создать директорий для сборки build-picolibc, например mkdir -p ${HOME}/temp/build-picolibc
    • перейти в созданный директорий, например cd ${HOME}/temp/build-picolibc
    • создать директорий для установки, например mkdir -p ${HOME}/tools/picolibc-mik32
    • запустить сборочную систему, например meson setup --cross-file ${HOME}/temp/mik32_picolibc/picolibc-mik32/scripts/cross-mik32-amur.txt -Dtests=false -Dmultilib=false -Dsemihost=false -Dnewlib-multithread=false -Dnewlib-retargetable-locking=false -Dprefix=${HOME}/tools/picolibc-mik32 -Dbuildtype=debugoptimized ${HOME}/temp/mik32_picolibc/picolibc-mik32
    • при отсутствии ошибок запустить сборку, команда ninja
    • при отсутствии ошибок запустить установку, команда ninja install (может потребовать ввод пароля для получения доступа к директорию инструментария riscv64-unknown-elf, т.к. устанавливается файл спецификации и скрипты линкера)
    • если установилось, то директорий с проектом ${HOME}/temp/mik32_picolibc и директорий для сборки ${HOME}/temp/build-picolibc можно удалить

    Применение

    Есть готовый пример
    А так, “для общего применения”, в файл с функцией main() нужно добавить следующее (можно в другой, но не забыть):

    #include <mik32_memory_map.h>  // это заголовок с описанием оборудования Mik32
    #include <uart.h>              // это заголовок с описанием блока UART
    
    #include <stdio.h>
    #include <string.h>
    
    __attribute__((used)) FILE __sf[2];
    __attribute__((used)) FILE * const stdin = &__sf[0];
    __attribute__((used)) FILE * const stdout = &__sf[1];
    __attribute__((used)) FILE * const stderr = &__sf[1];
    
    int mik32_putchar( char a_char, struct __file * ) {
      while ( 0 == (UART_0->FLAGS & UART_FLAGS_TXE_M) ) {}
      UART_0->TXDATA = a_char;
      return a_char;
    }
    
    int mik32_getchar( struct __file * ) {
      while ( 0 == (UART_0->FLAGS & UART_FLAGS_RXNE_M) ) {}
      return UART_0->RXDATA;
    }
    
    void local_init() {
      bzero( __sf, sizeof(__sf) );
      fdev_setup_stream( stdin, NULL, mik32_getchar, NULL, __SRD );
      fdev_setup_stream( stdout, mik32_putchar, NULL, NULL, __SWR );
    }
    

    И в самое начало функции main() добавить вызов функции local_init()
    Кроме этого, конечно, должна быть проведена инициализация UART_0, и это нужно сделать до первого использования функций из stdio.h
    Для сборки проектов под Mik32 с picolibc можно использовать такие параметры: riscv64-unknown-elf-gcc –specs=picolibc.specs -crt0=minimal -march=rv32imc_zicsr -mabi=ilp32 -L/usr/lib/gcc/riscv64-unknown-elf/12.2.0/rv32im/ilp32/
    Путь к библиотеке -L/usr/lib/gcc/riscv64-unknown-elf/12.2.0/rv32im/ilp32/ указывается для того, чтобы линкер нашёл libgcc.a (вроде необходимое оттуда перенесено в picolibc). Этот путь не потребуется, если для riscv64-unknown-elf есть цель сборки rv32imc. В другой версии gcc путь может отличаться.


    Полезные ссылки

    Описание

    Picolibc для Mik32 "Амур", совсем чуть-чуть подпилено для совместимости с Mik32.

    Конвейеры
    0 успешных
    0 с ошибкой