Skip to content

Commit

Permalink
flash-firmware fix
Browse files Browse the repository at this point in the history
  • Loading branch information
rafal-gorecki committed Jan 5, 2024
1 parent c64a23e commit 660c902
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 71 deletions.
26 changes: 7 additions & 19 deletions Dockerfile.hardware
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@

ARG ROS_DISTRO=melodic

## ============================ STM32FLASH =================================
# stm32flash needs an older version of glibc (2.28), which is why ubuntu 18.04 was used
FROM ubuntu:18.04 AS stm32flash_builder

# official releases are only for intel archs, so we need to build stm32flash from sources
RUN apt-get update && apt-get install -y \
git \
build-essential && \
git clone https://github.com/stm32duino/stm32flash.git && \
cd stm32flash/ && \
make all

## =========================== STM32 firmware===============================
# FROM --platform=linux/amd64 ubuntu:18.04 as stm32_firmware_builder
Expand Down Expand Up @@ -71,7 +59,7 @@ RUN export LC_ALL=C.UTF-8 && \
-DJOINT_STATES_ENABLE=1 \
-DROS_NOETIC_MSGS=${ROS_NOETIC_MSGS} \
-DKINEMATIC_TYPE=1" && \
pio run
pio run

## =========================== ROS package builder ===============================

Expand All @@ -82,7 +70,7 @@ SHELL ["/bin/bash", "-c"]
RUN apt update && apt install -y \
git \
python3-pip \
ros-$ROS_DISTRO-rosserial-python \
ros-$ROS_DISTRO-rosserial-python \
ros-$ROS_DISTRO-rosserial-server \
ros-$ROS_DISTRO-rosserial-client \
ros-$ROS_DISTRO-rosserial-msgs \
Expand Down Expand Up @@ -111,15 +99,16 @@ RUN mkdir -p src && \
RUN source /opt/ros/$ROS_DISTRO/setup.bash && \
catkin_make -DCATKIN_ENABLE_TESTING=0 -DCMAKE_BUILD_TYPE=Release

## =========================== ROS image ===============================

FROM ros:$ROS_DISTRO-ros-core
## =========================== Final Stage ===============================
FROM ros:$ROS_DISTRO-ros-core

SHELL ["/bin/bash", "-c"]

RUN apt update && apt install -y \
python3-pip \
ros-$ROS_DISTRO-rosserial-python \
stm32flash \
ros-$ROS_DISTRO-rosserial-python \
ros-$ROS_DISTRO-rosserial-server \
ros-$ROS_DISTRO-rosserial-client \
ros-$ROS_DISTRO-rosserial-msgs \
Expand All @@ -143,7 +132,6 @@ COPY --from=pkg-builder /ros_ws /ros_ws
# copy firmware built in previous stage
COPY --from=stm32_firmware_builder /rosbot-stm32-firmware/.pio/build/core2_diff/firmware.bin /root/firmware_diff.bin
COPY --from=stm32_firmware_builder /rosbot-stm32-firmware/.pio/build/core2_mec/firmware.bin /root/firmware_mecanum.bin
COPY --from=stm32flash_builder /stm32flash/stm32flash /usr/bin/stm32flash

# copy scripts
COPY ./flash-firmware.py /
Expand All @@ -156,4 +144,4 @@ RUN echo ". /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc && \
echo ". /ros_ws/devel/setup.bash" >> ~/.profile

ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["bash"]
CMD ["bash"]
105 changes: 53 additions & 52 deletions flash-firmware.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,50 @@
#!/usr/bin/python3

import sh
# Copyright 2023 Husarion
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sh
import time
import sys
import argparse
from periphery import GPIO


class FirmwareFlasher:
class FirmwareFlasher:
def __init__(self, sys_arch, binary_file):

self.binary_file = binary_file
self.sys_arch = sys_arch

self.max_approach_no = 5
self.max_approach_no = 3

print(f"System architecture: {self.sys_arch}")

