- 
                Notifications
    
You must be signed in to change notification settings  - Fork 5
 
Feature/build release #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    
  
     Merged
                    Changes from 2 commits
      Commits
    
    
            Show all changes
          
          
            10 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      5728bc4
              
                Add automatic builds that contain examples on release
              
              
                malcolm-sparkfun 5de809f
              
                Add unmount of immutable directory and persistent tracking so expandi…
              
              
                malcolm-sparkfun 0885da7
              
                update names for frozen examples
              
              
                malcolm-sparkfun fa2d97a
              
                pedantic fixes
              
              
                malcolm-sparkfun fe4cc0d
              
                Use built in extraction of freezefs to simplify build script
              
              
                malcolm-sparkfun 95c72eb
              
                Update content of PERSISTENT_FILE_FOR_UNPACK
              
              
                sfe-SparkFro 4fc3bbe
              
                Update build.sh
              
              
                sfe-SparkFro 65cb21a
              
                Merge branch 'features_for_launch' into feature/build_release
              
              
                sfe-SparkFro c37d7b3
              
                Change release workflow to rename firmware file
              
              
                sfe-SparkFro b6b5958
              
                build.sh: only copy frozen directory if different
              
              
                sfe-SparkFro File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| name: Build and Deploy Firmware Release | ||
| 
     | 
||
| on: | ||
| release: | ||
| types: [created] | ||
| 
     | 
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-22.04 | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| submodules: true | ||
| - name: Build Firmware | ||
| run: source build.sh && build_micropython_opencv | ||
| - name: Upload Release Assets | ||
| uses: shogo82148/actions-upload-release-asset@v1 | ||
| with: | ||
| asset_path: "micropython/ports/rp2/build-SPARKFUN_XRP_CONTROLLER-LARGE_BINARY/firmware.uf2" | ||
| github_token: ${{ secrets.GITHUB_TOKEN }} | ||
| upload_url: ${{ github.event.release.upload_url }} | ||
| 
     | 
||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| if which nproc > /dev/null; then | ||
| MAKEOPTS="-j$(nproc)" | ||
| else | ||
| MAKEOPTS="-j$(sysctl -n hw.ncpu)" | ||
| fi | ||
| 
     | 
||
| # TODO: Could also make these opts into the build_micropython_opencv function if we care... | ||
| FROZEN_MODULES_DIR="$(dirname "$0")/frozen_modules" | ||
| FROZEN_EXAMPLES_ARCHIVE_SCRIPT="frozen_examples.py" | ||
| FROZEN_EXAMPLES_UNPACKED_DIR="micropython-opencv-examples" | ||
| PERSISTENT_FILE_FOR_UNPACK="/keep_opencv_example_changes" | ||
                
      
                  malcolm-sparkfun marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| # Uses freezefs to create a frozen filesystem archive for the provided directory. | ||
| # See https://github.com/bixb922/freezefs for more details on freezefs | ||
| # Options: | ||
| # $1: The directory to freeze | ||
| # $2: The name that you want the frozen directory to have once unpacked on the board | ||
| # $3: The output file name for the frozen archive .py file | ||
| function create_frozen_fs { | ||
| local DIR_TO_FREEZE=$1 | ||
| local DIR_NAME_ON_BOARD=$2 | ||
| local OUTPUT_FILE=$3 | ||
| 
     | 
||
| echo "Creating frozen filesystem for directory: $DIR_TO_FREEZE" | ||
| echo "The frozen directory will be named: $DIR_NAME_ON_BOARD" | ||
| echo "The output file will be: $OUTPUT_FILE" | ||
| 
     | 
||
| cp -r $DIR_TO_FREEZE $DIR_NAME_ON_BOARD | ||
| 
     | 
||
| python -m freezefs $DIR_NAME_ON_BOARD $OUTPUT_FILE | ||
                
      
                  sfe-SparkFro marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| } | ||
| 
     | 
