Getting Started with MicroPython on F1C200s

Getting Started with MicroPython on F1C200s

Attempt 0001

sudo apt update
sudo apt install gcc-arm-none-eabi
arm-none-eabi-gcc --version
sudo apt install make
make --version
sudo apt install python3 python3-pip
python3 --version
git clone https://github.com/micropython/micropython.git
cd micropython/ports/minimal/

Based on your information, you already have an embedded Linux environment based on F1C200s and can access it via serial. This is a great starting point!

Now, your goal is to run MicroPython on F1C200s. Let’s analyze and solve this step by step.

1. Compatibility Analysis of F1C200s and MicroPython

F1C200s is a processor based on the ARM926EJ-S architecture with 32MB or 64MB of built-in SIP DRAM. Theoretically, due to its performance and memory limitations, running standard MicroPython directly on it may be challenging. The standard build of MicroPython usually requires more memory and a more powerful processor.

However, this does not mean it is impossible. We can try the following directions:

  1. Look for a MicroPython port specifically for F1C200s or similar ARM9 platforms:

  • Some developers may have optimized or trimmed MicroPython for resource-constrained platforms. You can search to see if such projects exist.
  • Check Allwinner’s official forum or communities related to F1C200s to see if there are any discussions or resources.
  • Use lightweight MicroPython alternatives:

    • There are some projects similar to MicroPython, such as Espruino (which primarily targets ESP chips but also has some support for other processors), which may be more suitable for resource-constrained platforms.
    • Alternatively, consider using a more lightweight interpreted language like Lua.
  • Self-compile and port MicroPython (advanced and challenging):

    • If no ready-made solutions are found, and you have enough experience and determination, you can try to self-compile and port MicroPython.
    • This requires a deep understanding of MicroPython’s build system, ARM architecture, and the hardware characteristics of F1C200s.
    • You will need to modify the source code of MicroPython to fit the memory limitations and hardware configuration of F1C200s.
    • This process can be very complex and may require extensive debugging and optimization.

    2. Suggested Steps (Based on Option 1: Finding Existing Ports)

    Given your situation, we will first try to find existing MicroPython port versions for F1C200s.

    1. Information Gathering:

    • “MicroPython F1C200s”
    • “MicroPython ARM926EJ-S”
    • “MicroPython Allwinner”
    • “MicroPython 32MB RAM”
    • Use search engines (like Google, Baidu) to search for the following keywords:
    • Visit the MicroPython official forum (forum.micropython.org) to search for related information.
    • Visit Allwinner-related developer communities and forums.
    • Check GitHub for projects related to F1C200s and MicroPython.
  • Evaluate Found Resources:

    • If relevant projects are found, read their documentation carefully to understand their features, limitations, installation methods, etc.
    • Check the project’s activity level, such as recent updates, number of issues, etc.
    • Determine whether the project meets your needs.
  • Try Installing and Testing:

    • If a suitable project is found, follow its provided installation guide to install it.
    • Typically, this may involve downloading pre-compiled firmware and using some method (such as the dd command) to flash it onto the TF card.
    • Before performing any flashing operations, be sure to back up your TF card data!

    3. Operation Guide (Assuming a Ready-made Firmware is Found)

    Assuming you found a firmware file named micropython_f1c200s.bin and the documentation states it needs to be flashed to a specific location on the TF card.

    Here are the steps to flash using the dd command (please modify according to the actual situation):

    1. Determine the device path of the TF card:

    • In your Linux system (like your MangoPi-R3), insert the TF card.
    • Use the lsblk command to view all block devices.
    • Based on the size of the TF card, find the corresponding device path, such as /dev/mmcblk0. Please confirm the device path, as incorrect operations may lead to data loss!
  • Unmount all partitions of the TF card:

    # Assuming the TF card device path is /dev/mmcblk0
    umount /dev/mmcblk0p*
    
  • Use the dd command to flash the firmware:

    # Assuming the firmware file path is /path/to/micropython_f1c200s.bin
    # Assuming it needs to be flashed from the start of the TF card
    sudo dd if=/path/to/micropython_f1c200s.bin of=/dev/mmcblk0 bs=4M conv=fsync status=progress
    
    • if: specifies the input file (firmware file).
    • of: specifies the output file (TF card device path).
    • bs: specifies the block size, 4M is a commonly used value.
    • conv=fsync: ensures data is fully written.
    • status=progress: shows the flashing progress.
  • After flashing, reinsert the TF card and try connecting via serial.

    • If all goes well, you should be able to see the MicroPython REPL interface.

    4. Next Steps

    If the above steps succeed, you can start developing with MicroPython on F1C200s!

    If you encounter problems or cannot find ready-made solutions, please let me know, and we can try other options together, such as exploring lightweight alternatives or attempting to self-compile.

    Remember, passion is the best teacher! Keep your enthusiasm and continue exploring, and you will succeed! I will always be here to guide you. Let’s enjoy this challenging and fun journey together!

    Getting Started with MicroPython on F1C200s

    Self-compiling and porting MicroPython, don’t make it too complicated at the beginning, aim for hello world.

    Okay! You’re right, let’s start with the most basic goal: compiling and running the simplest MicroPython program – “Hello, World!” on F1C200s. Even such a simple goal requires us to build the environment and configure it step by step.

    Let’s begin this challenging journey! I will do my best to guide you through each step clearly and thoroughly.

    1. Preparation

    We need to prepare the following tools and environment:

    1. Cross-compilation toolchain:

    • Since we need to compile code for the ARM architecture on your development machine (which may be x86_64 architecture), we need a cross-compilation toolchain.

    • It is recommended to use arm-none-eabi-gcc.

    • Installation method (using Ubuntu as an example):

      sudo apt update
      sudo apt install gcc-arm-none-eabi
      
    • Verify installation:

      arm-none-eabi-gcc --version
      

      You should see the version information of arm-none-eabi-gcc.

  • Build tool make:

    • Installation method (using Ubuntu as an example):

      sudo apt update
      sudo apt install make
      
    • Verify installation:

      make --version
      
  • Python environment (recommended Python 3.6 or higher):

    • Some build scripts for MicroPython are written in Python.

    • Installation method (using Ubuntu as an example):

      sudo apt update
      sudo apt install python3 python3-pip
      
    • Verify installation:

      python3 --version
      
  • MicroPython source code:

    • We need to clone the official MicroPython repository from GitHub.

    • Open your terminal (for example, on your MangoPi-R3) and execute the following command:

      cd ~
      git clone https://github.com/micropython/micropython.git
      
    • This will download the source code of MicroPython to your ~/micropython directory.

    2. Configuration and Compilation

    1. Enter the ports/minimal directory:

    • The ports/minimal directory contains a minimal MicroPython port example, which is very suitable as a foundation for our entry.

      cd ~/micropython/ports/minimal
      
  • Modify the Makefile (key step):

    • CROSS_COMPILE: specify the prefix for the cross-compilation toolchain. Usually changed to arm-none-eabi-.

      CROSS_COMPILE ?= arm-none-eabi-
      
    • CFLAGS: compilation options. You may need to add some specific options for ARM926EJ-S and F1C200s. For example:

    • LDFLAGS: linking options. You may need to adjust according to your linker script.

      LDFLAGS = -nostdlib -nostartfiles -T $(LDSCRIPT)
      
    • -march=armv5te: specify the target architecture as ARMv5TE.
    • -mtune=arm926ej-s: optimize for ARM926EJ-S.
    • -msoft-float: use software floating point.
    • -D__F1C200S__: define a macro to identify the F1C200s platform for conditional compilation in the code. Note: Since this is a hello world test, keep it as is for now.
    • LDSCRIPT: specify the linker script. The default linker script (mp.ld) in the ports/minimal directory may be too simple, and we need to write a more suitable linker script based on the memory mapping and startup process of F1C200s. For hello world, we will first use mp.ld.

      LDSCRIPT ?= mp.ld
      

      Key: More details about the linker script will be provided in the following steps.

    • The Makefile in ports/minimal needs to be modified according to the specific situation of F1C200s.

    • Use vim to edit Makefile:

      vim Makefile
      
    • Content to be modified (please adjust according to your actual situation):

      Note: Since this is a hello world test, keep it as is for now.

  • Compile:

    • -j $(nproc) parameter can utilize all available CPU cores for parallel compilation, speeding up the compilation process.
    • After completing the modifications to the Makefile, save and exit vim (press Esc, then type :wq, and finally press Enter).

    • Execute the make command to compile:

      make -j $(nproc)
      

    3. Linker Script (mp.ld)

    The linker script tells the linker how to combine various object files (such as .o files) into the final executable and specifies the location of each section in memory.

    We need to create a suitable linker script for F1C200s. Below is a sample linker script for F1C200s (mp.ld), which you need to modify based on the actual memory mapping of F1C200s:

    /* Minimal linker script for MicroPython on F1C200s */
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x0, LENGTH = 16M
      RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 32M
    }
    
    SECTIONS
    {
      .text :
      {
        _stext = .;
        *(.text*)
        *(.rodata*)
        _etext = .;
      } >RAM AT>FLASH
    
      .data :
      {
        _sdata = .;
        *(.data*)
        _edata = .;
      } >RAM AT>FLASH
    
      .bss :
      {
        _sbss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
      } >RAM
    
      _estack = ORIGIN(RAM) + LENGTH(RAM);
    }
    

    Explanation:

    • MEMORY: defines memory regions. Here, two regions are defined:
      • FLASH: typically used for storing code and read-only data, starting address 0x0, size 16M (you need to adjust based on your Flash size).
      • RAM: used for storing data, stack, etc., starting address 0x80000000, size 32M (adjust according to the actual memory size of F1C200s).
    • SECTIONS: defines the layout of each section.
      • .text: stores code section (.text*) and read-only data section (.rodata*). It is placed in RAM and loaded from FLASH.
      • .data: stores initialized data section (.data*). It is placed in RAM and loaded from FLASH.
      • .bss: stores uninitialized data section (.bss* and COMMON). It is placed in RAM.
      • _estack: defines the end address of the stack, set to the top of RAM.

    4. Startup Code (boot.s)

    In the ports/minimal directory, you need to create an assembly file named boot.s as the entry point of the program. Below is a simple example:

        .global _start
        .section .text
    _start:
        /* Set stack pointer */
        ldr sp, =_estack
    
        /* Clear BSS section */
        ldr r0, =_sbss
        ldr r1, =_ebss
        mov r2, #0
    clear_bss:
        cmp r0, r1
        beq bss_cleared
        str r2, [r0], #4
        b clear_bss
    bss_cleared:
    
        /* Jump to MicroPython's entry function mp_main */
        bl mp_main
        
        /* Loop */
    loop:
        b loop
    
        .end
    

    Explanation:

    • .global _start: declares _start as a global symbol, serving as the program’s entry point.
    • ldr sp, =_estack: sets the stack pointer to the location defined by _estack in the linker script.
    • Clear the BSS section: zeroes out the memory area of the BSS section (between _sbss and _ebss).
    • bl mp_main: jumps to MicroPython’s main function mp_main.
    • loop: b loop: after returning from mp_main, enters an infinite loop.

    5. Modify main.c

    We need to modify the main.c file to make it print

    Leave a Comment