Soon I'm going to start production on the PolyPulse.

There is a webserver running which the end user can use to upload/download his projects/samples and can also upload firmware zips. The zip is extracted and the firmware version (aka what executable is running) is changed by pointing a symlink to the selected executable and restarting the executable. This works reliably and thus far seems a good process for my beta testers.

The image I'm using is a stock bela image in which I run a script that modifies some stuff:

  • add and recompile a few .dts overlays, add them to uEnv.txt
  • create a few folders
  • add run.sh
  • add webserver executable and enable its .service

To save time I thought of making a new image by booting from a 4GB SD with a fresh bela image, running the script and then doing this to store the created image.

In situations where the OS / image somehow finds itself in a broken state I would like the user to be able to flash a clean image without screwing open the PolyPulse: the SD slot is internal and I've exposed a boot from SD button. I plan to add a 32 SDHC card with a valid image + extra storage space for samples. Then if the eMMC image breaks the user can hold the SD boot button to boot a valid image, and copy the SD image to the eMMC using /opt/Bela/bela_flash_emmc.sh.

Now if I were to use balena etcher to flash a bela image on a 32GB card it would only allow you to access 4 GB right? I were to resize the filesystem on the sd card I would not be able to run /opt/Bela/bela_flash_emmc.sh anymore right? If not I thought perhaps adding a partition for storage could work:

eMMC: modified bela image
SD partition 1 (4GB): modified bela image (backup)
SD partition 2 (28GB): extra sample storage

