Лабораторная 1
.docxМинистерство науки и высшего образования Российской Федерации
Федеральное государственное автономное образовательное учреждение высшего образования
ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОННИКИ (ТУСУР)
Кафедра комплексной информационной безопасности электронно-вычислительных систем (КИБЭВС)
ЗНАКОМСТВО С АРХИТЕКТУРОЙ ARM
Отчет по лабораторной работе №1
по дисциплине «Основы программирования микроконтроллеров»
Студенты гр. 712-2: ___________ Л.С. Болтушкин
___________ Н.А. Рыбин
___________ Д.В. Шабанова __________
Руководитель Старший преподаватель кафедры КИБЭВС
_______ __________ Д.С. Беляков
__________
Томск 2025
Введение
Целью данной лабораторной работы является знакомство с архитектурой ARM на примере микроконтроллера STM32F103RBT6, разработка программы на языке ассемблера для данного микроконтроллера, а также изучение содержимого объектного файла.
1 ХОД РАБОТЫ
1.1 Установка и настройка окружения
Для разработки прошивки под микроконтроллер были установлены пакеты через следующие команды, представленные на рисунке 1.1.1 и 1.1.2.
Рисунок 1.1.1 – Установка требуемых пакетов первой командой
Рисунок 1.1.2 – Установка требуемых пакетов второй командой
Далее был скачан и распакован архив «lab1_f103.zip» из электронного курса.
После для сборки проекта был совершен переход в каталог с проектом и введена команда «make» (рисунок 1.1.3).
Рисунок 1.1.3 – Сборка проекта
Далее подключена отладочная плата к компьютеру и введена команда «make upload» для загрузки прошивки на плату (рисунок 1.1.4).
Рисунок 1.1.4 – Результат выполнения представленной команды
Для тестирования работы прошивки был открыт gtkterm и использована команда: sudo gtkterm -s 115200 -p /dev/ttyACM0, необходимая для запуска терминала для связи по последовательному порту.
После перезагружен микроконтроллер, нажав на черную кнопку Reset на плате. В результате в gtkerm отобразился следующий текст, представленный на рисунке 1.1.5.
Рисунок 1.1.5 – Работа прошивки в микроконтроллере
1.2 Разработка прошивки
Прошивка требует ввод нескольких чисел через запятую. В случае корректного ввода управление передается функции operate(). Результат работы программы после ввода чисел представлен на рисунке 1.2.1.
Рисунок 1.2.1 – Работа прошивки после ввода данных
После исполнения функции operate(), происходит вывод содержимого исходного массива buf _in и массива с результатами вычислений buf _out, длина которого равняется len_out. После чего цикл повторяется - программа вновь просит ввести новый массив.
1.3 Ассемблер
В данной главе была проделана функция operate() по варианту №4: вычислить сумму первого и последнего чисел массива (рисунок 1.3.1).
Рисунок 1.3.1 – Вычисление суммы первого и последнего числа массива
Листинг программы находится в Приложении А.
1.4 Отладка ассемблера в симуляторе
Для отладки алгоритма, написанного на языке ассемблера, был совершен переход на сайт симулятора и вставлен код по откладке алгоритма.
Данный код является примером реализации функции operate() и, для примера, изменяет содержимое массивов, переданных по ссылкам buf _in и buf _out, а также значение buf _out.
Результат работы представлен на рисунке 1.4.1.
Рисунок 1.4.1 – Отладка алгоритма в симуляторе
1.5 Автоматизация тестирования
Была протестирована работа прошивки в автоматизированном режиме, для этого использован python.
В приложении А представлен листинг программы на python для взаимодействия по последовательному порту с микроконтроллером.
Далее сохранен файл как «test_lab1.py» и запущен, в результате получилось так, как представлено на рисунке 1.5.1.
Рисунок 1.5.1 – Работа прошивки после ввода данных
1.6 Исследование файла прошивки
Для дизассемблирования прошивки была использована программу arm-none-eabi-objdump и введена команда: arm-none-eabi-objdump -d lab1.elf.
Заключение
В ходе выполнения данной лабораторной работы была изучена архитектура ARM на примере микроконтроллера STM32F103RBT6, разработана программа на языке ассемблера для данного микроконтроллера, а также изучено содержимое объектного файла.
Приложение А
(обязательное)
Листинг программы в Ассемблер
.syntax unified
.cpu cortex-m3
.fpu softvfp
.thumb
.global operate
.section .text
.type operate, %function
/* void operate(int *buff_in, size_t len_in,
int *buff_out, size_t buff_size,
size_t *len_out);
r0 = buff_in
r1 = len_in
r2 = buff_out
r3 = buff_size
[sp, #36] = len_out (после push 9 регистров)
*/
operate:
/* Сохраняем регистры согласно AAPCS (9 штук) */
stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
/* Если массив пустой (len_in == 0) → результат 0 */
cmp r1, #0
beq empty_array
/* Загружаем первый элемент: buff_in[0] */
ldr r4, [r0] // r4 = buff_in[0]
/* Если в массиве только один элемент — он же и последний */
cmp r1, #1
beq store_result
/* len_in ≥ 2 → считаем адрес последнего элемента */
sub r5, r1, #1 // r5 = len_in - 1
ldr r5, [r0, r5, lsl #2] // r5 = buff_in[len_in-1]
add r4, r4, r5 // r4 = первый + последний
b store_result
empty_array:
mov r4, #0 // пустой массив → возвращаем 0
store_result:
/* Записываем результат в buff_out[0] */
str r4, [r2, #0]
/* Устанавливаем длину выходного массива: len_out = 1 */
mov r5, #1
ldr r6, [sp, #36] // адрес len_out
str r5, [r6]
/* Восстанавливаем регистры и возвращаемся */
ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
.size operate, .-operate
Приложение Б
(обязательное)
Листинг программы на python
import serial
import random
PORT = '/dev/ttyACM0'
TIMEOUT = 0.5
rx = b''
toggle = input("Введите массив через запятую, или введите 'r' для генерации случайного массива: \n>>> ")
if toggle == 'r':
toggle = input("Введите длину массива: ")
tx = [str(random.randint(0, 64)) for _ in range(int(toggle))]
tx = ','.join(tx) + "\n"
tx = tx.encode("utf-8")
else:
tx = toggle + "\n"
tx = tx.encode("utf-8")
print(tx)
s = serial.Serial(port=PORT, baudrate=115200, timeout=TIMEOUT)
s.write(tx)
rx = s.read(1000)
rx = rx.decode("utf-8")
rx = rx.split("\r\n")
for i in rx:
print(f"{i}")
s.close()