||
| # Options: | ||
| # $1: The directory to add to the manifest | ||
| # $2: The port (e.g. rp2) | ||
| # $3: The board (e.g. SPARKFUN_XRP_CONTROLLER) | ||
| # $4: The mpconfigboard file name (e.g. mpconfigboard.cmake or mpconfigboard.m) Default: mpconfigboard.cmake | ||
| function add_to_manifest { | ||
| local DIR=$1 | ||
| local PORT=$2 | ||
| local BOARD=$3 | ||
| local MPCONFIG_FILE="${4:-mpconfigboard.cmake}" | ||
| 
     | 
||
| # Add the directory to the manifest file | ||
| echo "Adding $DIR to the manifest for $PORT on $BOARD using $MPCONFIG_FILE" | ||
| local BOARD_DIR="micropython/ports/${PORT}/boards/${BOARD}" | ||
| 
     | 
||
| # Create manifest.py if it doesn't exist | ||
| if [ ! -f ${BOARD_DIR}/manifest.py ]; then | ||
| echo "include(\"\$(PORT_DIR)/boards/manifest.py\")" > ${BOARD_DIR}/manifest.py | ||
| 
     | 
||
| # also add the necessary frozen manifest line to mpconfigboard.cmake: set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) | ||
| # We will use the optional MPCONFIG_FILE argument to determine if we should add this line | ||
| 
     | 
||
| if [ -n "$MPCONFIG_FILE" ]; then | ||
| if [[ $MPCONFIG_FILE == *.mk ]]; then | ||
| # e.g. for TEENSY which uses mpconfigboard.mk instead of mpconfigboard.cmake | ||
| echo "Adding frozen manifest line to mpconfigboard.mk for $BOARD" | ||
| printf "\nFROZEN_MANIFEST ?= \$(BOARD_DIR)/manifest.py" >> ${BOARD_DIR}/$MPCONFIG_FILE | ||
| elif [[ $MPCONFIG_FILE == *.cmake ]]; then | ||
| echo "Adding frozen manifest line to mpconfigboard.cmake for $BOARD" | ||
                
      
                  malcolm-sparkfun marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| printf "\nset(MICROPY_FROZEN_MANIFEST \"\${MICROPY_BOARD_DIR}/manifest.py\")" >> ${BOARD_DIR}/$MPCONFIG_FILE | ||
| fi | ||
| fi | ||
| fi | ||
| 
     | 
||
| # Add the freeze line to the manifest.py for the board | ||
| echo "Adding freeze line to manifest.py for $BOARD" | ||
| printf "\nfreeze(\"${DIR}\")" >> ${BOARD_DIR}/manifest.py | ||
                
      
                  malcolm-sparkfun marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| # Helpful for debugging during the build process, but can be removed if we'd rather not see this output... | ||
| echo "Manifest.py for $BOARD:" | ||
| cat ${BOARD_DIR}/manifest.py | ||
| } | ||
| 
     | 
||
| # Adds the frozen data filesystem to the boot.py file for the given port | ||
                
      
                  malcolm-sparkfun marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| # Options: | ||
