У вас там много вопросов.Для начала давайте предположим простую ситуацию, такую как Arduino, которая представляет собой комбинацию программного и аппаратного обеспечения.Программная часть начинается с написания вами простого кода на C ++, например:
byte ledPin = 13;
void setup(){
pinMode (ledPin, OUTPUT);
}
void loop(){
digitalWrite (ledPin, HIGH);
digitalWrite (ledPin, LOW);
}
Затем вы должны скомпилировать код.Arduino IDE (интегрированная среда разработки) выполняет некоторые вещи (в фоновом режиме, например, добавляя main (), который будет вызывать функцию setup () один раз, и функцию loop () повторно), чтобы превратить этот C ++ в код ассемблера, которыйможет выглядеть так (не фактический вывод из приведенного выше):
; Define pull-ups and set outputs high
; Define directions for port pins
ldi r16,(1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0)
ldi r17,(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0)
out PORTB,r16
out DDRB,r17
; Insert nop for synchronization
nop
; Read port pins
in r16,PINB
Ассемблер, который берет этот код и преобразует его в шестнадцатеричный формат информации, которую программист может поместить в ПЗУ на микроконтроллере Atmega328P.В основном, строки данных в файле, каждая строка содержит начальный адрес строки, возможно, 16 байтов данных, и контрольную сумму, чтобы убедиться, что данные не были повреждены во время их обработки:
000100005673495a6b4f5e205673495a6b4f5e24465
Это не реальные данные.0001000 может быть начальным адресом в ПЗУ, следующие 32 символа - это 16 байтов данных, которые должны быть запрограммированы, а последние 4 могут быть контрольной суммой, которая создается путем манипулирования данными каким-либо образом.Программист получает данные, выполняет те же манипуляции и, если контрольная сумма верна, записывает их в память.
Шестнадцатеричный код может быть помещен в ПЗУ несколькими способами - программист может получить контроль над чипом.и поместите код в память напрямую, и после сброса чип просто запустит код; или загрузчик может быть запущен из области ПЗУ на чипе после сброса, и он будет общаться с ПК по последовательным линиям(Rx, Tx), чтобы получить данные, а затем записать их в другую область ПЗУ.Если код загрузки не обнаружил ПК, пытающийся с ним поговорить, он перешел бы к адресу ПЗУ, с которого код запускался и запускался оттуда.
8-битные микроконтроллеры могут иметь 16-битные регистры, которые он может использовать длятакие вещи, как захват результатов преобразования АЦП или сохранение результатов в виде двух 8-битных байтов с данными старшего и младшего разрядов.
Стек может быть выделенным аппаратным регистром или областьюSRAM, который используется для хранения таких вещей, как результаты математических операций.Код заботится о том, чтобы поместить вещи в стек и прочитать их обратно, обычно вы не будете заниматься программированием.С '328P, имеется 2048 байтов SRAM, поэтому вам нужно всего лишь убедиться, что у вас не слишком много объявленных переменных в коде (например, байт ledPin = 13;), который использовал все это и не оставлял местадля кода.Зачастую, например, в 328P это вызвано попыткой доступа к массиву за его пределами, поэтому либо возвращаются бессмысленные результаты, либо происходит сбой программы, когда запись после конца массива перезаписывает что-то другое.Гибкость C ++ великолепна, но она также позволит вам столкнуться с проблемами, если не позаботиться о ней.