├── README.md ├── images ├── .DS_Store ├── logo.png └── logosquare.tiff ├── install.sh ├── scripts ├── pishift.py └── startmod.sh └── services ├── pishift.service └── startotg.service /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | piShift makes it super simple to get programming on your Pi Zero - just plug your Pi into your laptop with a micro-USB cable and it appears as a USB Drive. Drag across a .py file, and within seconds the Pi will automatically detect it's been added, and will start running the most recently edited file. 4 | 5 | #Installation 6 | 1. Install Raspbian (full, not lite) onto an SD card 7 | 2. Expand your SD card! 8 | 3. Get internet on your Pi - you can do this with a USB hub + WiFi dongle on the PiZero, or by temporarily putting your SD card into a B+/2/3 . 9 | 4. Run the following commands: 10 | ``` 11 | git clone https://github.com/tomhartley/piShift.git 12 | cd piShift 13 | sudo ./install.sh 14 | ``` 15 | 16 | Now attach a micro-USB cable to the USB port marked "USB" on the PiZero, plug into your computer, and you should be good to go! 17 | 18 | #FAQ 19 | - Q: Does it work with other versions of the Pi as well as the Pi Zero? 20 | - A: Sadly, no. The other Pis have a USB hub in the way (with the exception of the A/A+, which we're working on) - and this cannot work. 21 | -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomhartley/piShift/4cba945649442baeb3be75112ee8acdc520103bf/images/.DS_Store -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomhartley/piShift/4cba945649442baeb3be75112ee8acdc520103bf/images/logo.png -------------------------------------------------------------------------------- /images/logosquare.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomhartley/piShift/4cba945649442baeb3be75112ee8acdc520103bf/images/logosquare.tiff -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$(id -u)" != "0" ]; then #Check if script is being run as root 4 | echo "This script must be run as root" 1>&2 5 | exit 1 6 | fi 7 | if [ ! $? = 0 ]; then 8 | exit 1 9 | else 10 | echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt 11 | echo "dwc2" | sudo tee -a /etc/modules 12 | echo "g_acm_ms" | sudo tee -a /etc/modules 13 | systemctl enable getty@ttyGS0.service 14 | idir="/opt/pishift" 15 | mkdir "$idir" 16 | mkdir "$idir/binaries" 17 | mkdir "$idir/programs" 18 | mkdir "$idir/scripts" 19 | touch "$idir/programs/test.txt" 20 | binf="$idir/binaries/ms.bin" 21 | dd if=/dev/zero of="$binf" bs=512 count=2880 22 | mkdosfs "$binf" 23 | cp -a services/. /etc/systemd/system/ 24 | cp -a scripts/. "$idir/scripts/" 25 | for filename in services/*.service; do 26 | name=${filename##*/} 27 | systemctl enable $name 28 | done 29 | whiptail --title "Installation complete" --msgbox "piShift installation complete. You can now safely shutdown your Raspberry Pi and insert the micro SD card into your Raspberry Pi Zero." 8 78 30 | fi 31 | -------------------------------------------------------------------------------- /scripts/pishift.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import subprocess 3 | from time import sleep 4 | def grabRecent(): 5 | #mountCommand = "sudo mount -o ro /opt/pishift/binaries/ms.bin /mnt" 6 | mountCommand = ["sudo", "mount", "-o", "ro", "/opt/pishift/binaries/ms.bin", "/mnt"] 7 | #unmountCommand = "sudo umount /mnt" 8 | unmountCommand = ["sudo", "umount", "/mnt"] 9 | 10 | findCmd = "cd /mnt; ls -tp | grep -v '/$' | head -n1" 11 | 12 | runCmd(mountCommand) 13 | 14 | filename = runCmd(findCmd, shell=True)[:-1] 15 | 16 | copyDest = "/opt/pishift/programs/"+filename 17 | 18 | #copyCmd = 'cp "/mnt/' + filename + '" "' + copyDest + '"' 19 | copyCmd = ["cp", "/mnt/" + filename, copyDest] 20 | 21 | runCmd(copyCmd) 22 | 23 | runCmd(unmountCommand) 24 | 25 | return copyDest,filename 26 | 27 | def getMD5(fname): 28 | #md5Command = 'md5sum "' + fname + '"' 29 | md5Command = ["md5sum", fname] 30 | result = runCmd(md5Command) 31 | return result.split()[0] 32 | 33 | def runCmd(cmd, shell=False): 34 | process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=shell) 35 | output = process.communicate()[0] 36 | return output 37 | 38 | lastHash = None 39 | proc = None 40 | while True: 41 | fullpath,newName = grabRecent() 42 | newHash = getMD5(fullpath) 43 | if(proc): 44 | if (proc.poll()!=None): 45 | print ("=====YOUR PROGRAM DIED. TRY AGAIN?=====") 46 | print ("=====THE OUTPUT WAS: ========") 47 | print "" 48 | print (proc.communicate()[0]) 49 | print ("=====WAITING FOR NEW FILE======") 50 | proc = None 51 | if (newHash!=lastHash and newName!="pishift.py"): #avoid recursion by not running this file automatically 52 | if (proc): 53 | proc.kill() #kill the old python file that was running, and start running the new process 54 | print ("======KILLED======") 55 | print ("======RUNNING NEW FILE: "+newName+"======") 56 | proc = subprocess.Popen(["python3",fullpath],stdout=subprocess.PIPE,stderr=subprocess.STDOUT) 57 | lastHash = newHash 58 | else: 59 | #print ("======NO CHANGES FOUND======") 60 | pass 61 | sleep(1) 62 | -------------------------------------------------------------------------------- /scripts/startmod.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | sudo modprobe g_acm_ms luns=1 file=/opt/pishift/binaries/ms.bin ro=0 stall=0 4 | 5 | exit 0 6 | -------------------------------------------------------------------------------- /services/pishift.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Starts piShift 3 | DefaultDependencies=false 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/opt/pishift/scripts/pishift.py 8 | WorkingDirectory=/opt/pishift/ 9 | TTYPath=/dev/ttyGS0 10 | 11 | [Install] 12 | WantedBy=local-fs.target -------------------------------------------------------------------------------- /services/startotg.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Starts kernel modules for USB OTG 3 | After=systemd-remount-fs.service 4 | DefaultDependencies=false 5 | 6 | [Service] 7 | Type=simple 8 | ExecStart=/opt/pishift/scripts/startmod.sh 9 | WorkingDirectory=/opt/pishift/ 10 | 11 | [Install] 12 | WantedBy=local-fs.target 13 | --------------------------------------------------------------------------------