All Projects → cpq → mdk

cpq / mdk

Licence: MIT License
A bare metal SDK for the ESP32 & ESP32C3

Programming Languages

c
50402 projects - #5 most used programming language
Makefile
30231 projects
shell
77523 projects

Projects that are alternatives of or similar to mdk

X86 Bare Metal Examples
Dozens of minimal operating systems to learn x86 system programming. Tested on Ubuntu 17.10 host in QEMU 2.10 and real hardware. Userland cheat at: https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly ARM baremetal setup at: https://github.com/cirosantilli/linux-kernel-module-cheat#baremetal-setup 学习x86系统编程的数十个最小操作系统。 已在QE…
Stars: ✭ 3,985 (+10386.84%)
Mutual labels:  bare-metal, baremetal
stm32mp1-baremetal
Baremetal framework and example projects for the STM32MP15x Cortex-A7 based MPU
Stars: ✭ 43 (+13.16%)
Mutual labels:  bare-metal, baremetal
bare bones
Ada Bare Bones OS development tutorial source code
Stars: ✭ 74 (+94.74%)
Mutual labels:  bare-metal, baremetal
metalnetes
Create and manage multiple Kubernetes clusters using KVM on a bare metal Fedora 29 server. Includes helm + rook-ceph + nginx ingress + the stock analysis engine (jupyter + redis cluster + minio + automated cron jobs for data collection) - works on Kubernetes version v1.16.0 - 1.16.3 was not working
Stars: ✭ 37 (-2.63%)
Mutual labels:  bare-metal, baremetal
rackshift
RackShift 是开源的裸金属服务器管理平台,功能覆盖裸金属服务器的发现、带外管理、RAID 配置、固件更新、操作系统安装等。
Stars: ✭ 467 (+1128.95%)
Mutual labels:  bare-metal, baremetal
hftrx
Embedded firmware for ham radio transceivers
Stars: ✭ 27 (-28.95%)
Mutual labels:  bare-metal, baremetal
ESP-Mail-Client
⚡️Arduino Mail Client Library to send, read and get incoming mail notification for ESP32, ESP8266 and SAMD21 devices. The library also supported other Arduino devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient.
Stars: ✭ 78 (+105.26%)
Mutual labels:  esp32
openocd cmsis-dap v2
支持CMSIS-DAP v2接口协议,支持ARM、RISCV、ESP32等目标芯片,详见Wiki及release
Stars: ✭ 26 (-31.58%)
Mutual labels:  esp32
RFLink
RFLink for ESP, with MQTT client
Stars: ✭ 52 (+36.84%)
Mutual labels:  esp32
drone-cortexm
ARM® Cortex®-M platform crate for Drone, an Embedded Operating System.
Stars: ✭ 31 (-18.42%)
Mutual labels:  bare-metal
async
🔀 Asynchronous framework in C.
Stars: ✭ 16 (-57.89%)
Mutual labels:  bare-metal
esp32WS2811
Arduino library for ESP32 to drive WS2811 LEDs using the RMT peripheral
Stars: ✭ 22 (-42.11%)
Mutual labels:  esp32
coffee-scale-app
Firmware and Progressive Web App to connect to a DIY bluetooth enabled coffee and espresso scale.
Stars: ✭ 31 (-18.42%)
Mutual labels:  esp32
ESP32AudioFramework
Dual core concurrent multi-task processing of continuous real-time audio on the ESP-32
Stars: ✭ 35 (-7.89%)
Mutual labels:  esp32
houseflow
Home automation platform for microcontrollers(including ESP8266/ESP32), Raspberry Pi, and others. Made with Rust and C++.
Stars: ✭ 88 (+131.58%)
Mutual labels:  esp32
NMEA2000WifiGateway-with-ESP32
This repository shows how to build a NMEA2000 WiFi Gateway with voltage and temperature alarms.
Stars: ✭ 38 (+0%)
Mutual labels:  esp32
micropython-i2s-examples
Examples for I2S support on microcontrollers that run MicroPython
Stars: ✭ 40 (+5.26%)
Mutual labels:  esp32
Farm-Data-Relay-System
A system that uses ESP-NOW, LoRa, and other protocols to transport sensor data in remote areas without relying on WiFi.
Stars: ✭ 97 (+155.26%)
Mutual labels:  esp32
Train plus plus
Repo and code of the IEEE UIC paper: Train++: An Incremental ML Model Training Algorithm to Create Self-Learning IoT Devices
Stars: ✭ 17 (-55.26%)
Mutual labels:  esp32
esp32-flite
Speech synthesis running on ESP32 based on Flite engine.
Stars: ✭ 28 (-26.32%)
Mutual labels:  esp32

MDK (Minimal Development Kit) - a baremetal ESP32/ESP32C3 SDK

A bare metal make-based SDK for the ESP32/ESP32C3 chips. Written from scratch using datasheets ( ESP32 C3 TRM, ESP32 TRM). It is completely independent from the ESP-IDF and does not use any ESP-IDF tools or files. The only requirement is GCC crosscompiler.