I also wonder how Bela flashes their SDs/eMMCs in production, do you have a fancy automatic SD card copier, perhaps a script that runs dd or do you buy your SD cards pre-flashed from the factory?

    9 days later

    Ward Then if the eMMC image breaks the user can hold the SD boot button to boot a valid image, and copy the SD image to the eMMC using /opt/Bela/bela_flash_emmc.sh.

    Sounds reasonable. You could even automate it further by running that program automatically when booting from SD card.

    Ward I were to resize the filesystem on the sd card I would not be able to run /opt/Bela/bela_flash_emmc.sh anymore right?

    It would work as long as the space actually used on the SD card is smaller than the eMMC's partition, as it is a file-by-file copy (after setting up the destination partition) and not an "image copy". There's no check before you start the copy, though, so with the file as it is, you'd only find out at the very end.

    Ward If not I thought perhaps adding a partition for storage could work:

    eMMC: modified bela image
    SD partition 1 (4GB): modified bela image (backup)
    SD partition 2 (28GB): extra sample storage

    This sounds like the best option.

    Ward I also wonder how Bela flashes their SDs/eMMCs in production, do you have a fancy automatic SD card copier,

    I can't speak to that effect, but If you enable the bela_flash_emmc service to automatically run on boot, all you need is inserting the SD card in the BBB and power it up and wait till the light tell you it's done (or it failed). Similarly, you could invert the process and have a BBB with an image that automatically attempts to flash the SD cards. Then you only need enough BBBs :-) .

    • Ward replied to this.
      5 days later

      giuliomoro It would work as long as the space actually used on the SD card is smaller than the eMMC's partition, as it is a file-by-file copy (after setting up the destination partition) and not an "image copy".

      Ah so maybe I could also flash the Bela image, resize to fit 32GB, and only copy the OS / Bela files and exclude the folder that contains the users samples/projects?

      giuliomoro Sounds reasonable. You could even automate it further by running that program automatically when booting from SD card.

      giuliomoro I can't speak to that effect, but If you enable the bela_flash_emmc service to automatically run on boot, all you need is inserting the SD card in the BBB and power it up and wait till the light tell you it's done (or it failed).

      systemctl enable bela_flash_emmc.service right?

      So in the SD image I enable this service and then the SD is copied to the eMMC. Now when I boot from the eMMC, do I need to disable the service again? Looking at the script it seems I could just leave it enabled and it should exit without doing anything?

      So to create the SD with 4 GB backup image and 28 GB storage:

      • use balena etcher to flash stock Bela image to SD card
      • boot from SD
        • run PolyPulse install script,
        • enable bela_flash_emmc.service
        • run bela_flash_emmc.sh once
      • boot from eMMC
        • use fdisk to create partition with unused space (28 GB)*
        • use mkfs.ext4 to create a usable filesystem on the new partition
        • run PolyPulse firmware and test PolyPulse hardware

      *I looked at fdisk a bit and it seems it can't be scripted from bash. Do you know of a (scriptable) way to create a partition that takes up the remaining space (the 28GB part)?

        Ward Ah so maybe I could also flash the Bela image, resize to fit 32GB, and only copy the OS / Bela files and exclude the folder that contains the users samples/projects?

        I guess that would work too, but I think it'd be cleaner if you keep them separate, unless you need every last megabyte, in which case a single partition would be more efficient.

        Ward Now when I boot from the eMMC, do I need to disable the service again? Looking at the script it seems I could just leave it enabled and it should exit without doing anything?

        No need to disable it. This line:

        rm -rf $MNT_ROOT/etc/systemd/system/default.target.wants/bela_flash_emmc.service

        is used to disable the service on the target medium.

        Ward *I looked at fdisk a bit and it seems it can't be scripted from bash. Do you know of a (scriptable) way to create a partition that takes up the remaining space (the 28GB part)?

        sfdisk; see example usage here: https://github.com/BelaPlatform/bela-image-builder/blob/master/misc/rootfs/opt/Bela/bela_flash_emmc.sh#L78-L90

        14 days later

        Hey it seems I can't get a fresh BeagleBone to boot from the emmc without physically removing the SD card:

        What I did:

        • get fresh BBB from box
        • insert 32 GB sandisk SDHC flashed with bela_image_v0.3.8h.img using Balena Etcher on Windows
        • hold BBB boot button and connect 5V 2A power via barrel jack
        • login over ssh, run /opt/Bela/bela_flash_emmc.sh and wait for finish and print Flashing was successful
        • reboot without holding boot button so it should boot from eMMC:
          • by shutdown now, waiting a bit, removing barrel power and then reapplying power after a few seconds.
          • or by running reboot (could this work at all? does calling reboot get the BBB to retry all 4 boot options?)

        Now at this point I would expect it to be booted from the eMMC. However if I run mount | grep "on / " I still get /dev/mmcblk0p2 on / type ext4 (rw,noatime,data=ordered) indicating it is still running from the SD card... If I however completely remove the SD card it boots up fine from the eMMC.

        I tried this with two Beaglebones btw.

        I'm a bit confused now and I would've hoped to be producing by now, but I have to get the SD+emmc flashing right first.

          Ward by shutdown now, waiting a bit, removing barrel power and then reapplying power after a few seconds.

          This should definitely work. The reboot one wouldn't because the button is sampled only on a hard reboot. Does it successfully boot from emmc if you boot without the sd card?

          Yes if I remove the SD card from the BBB it boots from the eMMC

          Is this with a plain BBB with nothing inserted in its pins? There are 16 pins on P8 that decide boot order alongside the button

          Yes plain BBB and plain image Inmentioned above. Only ethernet connected and 5V 2A supply on the barrel jack, no jumpers or PCBs connected

          I recommend you connect a uart cable to the 5x1 header of the bbb and look at the boot log there

          • Ward replied to this.

            giuliomoro you mean J1? With something like this or this?

            Can the boot logs also be read from the Linux after booting somewhere or does it only log over uart while booting?

            Alright so I used an ESP32 I had laying around to forward uart to serial print and I get this:

            Without holding down boot button

            U-Boot SPL 2019.01-00005-g7fb319437d (Jul 03 2021 - 11:43:29 +0000)
            Trying to boot from MMC2
            Loading Environment from EXT4... 
            ** Unable to use mmc 0:1 for loading the env **
            
            
            U-Boot 2019.01-00005-g7fb319437d (Jul 03 2021 - 11:43:29 +0000)
            
            CPU  : AM335X-GP rev 2.1
            I2C:   ready
            DRAM:  512 MiB
            No match for driver 'omap_hsmmc'
            No match for driver 'omap_hsmmc'
            Some drivers were not found
            Reset Source: Power-on reset has occurred.
            RTC 32KCLK Source: External.
            MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
            Loading Environment from EXT4... 
            ** Unable to use mmc 0:1 for loading the env **
            Board: BeagleBone Black
            <ethaddr> not set. Validating first E-fuse MAC
            BeagleBone Black:
            BeagleBone: cape eeprom: i2c_probe: 0x54:
            BeagleBone: cape eeprom: i2c_probe: 0x55:
            BeagleBone: cape eeprom: i2c_probe: 0x56:
            BeagleBone: cape eeprom: i2c_probe: 0x57:
            Net:   eth0: MII MODE
            cpsw, usb_ether
            Press SPACE to abort autoboot in 0 seconds
            1498 bytes read in 2 ms (731.4 KiB/s)
            booting from SD card
            board_name=[A335BNLT] ...
            board_rev=[00C0] ...
            loading am335x-boneblack.dtb
            60607 bytes read in 29 ms (2 MiB/s)
            loading /lib/firmware/BB-BELA-00A1.dtbo
            11248 bytes read in 102 ms (107.4 KiB/s)
            loading /lib/firmware/BB-BELA-CTAG-SPI-00A0.dtbo
            1643 bytes read in 48 ms (33.2 KiB/s)
            8870416 bytes read in 564 ms (15 MiB/s)
            ## Flattened Device Tree blob at 88000000
               Booting using the fdt blob at 0x88000000
               reserving fdt memory region: addr=88000000 size=72000
               Loading Device Tree to 8ff8b000, end 8fffffff ... OK
            
            Starting kernel ...
            
            [    0.002192] timer_probe: no matching timers found
            [    0.433593] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
            [    0.657793] omap_voltage_late_init: Voltage driver support not added
            [    0.664747] PM: Cannot get wkup_m3_ipc handle
            [    0.730941] PM: Cannot get wkup_m3_ipc handle
            
            
            Debian GNU/Linux 9 bela ttyS0
            
            bela login: 

            Holding down boot button

            U-Boot SPL 2019.01-00005-g7fb319437d (Jul 03 2021 - 11:43:29 +0000)
            Trying to boot from MMC1
            Loading Environment from EXT4... 
            ** Unable to use mmc 0:1 for loading the env **
            
            
            U-Boot 2019.01-00005-g7fb319437d (Jul 03 2021 - 11:43:29 +0000)
            
            CPU  : AM335X-GP rev 2.1
            I2C:   ready
            DRAM:  512 MiB
            No match for driver 'omap_hsmmc'
            No match for driver 'omap_hsmmc'
            Some drivers were not found
            Reset Source: Power-on reset has occurred.
            RTC 32KCLK Source: External.
            MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
            Loading Environment from EXT4... 
            ** Unable to use mmc 0:1 for loading the env **
            Board: BeagleBone Black
            <ethaddr> not set. Validating first E-fuse MAC
            BeagleBone Black:
            BeagleBone: cape eeprom: i2c_probe: 0x54:
            BeagleBone: cape eeprom: i2c_probe: 0x55:
            BeagleBone: cape eeprom: i2c_probe: 0x56:
            BeagleBone: cape eeprom: i2c_probe: 0x57:
            Net:   eth0: MII MODE
            cpsw, usb_ether
            Press SPACE to abort autoboot in 0 seconds
            1498 bytes read in 1 ms (1.4 MiB/s)
            booting from SD card
            board_name=[A335BNLT] ...
            board_rev=[00C0] ...
            loading am335x-boneblack.dtb
            60607 bytes read in 28 ms (2.1 MiB/s)
            loading /lib/firmware/BB-BELA-00A1.dtbo
            11248 bytes read in 102 ms (107.4 KiB/s)
            loading /lib/firmware/BB-BELA-CTAG-SPI-00A0.dtbo
            1643 bytes read in 49 ms (32.2 KiB/s)
            8870416 bytes read in 564 ms (15 MiB/s)
            ## Flattened Device Tree blob at 88000000
               Booting using the fdt blob at 0x88000000
               reserving fdt memory region: addr=88000000 size=72000
               Loading Device Tree to 8ff8b000, end 8fffffff ... OK
            
            Starting kernel ...
            
            [    0.002187] timer_probe: no matching timers found
            [    0.433177] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
            [    0.657851] omap_voltage_late_init: Voltage driver support not added
            [    0.664830] PM: Cannot get wkup_m3_ipc handle
            [    0.734642] PM: Cannot get wkup_m3_ipc handle
            
            
            Debian GNU/Linux 9 bela ttyS0
            
            bela login: 

            And the diff:

            diff with-sd-no-button.txt with-sd-holding-button.txt
            2c2
            < Trying to boot from MMC2
            ---
            > Trying to boot from MMC1
            30c30
            < 1498 bytes read in 2 ms (731.4 KiB/s)
            ---
            > 1498 bytes read in 1 ms (1.4 MiB/s)
            35c35
            < 60607 bytes read in 29 ms (2 MiB/s)
            ---
            > 60607 bytes read in 28 ms (2.1 MiB/s)
            39c39
            < 1643 bytes read in 48 ms (33.2 KiB/s)
            ---
            > 1643 bytes read in 49 ms (32.2 KiB/s)
            48,52c48,52
            < [    0.002192] timer_probe: no matching timers found
            < [    0.433593] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
            < [    0.657793] omap_voltage_late_init: Voltage driver support not added
            < [    0.664747] PM: Cannot get wkup_m3_ipc handle
            < [    0.730941] PM: Cannot get wkup_m3_ipc handle
            ---
            > [    0.002187] timer_probe: no matching timers found
            > [    0.433177] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
            > [    0.657851] omap_voltage_late_init: Voltage driver support not added
            > [    0.664830] PM: Cannot get wkup_m3_ipc handle
            > [    0.734642] PM: Cannot get wkup_m3_ipc handle

            Only difference seems to be that no button starts with MMC2 (wait there's 3?? or is this off by one?) and that button starts with MMC1. Its weird because MMC2 is not even listed in the boot table

              I am no expert but it may be that the content of uEnv.txt on /dev/mmcblk1p1 (the emmc's first partition) is wrong and tells it to boot from sd card. Can you show the log booting without sd card or button?

              without sd card & not holding button

              U-Boot SPL 2019.01-00005-g7fb319437d (Jul 03 2021 - 11:43:29 +0000)
              Trying to boot from MMC2
              Loading Environment from EXT4... Card did not respond to voltage select!
              
              
              U-Boot 2019.01-00005-g7fb319437d (Jul 03 2021 - 11:43:29 +0000)
              
              CPU  : AM335X-GP rev 2.1
              I2C:   ready
              DRAM:  512 MiB
              No match for driver 'omap_hsmmc'
              No match for driver 'omap_hsmmc'
              Some drivers were not found
              Reset Source: Power-on reset has occurred.
              RTC 32KCLK Source: External.
              MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
              Loading Environment from EXT4... Card did not respond to voltage select!
              Board: BeagleBone Black
              <ethaddr> not set. Validating first E-fuse MAC
              BeagleBone Black:
              BeagleBone: cape eeprom: i2c_probe: 0x54:
              BeagleBone: cape eeprom: i2c_probe: 0x55:
              BeagleBone: cape eeprom: i2c_probe: 0x56:
              BeagleBone: cape eeprom: i2c_probe: 0x57:
              Net:   eth0: MII MODE
              cpsw, usb_ether
              Press SPACE to abort autoboot in 0 seconds
              Card did not respond to voltage select!
              Card did not respond to voltage select!
              1498 bytes read in 1 ms (1.4 MiB/s)
              booting from eMMC
              board_name=[A335BNLT] ...
              board_rev=[00C0] ...
              loading am335x-boneblack.dtb
              60607 bytes read in 22 ms (2.6 MiB/s)
              loading /lib/firmware/BB-BELA-00A1.dtbo
              11248 bytes read in 83 ms (131.8 KiB/s)
              loading /lib/firmware/BB-BELA-CTAG-SPI-00A0.dtbo
              1643 bytes read in 34 ms (46.9 KiB/s)
              8870416 bytes read in 561 ms (15.1 MiB/s)
              ## Flattened Device Tree blob at 88000000
                 Booting using the fdt blob at 0x88000000
                 reserving fdt memory region: addr=88000000 size=72000
                 Loading Device Tree to 8ff8b000, end 8fffffff ... OK
              
              Starting kernel ...
              
              [    0.002181] timer_probe: no matching timers found
              [    0.432898] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
              [    0.657036] omap_voltage_late_init: Voltage driver support not added
              [    0.663939] PM: Cannot get wkup_m3_ipc handle
              [    0.730791] PM: Cannot get wkup_m3_ipc handle
              
              
              Debian GNU/Linux 9 bela ttyS0
              
              bela login: 

              edit sorry didn't post the whole thing

                Compare the content of /uEnv.txt on /dev/mmcblk0p1 and /dev/mmcblk1p1

                /dev/mmcblk0p1/uEnv.txt

                uenvcmd=echo loading ${fdtfile}; load mmc ${mmcid}:2 ${fdtaddr} boot/dtbs/${uname_r}/${fdtfile}; if env exists uboot_overlay_addr0; then setenv overlay ${uboot_overlay_addr0}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr1; then setenv overlay ${uboot_overlay_addr1}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr2; then setenv overlay ${uboot_overlay_addr2}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr3; then setenv overlay ${uboot_overlay_addr3}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr4; then setenv overlay ${uboot_overlay_addr4}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr5; then setenv overlay ${uboot_overlay_addr5}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr6; then setenv overlay ${uboot_overlay_addr6}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr7; then setenv overlay ${uboot_overlay_addr7}; run bela_loadoverlay; fi; load mmc ${mmcid}:2 ${loadaddr} /boot/vmlinuz-${uname_r}; setenv bootargs console=${console} root=/dev/mmcblk${mmcid}p2 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 quiet; bootz ${loadaddr} - ${fdtaddr};
                bela_loadoverlay=echo loading ${overlay}; load mmc ${mmcid}:2 ${rdaddr} ${overlay}; fdt addr $fdtaddr; fdt resize 0x60000; fdt apply ${rdaddr}; fdt resize 0x60000;
                
                uboot_overlay_addr2=/lib/firmware/BB-BELA-00A1.dtbo
                uboot_overlay_addr3=/lib/firmware/BB-BELA-CTAG-SPI-00A0.dtbo
                
                console=ttyS0,115200n8
                uname_r=4.14.108-ti-xenomai-r143
                mmcid=0

                /dev/mmcblk1p1/uEnv.txt

                uenvcmd=echo loading ${fdtfile}; load mmc ${mmcid}:2 ${fdtaddr} boot/dtbs/${uname_r}/${fdtfile}; if env exists uboot_overlay_addr0; then setenv overlay ${uboot_overlay_addr0}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr1; then setenv overlay ${uboot_overlay_addr1}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr2; then setenv overlay ${uboot_overlay_addr2}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr3; then setenv overlay ${uboot_overlay_addr3}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr4; then setenv overlay ${uboot_overlay_addr4}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr5; then setenv overlay ${uboot_overlay_addr5}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr6; then setenv overlay ${uboot_overlay_addr6}; run bela_loadoverlay; fi; if env exists uboot_overlay_addr7; then setenv overlay ${uboot_overlay_addr7}; run bela_loadoverlay; fi; load mmc ${mmcid}:2 ${loadaddr} /boot/vmlinuz-${uname_r}; setenv bootargs console=${console} root=/dev/mmcblk${mmcid}p2 ro rootfstype=ext4 rootwait coherent_pool=1M net.ifnames=0 quiet; bootz ${loadaddr} - ${fdtaddr};
                bela_loadoverlay=echo loading ${overlay}; load mmc ${mmcid}:2 ${rdaddr} ${overlay}; fdt addr $fdtaddr; fdt resize 0x60000; fdt apply ${rdaddr}; fdt resize 0x60000;
                
                uboot_overlay_addr2=/lib/firmware/BB-BELA-00A1.dtbo
                uboot_overlay_addr3=/lib/firmware/BB-BELA-CTAG-SPI-00A0.dtbo
                
                console=ttyS0,115200n8
                uname_r=4.14.108-ti-xenomai-r143
                mmcid=1

                diff mmc0 mmc1

                9c9
                < mmcid=0
                ---
                > mmcid=1

                That looks as expected.
                Now diff this

                Ward Without holding down boot button

                and this

                Ward without sd card & not holding button

                diff with-sd-holding-button.txt without-sd-no-button.txt
                2,4c2,3
                < Trying to boot from MMC1
                < Loading Environment from EXT4...
                < ** Unable to use mmc 0:1 for loading the env **
                ---
                > Trying to boot from MMC2
                > Loading Environment from EXT4... Card did not respond to voltage select!
                18,19c17
                < Loading Environment from EXT4...
                < ** Unable to use mmc 0:1 for loading the env **
                ---
                > Loading Environment from EXT4... Card did not respond to voltage select!
                29a28,29
                > Card did not respond to voltage select!
                > Card did not respond to voltage select!
                31c31
                < booting from SD card
                ---
                > booting from eMMC
                35c35
                < 60607 bytes read in 28 ms (2.1 MiB/s)
                ---
                > 60607 bytes read in 22 ms (2.6 MiB/s)
                37c37
                < 11248 bytes read in 102 ms (107.4 KiB/s)
                ---
                > 11248 bytes read in 83 ms (131.8 KiB/s)
                39,40c39,40
                < 1643 bytes read in 49 ms (32.2 KiB/s)
                < 8870416 bytes read in 564 ms (15 MiB/s)
                ---
                > 1643 bytes read in 34 ms (46.9 KiB/s)
                > 8870416 bytes read in 561 ms (15.1 MiB/s)
                48,52c48,52
                < [    0.002187] timer_probe: no matching timers found
                < [    0.433177] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
                < [    0.657851] omap_voltage_late_init: Voltage driver support not added
                < [    0.664830] PM: Cannot get wkup_m3_ipc handle
                < [    0.734642] PM: Cannot get wkup_m3_ipc handle
                ---
                > [    0.002181] timer_probe: no matching timers found
                > [    0.432898] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
                > [    0.657036] omap_voltage_late_init: Voltage driver support not added
                > [    0.663939] PM: Cannot get wkup_m3_ipc handle
                > [    0.730791] PM: Cannot get wkup_m3_ipc handle

                Diff the ones without button! With sd vs without sd