Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторная 1

.docx
Скачиваний:
0
Добавлен:
15.12.2025
Размер:
2.62 Mб
Скачать

Министерство науки и высшего образования Российской Федерации

Федеральное государственное автономное образовательное учреждение высшего образования

ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОННИКИ (ТУСУР)

Кафедра комплексной информационной безопасности электронно-вычислительных систем (КИБЭВС)

ЗНАКОМСТВО С АРХИТЕКТУРОЙ 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()