if self.sys_arch.stdout == b'armv7l\n':
if self.sys_arch.stdout == b"armv7l\n":
# Setups ThinkerBoard pins
print("Device: ThinkerBoard\n")
self.port = "/dev/ttyS1"
boot0_pin_no = 164
reset_pin_no = 184


elif self.sys_arch.stdout == b'x86_64\n':
elif self.sys_arch.stdout == b"x86_64\n":
# Setups UpBoard pins
print("Device: UpBoard\n")
self.port = "/dev/ttyS4"
boot0_pin_no = 17
reset_pin_no = 18
elif self.sys_arch.stdout == b'aarch64\n':

elif self.sys_arch.stdout == b"aarch64\n":
# Setups RPi pins
print("Device: RPi\n")
self.port = "/dev/ttyAMA0"
Expand All @@ -45,79 +57,68 @@ def __init__(self, sys_arch, binary_file):
self.boot0_pin = GPIO(boot0_pin_no, "out")
self.reset_pin = GPIO(reset_pin_no, "out")


def enter_bootloader_mode(self):

self.boot0_pin.write(True)
self.reset_pin.write(True)
time.sleep(0.2)
self.reset_pin.write(False)
time.sleep(0.2)


def exit_bootloader_mode(self):

self.boot0_pin.write(False)
self.reset_pin.write(True)
time.sleep(0.2)
self.reset_pin.write(False)
time.sleep(0.2)

def try_flash_operation(self, operation_name, flash_command, flash_args):
for i in range(self.max_approach_no):
try:
flash_command(self.port, *flash_args, _out=sys.stdout)
time.sleep(0.2)
break
except Exception as e:
print(f"{operation_name} error! Trying again.")
print(f"Error: {e}")
print("---------------------------------------")
else:
print(f"WARNING! {operation_name} went wrong.")

def flash_firmware(self):

self.enter_bootloader_mode()

# Flashing the firmware
succes_no = 0
for i in range(self.max_approach_no):
try:
if succes_no == 0:
# Disable the flash write-protection
sh.stm32flash(self.port, "-u", _out=sys.stdout)
time.sleep(0.2)
succes_no += 1

if succes_no == 1:
# Disable the flash read-protection
sh.stm32flash(self.port, "-k", _out=sys.stdout)
time.sleep(0.2)
succes_no += 1

if succes_no == 2:
# Flashing the firmware
sh.stm32flash(self.port, "-v", w=self.binary_file, b="115200", _out=sys.stdout)
time.sleep(0.2)
break
except:
pass
# Disable the flash write-protection
self.try_flash_operation("Write-UnProtection", sh.stm32flash, ["-u"])

else:
print('ERROR! Something goes wrong. Try again.')
# Disable the flash read-protection
self.try_flash_operation("Read-UnProtection", sh.stm32flash, ["-k"])

# Flashing the firmware
flash_args = ["-v", "-w", self.binary_file, "-b", "115200"]
self.try_flash_operation("Flashing", sh.stm32flash, flash_args)

self.exit_bootloader_mode()



def main():

parser = argparse.ArgumentParser(
description='Flashing the firmware on STM32 microcontroller in ROSbot')

description="Flashing the firmware on STM32 microcontroller in ROSbot"
)

parser.add_argument(
"file",
nargs='?',
default="/root/firmware_diff.bin",
help="Path to a firmware file. Default = /root/firmware_diff.bin")

binary_file = parser.parse_args().file
sys_arch = sh.uname('-m')
"file",
nargs="?",
default="/root/firmware_diff.bin",
help="Path to a firmware file. Default = /root/firmware.bin",
)

binary_file = parser.parse_args().file
sys_arch = sh.uname("-m")

flasher = FirmwareFlasher(sys_arch, binary_file)
flasher.flash_firmware()
print("Done.")
print("Done!")


if __name__ == "__main__":
main()
main()

0 comments on commit 660c902

Please sign in to comment.