A screenshot below demonstrates a examples/c3ws2812 RGB LED firmware flashed on a ESP32-C3-DevKitM-1 board. It takes < 2 seconds for a full firmware rebuild and flash:

Environment setup

  1. Use Linux or MacOS. Install Docker
  2. Execute the following shell commands (or add them to your ~/.profile):
$ export MDK=/path/to/mdk                 # Points to MDK directory
$ export PORT=/dev/ttyUSB0                # Serial port for flashing

Verify setup by building and flashing a blinky example firmware. From repository root, execute:

$ make -C examples/blinky clean build flash monitor

Firmware Makefile

Firmware Makefile should look like this:

SOURCES = main.c another_file.c

EXTRA_CFLAGS ?=
EXTRA_LINKFLAGS ?=

include $(MDK)/make/build.mk

Environment reference

  • Environment / Makefile variables:
    • ARCH - Architecture. Possible values: esp32c3, esp32, posix. Default: esp32c3
    • TOOLCHAIN - GCC binary prefix. Default: riscv64-unknown-elf
    • PORT - Serial port for flashing. Default: /dev/ttyUSB0
    • FLASH_PARAMS - Flash parameters, see below. Default: empty
    • FLASH_SPI - Flash SPI settings, see below. Default: empty
    • EXTRA_CFLAGS - Extra compiler flags. Default: empty
    • EXTRA_LINKFLAGS - Extra linker flags. Default: empty
  • Makefile targets:
    • make clean - Clean up build artifacts
    • make build - Build firmware in a project's build/ directory
    • make flash - Flash firmware. Needs PORT variable set
    • make monitor - Run serial monitor. Needs PORT variable set
    • make unix - Build Mac/Linux executable firmware, see "UNIX mode" section below
  • SDK Preprocessor definitions:
    • LED1 - User LED pin. Default: 2
    • BTN1 - User button pin. Default: 9

API reference

API support matrix:

Name GPIO SPI I2C UART WiFi Timer System RTOS
ESP32C3 yes yes - yes - yes yes -
ESP32 yes yes - - - yes yes -
  • GPIO src/ARCH/gpio.h
    void gpio_output(int pin);              // Set pin mode to OUTPUT
    void gpio_input(int pin);               // Set pin mode to INPUT
    void gpio_write(int pin, bool value);   // Set pin to low (false) or high
    void gpio_toggle(int pin);              // Toggle pin value
    bool gpio_read(int pin);                // Read pin value
  • SPI src/spi.h, src/spi.c
    // SPI descriptor. Specifies pins for MISO, MOSI, CLK and chip select
    struct spi { int miso, mosi, clk, cs[3]; };
    
    bool spi_init(struct spi *spi);           // Init SPI
    void spi_begin(struct spi *spi, int cs);  // Start SPI transaction
    void spi_end(struct spi *spi, int cs);    // End SPI transaction
    unsigned char spi_txn(struct spi *spi, unsigned char);   // Do SPI transaction
  • UART src/uart.h, src/ARCH/uart.c
    void uart_init(int no, int tx, int rx, int baud);   // Initialise UART
    bool uart_read(int no, uint8_t *c);   // Read byte. Return true on success
    void uart_write(int no, uint8_t c);   // Write byte. Block if FIFO is full
  • SOC src/ARCH/soc.h
    void wdt_disable(void);   // Disable watchdog
    int sdk_ram_used(void);           // Return used RAM in bytes
    int sdk_ram_free(void);           // Return free RAM in bytes
    unsigned long time_us(void);      // Return uptime in microseconds
    void delay_us(unsigned long us);  // Block for "us" microseconds
    void delay_ms(unsigned long ms);  // Block for "ms" milliseconds
    void spin(unsigned long count);   // Execute "count" no-op instructions
  • Timer src/timer.h
    struct timer {
      uint64_t period;       // Timer period in micros
      uint64_t expire;       // Expiration timestamp in micros
      void (*fn)(void *);    // Function to call
      void *arg;             // Function argument
      struct timer *next;    // Linkage
    };
    
    #define TIMER_ADD(head_, p_, fn_, arg_)
    void timers_poll(struct timer *head, uint64_t now);
  • Log src/log.h, src/log.c
    void sdk_log(const char *fmt, ...);   // Log message to UART 0
                                          // Supported specifiers:
                                          // %d, %x, %s, %p
    void sdk_hexdump(const void *buf, size_t len);  // Hexdump buffer
  • TCP/IP

esputil

esputil is a command line tool for managing Espressif devices. It is a replacement of esptool.py. esputil is written in C, its source code is in tools/esputil.c. It works on Linux, UNIX and Windows. A pre-compiled Windows executable can be downloaded from the tools folder. Below is a quick reference:

