Загрузка кода в mega 2560

В рамках моего приложения мне нужно иметь возможность обновить код на mega 2560 в поле с помощью загрузки из Интернета.

Я нашел этот код в техническом паспорте AT Mega 2560

 ;-подпрограмма записывает одну страницу данных из оперативной памяти во флэш
-память ; на первое место данных в оперативной памяти указывает указатель Y
; на первое место данных во флэш-памяти указывает указатель Z
 ;-обработка ошибок не включена
 ;-программа должна быть помещена в загрузочное пространство
 ; (по крайней мере, подпрограмма Do_spm). Только код внутри раздела NRWW может
быть прочитан во время самопрограммирования (стирание страницы и запись страницы).
 ;-используемые регистры: r0, r1, temp1 (r16), temp2 (r17), looplo (r24),
; loophi (r25), spmcrval (r20)
 ; хранение и восстановление регистров не входит в подпрограмму
 ; использование регистра может быть оптимизировано за счет размера кода
 ;-Предполагается, что либо таблица прерываний перемещается в загрузочную
 ; раздел загрузчика или что прерывания отключены
..equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB is page size in BYTES, not words
.org SMALLBOOTSTART
Write_page:
    ; Page Erase
    ldi  spmcrval, (1<<PGERS) | (1<<SPMEN)
    call Do_spm

    ; re-enable the RWW section
    ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
    call Do_spm

    ; transfer data from RAM to Flash page buffer
    ldi  looplo, low(PAGESIZEB) ;init loop variable
    ldi  loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256

Wrloop:
    ld   r0, Y+
    ld   r1, Y+
    ldi  spmcrval, (1<<SPMEN)
    call Do_spm
    adiw ZH:ZL, 2
    sbiw loophi:looplo, 2 ;use subi for PAGESIZEB<=256
    brne Wrloop

    ; execute Page Write
    subi ZL, low(PAGESIZEB)       ;restore pointer
    sbci ZH, high(PAGESIZEB)      ;not required for PAGESIZEB<=256
    ldi  spmcrval, (1<<PGWRT) | (1<<SPMEN)
    call Do_spm

    ; re-enable the RWW section
    ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
    call Do_spm

    ; read back and check, optional
    ldi  looplo, low(PAGESIZEB)   ;init loop variable
    ldi  loophi, high(PAGESIZEB)  ;not required for PAGESIZEB<=256
    subi YL, low(PAGESIZEB)       ;restore pointer
    sbci YH, high(PAGESIZEB)
Rdloop:
    elpm r0, Z+
    ld   r1, Y+
    cpse r0, r1
    jmp  Error
    sbiw loophi:looplo, 1         ;use subi for PAGESIZEB<=256
    brne Rdloop

    ; return to RWW section
    ; verify that RWW section is safe to read
Return:
    in   temp1, SPMCSR
    sbrs temp1, RWWSB     ; If RWWSB is set, the RWW section is not ready yet
    ret
    ; re-enable the RWW section
    ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
    call Do_spmr
    jmp Return

Do_spm:
    ; check for previous SPM complete
Wait_spm:
    in   temp1, SPMCSR
    sbrc temp1, SPMEN
    rjmp Wait_spm
    ; input: spmcrval determines SPM action
    ; disable interrupts if enabled, store status
    in   temp2, SREG
    cli
    ; check that no EEPROM write access is present
Wait_ee:
    sbic EECR, EEPE
    rjmp Wait_ee
    ; SPM timed sequence
    out  SPMCSR, spmcrval
    spm
    ; restore SREG (to enable interrupts if originally enabled)
    out  SREG, temp2
    ret

Я пытаюсь преобразовать это в код, который я могу использовать в своем проекте arduino в разделе проводка. Мой первый вопрос-это реестр. Похоже, что spmcrval-это регистр 20, но как я могу получить доступ к этому регистру из моего проекта arduino?

Я нашел константы, такие как SPMEN в заголовке arduino, но не эти имена регистров.

Кроме того, не стесняйтесь, если хотите, избежать драмы и сказать: "Вот исходный код C", который будет стоить определенного поклонения герою.

Похоже, все использует avrdude, и поэтому я пытаюсь разобрать и это.

, 👍2

Обсуждение

https://github.com/jandrassy/ArduinoOTA/blob/master/examples/Advanced/OTASketchDownload/OTASketchDownload.ino, @Juraj


1 ответ


Лучший ответ:

3

Только из раздела загрузчика можно писать во flash на ATmega2560. Optiboot 8 имеет функцию do_spm для записи во flash. Он доступен через заголовочный файл, доступный в примерах в репозитории OptibootGitHub.

После того, как обновленный двоичный файл приложения будет записан в свободную часть флэш-памяти запущенным приложением, необходимо скопировать обновленное приложение в место запуска с адреса 0. Это должно быть сделано снова загрузчиком.

Сборки Optiboot в MCUdude Mega Core и Mighty Core имеют Optiboot, усиленный моей функцией copy_flash_pages, которая копирует страницы, а затем сбрасывает MCU.

Моя библиотека ArduinoOTA использует функции do_spm и copy_flash_pages для хранения и применения загруженного двоичного файла скетча. Объект InternalStorage также можно использовать для применения загруженного двоичного файла.

,

То, что я вижу, обрабатывает загрузки. Есть ли здесь что-то, что устанавливает эти загрузки в Mega 2560? Я отталкиваюсь от планшета., @Thom

это самообновление. вызов InternalStorage.apply заменяет скетч загруженным двоичным файлом, @Juraj

разместил еще один вопрос здесь: https://arduinoprosto.ru/q/85142/program-a-mega2560-from-a-different-serial-port о том, как изменить последовательный порт на тот, который используется HC-05. не могу найти пример, но он кажется простым., @Thom