| # $1: Port name | ||
| # $2: Frozen data file path | ||
| # $3: Copy Source: If copying imported frozen data to a mutable location, this is the directory name of the source (optional) | ||
| # $4: Copy Destination: If copying imported frozen data to a mutable location, this is the directory name of the destination (optional) | ||
| # $5: Add destination to sys.path? If true, the destination directory will be added to sys.path in _boot.py (optional) | ||
| # NOTE: By providing the source and destination, the frozen data filesystem will be copied to a mutable location on the board | ||
| # If they are not provided, the frozen data filesystem will still be accessible, but will be read-only. | ||
| function add_frozen_data_to_boot_for_port { | ||
| local TARGET_PORT_NAME=$1 | ||
| local FROZEN_DATA_FILE=$2 | ||
| local SOURCE_DIR=$3 | ||
| local DESTINATION_DIR=$4 | ||
| local ADD_TO_SYSPATH=${5:-false} | ||
| 
     | 
||
| # Remove the ".py" extension from the frozen data file | ||
| local FROZEN_DATA_BASENAME=$(basename $FROZEN_DATA_FILE .py) | ||
| 
     | 
||
| # Check if the _boot.py file exists in the port's modules directory and error out if it does not | ||
| if [ ! -f micropython/ports/${TARGET_PORT_NAME}/modules/_boot.py ]; then | ||
| echo "Error: _boot.py file not found in ports/${TARGET_PORT_NAME}/modules/" | ||
| exit 1 | ||
| fi | ||
| 
     | 
||
| # Add the frozen data filesystem to the _boot.py file | ||
| local BOOT_FILE="micropython/ports/${TARGET_PORT_NAME}/modules/_boot.py" | ||
| 
     | 
||
| # Create our "persistent file for unpack" that will be used to check if the frozen data filesystem has already been unpacked | ||
| # If it has not been unpacked, we will import the frozen data filesystem | ||
| echo "Adding frozen data filesystem to ${BOOT_FILE}" | ||
| echo "import os" >> ${BOOT_FILE} | ||
| echo "try:" >> ${BOOT_FILE} | ||
| echo " os.stat('${PERSISTENT_FILE_FOR_UNPACK}')" >> ${BOOT_FILE} | ||
| echo "except OSError:" >> ${BOOT_FILE} | ||
| echo " import ${FROZEN_DATA_BASENAME}" >> ${BOOT_FILE} | ||
| echo " with open('${PERSISTENT_FILE_FOR_UNPACK}', 'w') as f:" >> ${BOOT_FILE} | ||
| echo " f.write('Hi! Delete this file to restore the ${FROZEN_EXAMPLES_UNPACKED_DIR} to its default state. WARNING: This will override ALL of your changes to that directory.')" >> ${BOOT_FILE} | ||
| 
     | 
||
| # Now, copy the unpacked frozen data filesystem to a mutable location if the source and destination are provided | ||
| # Simple recursive function to copy the directory tree (since i.e. shutil.copytree is not available on MicroPython) | ||
| if [ -n "$SOURCE_DIR" ] && [ -n "$DESTINATION_DIR" ]; then | ||
| echo "Copying frozen data from ${SOURCE_DIR} to ${DESTINATION_DIR} in _boot.py" | ||
| local BOOT_FILE="micropython/ports/${TARGET_PORT_NAME}/modules/_boot.py" | ||
| echo " def copytree(src, dst):" >> ${BOOT_FILE} | ||
| echo " try:" >> ${BOOT_FILE} | ||
| echo " os.mkdir(dst)" >> ${BOOT_FILE} | ||
| echo " except OSError:" >> ${BOOT_FILE} | ||
| echo " pass" >> ${BOOT_FILE} | ||
| echo " for entry in os.ilistdir(src):" >> ${BOOT_FILE} | ||
| echo " fname, typecode, _, _ = entry" >> ${BOOT_FILE} | ||
| echo " src_path = src + '/' + fname" >> ${BOOT_FILE} | ||
| echo " dst_path = dst + '/' + fname" >> ${BOOT_FILE} | ||
| echo " if typecode == 0x4000:" >> ${BOOT_FILE} # typecode == 0x4000 means directory | ||
| echo " copytree(src_path, dst_path)" >> ${BOOT_FILE} | ||
| echo " else:" >> ${BOOT_FILE} | ||
| echo " with open(src_path, 'rb') as fsrc:" >> ${BOOT_FILE} | ||
| echo " with open(dst_path, 'wb') as fdst:" >> ${BOOT_FILE} | ||
| echo " fdst.write(fsrc.read())" >> ${BOOT_FILE} | ||
| echo " copytree('${SOURCE_DIR}', '${DESTINATION_DIR}')" >> ${BOOT_FILE} | ||
| # Finally, unmount the source directory if it is mounted | ||
| echo " try:" >> ${BOOT_FILE} | ||
| echo " os.umount('/${SOURCE_DIR}')" >> ${BOOT_FILE} | ||
| echo " except Exception as e:" >> ${BOOT_FILE} | ||
| echo " print('umount failed:', e)" >> ${BOOT_FILE} | ||
| fi | ||
                
      
                  sfe-SparkFro marked this conversation as resolved.
               
              
                Outdated
          
            Show resolved
            Hide resolved
         | 
||
| 
     | 
||
| # If the ADD_TO_SYSPATH flag is true, add the destination directory to sys.path | ||
| if [ "$ADD_TO_SYSPATH" = true ]; then | ||
| echo "Adding ${DESTINATION_DIR} to sys.path in _boot.py" | ||
| echo "import sys" >> ${BOOT_FILE} | ||
| echo "sys.path.append('/${DESTINATION_DIR}')" >> ${BOOT_FILE} | ||
| fi | ||
| 
     | 
||
| # Helpful for debugging during the build process, but can be removed if we'd rather not see this output... | ||
| echo "Content of _boot.py after adding frozen data filesystem:" | ||
| cat micropython/ports/${TARGET_PORT_NAME}/modules/_boot.py | ||
| } | ||
| 
     | 