$ esputil -h
Defaults: BAUD=115200, PORT=/dev/ttyUSB0
Usage:
  esputil [-v] [-b BAUD] [-p PORT] monitor
  esputil [-v] [-b BAUD] [-p PORT] info
  esputil [-v] [-b BAUD] [-p PORT] readmem ADDR SIZE
  esputil [-v] [-b BAUD] [-p PORT] readflash ADDR SIZE
  esputil [-v] [-b BAUD] [-p PORT] [-fp FLASH_PARAMS] [-fspi FLASH_SPI] flash OFFSET BINFILE ...
  esputil [-v] mkbin FIRMWARE.ELF FIRMWARE.BIN
  esputil mkhex ADDRESS1 BINFILE1 ADDRESS2 BINFILE2 ...
  esputil [-tmp TMP_DIR] unhex HEXFILE

Example: flash MDK-built ESP32C3 firmware:

$ esputil flash 0 ./build/firmware.bin

Example: flash ESP-IDF built firmware on ESP32-PICO-Kit board:

$ esputil -fspi 6,17,8,11,16 flash 
  0x1000 build/bootloader/bootloader.bin \
  0x8000 build/partitions.bin \
  0xe000 build/ota_data_initial.bin \
  0x10000 build/firmware.bin

Build esputil

Linux, macOS:

$ make -C tools esputil

Windows:
Choose one of the below compilers, and use the provided command from the mdk root folder. Check to make sure the path points to where you installed the compiler.

Clang: (From PowerShell)

& 'C:\Program Files\LLVM\bin\clang.exe' -v -o esputil.exe tools\esputil.c

TCC: (From PowerShell)

& 'C:\Program Files\tcc\tcc.exe' -v -o esputil.exe tools\esputil.c

MSVC: (From Developer Command Prompt)

cl tools\esputil.c

ESP32 flashing

Flashing ESP32 chips is done via UART. In order to do so, ESP32 should be rebooted in the flashing mode, by pulling IO0 low during boot. Then, a ROM bootloader uses SLIP framing for a simple serial protocol, which is described at https://docs.espressif.com/projects/esptool/en/latest/advanced-topics/serial-protocol.html.

Using that SLIP protocol, it is possible to write images to flash at any offset. That is what tools/esputil.c implements. The image should be of the following format:

  • COMMON HEADER - 4 bytes, contains number of segments in the image and flash params
  • ENTRY POINT ADDRESS - 4 bytes, the beginning of the image code
  • EXTENDED HEADER - 16 bytes, contains chip ID and extra flash params
  • One or more SEGMENTS, which are padded to 16 bytes
 | COMMON HEADER |  ENTRY  |           EXTENDED HEADER          | SEGM1 | ... | 
 | 0xe9 N F1 F2  | X X X X | 0xee 0 0 0 C 0 V 0 0 0 0 0 0 0 0 1 |       | ... | 

   0xe9 - Espressif image magic number. All images must start with 0xe9
   N    - a number of segments in the image
   F1  - flash mode. 0: QIO, 1: QOUT, 2: DIO, 3: DOUT
   F2  - flash size (high 4 bits) and flash frequency (low 4 bits):
            size: 0: 1MB, 0x10: 2MB, 0x20: 4MB, 0x30: 8MB, 0x40: 16MB
            freq: 0: 40m, 1: 26m, 2: 20m, 0xf: 80m
   ENTRY - 4-byte entry point address in little endian
   C     - Chip ID. 0: ESP32, 5: ESP32C3
   V     - Chip revision

Flash parameters

Image header format includes two bytes, F1 and F2, which desribe SPI flash parameters that ROM bootloader uses to load the rest of the firmware. Those two bytes encode three parameters:

  • Flash mode (F1 byte - can be 0, 1, 2, 3)
  • FLash size (hight 4 bits of F2 byte - can be 0, 1, 2, 3, 4)
  • Flash frequency (low 4 bits of F2 byte - can be 0, 1, 2, f)

By default, esputil fetches flash params F1 and F2 from the existing bootloader by reading first 4 bytes of the bootloader from flash. It is possible to manually set flash params via the -fp flag, which is an integer value that represent 3 hex nimbles. For example fp 0x22f sets flash to DIO, 4MB, 80MHz:

$ esputil -fp 0x22f flash 0 build/firmware.bin

FLash SPI pin settings

Some boards fail to talk to flash: when you attempt to esputil flash them, they'll time out with the flash_begin/erase failed, for example trying to flash a bootloader on a ESP32-PICO-D4-Kit:

$ esputil flash 4096 build/bootloader/bootloader.bin 
Error: can't read bootloader @ addr 0x1000
Erasing 24736 bytes @ 0x1000
flash_begin/erase failed

This is because ROM bootloader on such boards have wrong SPI pins settings. Espressif's esptool.py alleviates that by uploading its own piece of software into ESP32 RAM, which does the right thing. esputil uses ROM bootloader, and in order to fix an issue, a -fspi FLASH_PARAMS parameter can be set which manually sets flash SPI pins. The format of the FLASH_PARAMS is five comma-separated integers for CLK,Q,D,HD,CS pins.

A previously failed ESP32-PICO-D4-Kit example can be fixed by passing a correct SPI pin settings:

$ esputil -fspi 6,17,8,11,16 flash 4096 build/bootloader/bootloader.bin 
Written build/bootloader/bootloader.bin, 24736 bytes @ 0x1000
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].