||
| # Installs necessary dependencies and builds OpenCV and the firmware | ||
| # Also freezes the examples directory in a filesystem archive on the board | ||
| function build_micropython_opencv { | ||
| # Install necessary packages (Could move into an install_dependencies.sh if we want this to be more explicit/modular) | ||
| sudo apt-get update | ||
| sudo apt install cmake python3 build-essential gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib | ||
| # Install necessary python packages (could also move this to a requirements.txt file) | ||
| pip install freezefs | ||
| 
     | 
||
| # Create a directory for frozen modules, we can add arbitrary .py files to this directory in the future. | ||
| # For now it will just contain the archived examples script. | ||
| mkdir "$FROZEN_MODULES_DIR" | ||
| 
     | 
||
| # Create our frozen filesystem archive for the examples directory | ||
| # Note the "." to make the read-only version of the examples directory hidden in IDEs like Thonny | ||
| create_frozen_fs "examples" ".$FROZEN_EXAMPLES_UNPACKED_DIR" "$FROZEN_MODULES_DIR/$FROZEN_EXAMPLES_ARCHIVE_SCRIPT" | ||
| 
     | 
||
| # Add necessary content to the manifest file to freeze the modules in the provided directory | ||
| add_to_manifest "$FROZEN_MODULES_DIR" "rp2" "SPARKFUN_XRP_CONTROLLER" "mpconfigvariant_LARGE_BINARY.cmake" | ||
| 
     | 
||
| # Add necessary content to the boot.py file to unpack the frozen data filesystem on boot | ||
| # Provide the source and destination directories to copy the frozen data filesystem to a mutable (and non-hidden) location | ||
| # Provide "true" as the last argument to add the destination directory to sys.path (since our examples directory contains modules that we want to be importable...) | ||
| add_frozen_data_to_boot_for_port "rp2" "$FROZEN_EXAMPLES_ARCHIVE_SCRIPT" ".$FROZEN_EXAMPLES_UNPACKED_DIR" "$FROZEN_EXAMPLES_UNPACKED_DIR" true | ||
| 
     | 
||
| # Set Pico SDK path to $GITHUB_WORKSPACE/micropython/lib/pico-sdk if $GITHUB_WORKSPACE is set, otherwise use the current directory | ||
| if [ -n "$GITHUB_WORKSPACE" ]; then | ||
| export PICO_SDK_PATH="$GITHUB_WORKSPACE/micropython/lib/pico-sdk" | ||
| else | ||
| export PICO_SDK_PATH=$(dirname "$0")/micropython/lib/pico-sdk | ||
| fi | ||
| 
     | 
||
| # Build MPY Cross compiler | ||
| make -C micropython/mpy-cross | ||
| 
     | 
||
| # Update necessary MicroPython submodules | ||
| make -C micropython/ports/rp2 BOARD=SPARKFUN_XRP_CONTROLLER submodules | ||
| 
     | 
||
| # Build OpenCV | ||
| make -C src/opencv PLATFORM=rp2350 --no-print-directory ${MAKEOPTS} | ||
| 
     | 
||
| # Build firmware | ||
| make BOARD=SPARKFUN_XRP_CONTROLLER ${MAKEOPTS} | ||
| } | ||
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.