Potrzebowal bym skladnie komend BootLoadera mikrokontrolera AT90S2313, oraz skladnia plikow stosowanych programatorach. Za pomoc bylbym wdzieczny!
Czy wolisz polską wersję strony elektroda?
Nie, dziękuję Przekieruj mnie tam
'Program Bootloadera (monitora) dla ATmega8 umożliwiający ładowanie
'programu do pamięci Flash przez interfejs RS232 z prędkością 19200
'bodów
'Bity fuse należy ustawić, by na Bootloader było przeznaczonych 128
'bajtów
'Początek adresu programu Bootloadera: $F80
'Fuse bity: Wielkość: Miejsce: Bootloader: Koniec: Początek:
'BOOTSZ1 BOOTSZ0
' 1 1 128 $000 - $F7F $F80 - $FFF $F7F $F80
'Bootloader pobiera plik w standardzie Intel HEX
'Przykład pliku HEX:
':Size Address Type Data Bytes Checksum
':10 00 00 00 26 C0 B3 C0 B3 C0 B3 C0 B3 C0 C5 C0 C5 C0 D0 C0 A4
':10 00 10 00 DB C0 E4 C0 ED C0 30 31 32 33 34 35 36 37 38 39 E7
'...
'...
':10 05 30 00 55 DF 08 95 57 E5 57 DF 52 E5 55 DF 54 E5 53 DF A2
':10 05 40 00 5C E2 51 DF 53 2F 52 95 49 DF 53 2F 47 DF 01 D0 33
':0B 05 50 00 08 95 5D E0 48 DF 5A E0 46 DF 08 95 A2 DC
':00 00 00 01 FF
$regfile = "m8def.dat" 'informuje kompilator o pliku
'dyrektyw mikrokontrolera
$crystal = 8000000 'informuje kompilator
'o częstotliwości oscylatora
'taktującego mikrokontroler
Const Ramend_lo = $5f 'ustawienie adresu końca pamięci
'RAM
Const Ramend_hi = $04
Const Pagesize = 32 'rozmiar strony pamięci Flash
'w słowach
'definicje zmiennych
!.def Tmp_reg = R16 'rejestr tymczasowy
!.def Hex_reg = R17 'rejestr przeliczeniowy HEX
!.def Ser_reg = R18 'rejestr będący buforem
'szeregowym
!.def SPM_reg = R19 'tymczasowy rejestr dla rozkazu
'SPM
!.def Rec_size = R20 'numer bajtu danych w linii
'pliku HEX
!.def Chk_sum = R21 'przechowuje sumę kontrolna
'początek programu umożliwiającego wywołanie Bootloadera
Config Pinb.1 = Input 'linia PB1 jako wejściowa
S1 Alias Pinb.1 'przypisanie nazwie Pinb.1
'nazwy S1
Set Portb.1 'dołączenie do linii PB1
'rezystora podciągającego
Do 'nieskończona pętla Do...Loop
If S1 = 0 Then 'jeśli naciśniety przycisk S1, to
Waitms 25 'opóźnienie 25 ms dla eliminacji
'drgań styków
If S1 = 0 Then 'sprawdzenie ponownie, czy S1
'jest naciśniety, jeśli tak, to
JMP $F80 'skok do programu Bootloadera
End If 'koniec warunków
End If
Loop 'koniec nieskończonej pętli
End 'koniec programu
'*********************************************************************
'Początek Bootloadera napisanego w asemblerze
$boot = $f7f 'ustawienie wektora Boot na
'adres F7F, od tego adresu
'zostanie załadowany do pamięci
'program Bootloadera
NOP 'instrukcji NOP
Disable Interrupts 'wyłączenie globalnych przerwań
_bootloader_start: 'początek Bootloadera
LDI Tmp_reg, Ramend_Hi 'wpisanie do Tmp_reg górnej
'wartości adresu pamięci SRAM
!OUT SPH, Tmp_reg 'ustawienie bardziej znaczącego
'bajtu wskaźnika stosu
LDI Tmp_reg, Ramend_Lo 'wpisanie do Tmp_reg dolnej
'wartości adresu pamięci SRAM
!OUT SPL, Tmp_reg 'ustawienie mniej znaczącego
'bajtu wskaźnika stosu
LDI Tmp_reg, $00 'wpisanie do Tmp_reg ustawienia
'usartu
!OUT UCSRA, Tmp_reg 'ustawienie USARTu
LDI Tmp_reg, $18 'wpisanie do Tmp_reg następnych
'ustawień USARTu
!OUT UCSRB, Tmp_reg 'ustawienie USARTu
LDI Tmp_reg, $86 'wpisanie do Tmp_reg następnych
'ustawień USARTu
!OUT UCSRC, Tmp_reg 'ustawienie USARTu
LDI Tmp_reg, $00 'wpisanie do Tmp_reg bardziej
'znaczącego bajtu, który określa
'prędkość
!OUT UBRRH, Tmp_reg 'ustawienie USARTu
LDI Tmp_reg, 25 'wpisanie do Tmp_reg mniej
'znaczącego bajtu, który określa
'prędkość
!out UBRRL,tmp_reg 'ustawienie USARTu
CLT 'zerowanie flagi T, użytej do
'wskazania końca pliku HEX
_send_boot_msg: 'wysyła znak B oznaczający start
'Bootloadera
LDI Ser_reg, Asc("B") 'wpisanie znaku B do Ser_reg
RCALL _send_ser 'wysłanie znaku B przez RS232
_read_lines: 'odczytuje linie z szeregowego
'interfejsu RS232 do pamięci
'SRAM
RCALL _receive_hex_line 'otrzymanie pojedynczej linii
'zapisanej do pamięci SRAM
_parse_line: 'dekoduje wybrana linie HEX
LDI XH, $01 'początek linii, bardziej
'znaczący bajt, od $0100
LDI XL, $00 'początek linii, mniej znaczący
'bajt
CLR Chk_sum 'wyzerowanie rejestru sumy
'kontrolnej dla tej linii
_read_header: 'odczytuje dane
LD Tmp_reg, X+ 'pierwszym otrzymanym znakiem
'powinien być znak :
CPI Tmp_reg, Asc(":") 'porównanie czy otrzymano : i
'ustawienie flagi błędu
BREQ _header_ok 'odczytanie kolejnego rekordu
_header_err: 'jeśli nie otrzymano :
LDI Ser_reg, Asc("!") 'wpisanie znaku błędu !
RCALL _send_ser 'wysłanie znaku błędu
_header_ok: 'odczyt następnego rekordu
_read_record_size: 'odczytanie danych wybranej
'linii
RCALL _char_to_byte 'wywołanie podprogramu konwersji
'znaku na bajt
MOV Rec_size, Hex_reg 'zapis numeru bajtu w tej linii
TST Rec_size 'test, czy rekord ma wartość 0
'dla tej linii
BRNE _read_address 'jeśli nie, to nie koniec linii
'i kontynuacja odczytu
!SET 'ustawienie flagi T kiedy
'wskazywana jest ostatnia strona
RJMP _write_current_page 'koniec linii, zapisanie
'aktualnej strony i wyjście do
'głównego programu
_read_address: 'odczytanie bajtu bardziej
'i mniej znaczącego adresu
'i zapis do ZH/ZL
RCALL _char_to_byte 'wywołanie podprogram konwersji
'znaku na bajt
MOV ZH, Hex_reg 'wpisanie do ZH strony z bajtem
'bardziej znaczącym adresu
RCALL _char_to_byte 'wywołanie podprogramu konwersji
'znaku na bajt
MOV ZL, Hex_reg 'wpisanie do ZH strony z bajtem
'mniej znaczącym adresu
_read_record_type: 'odczyt typu rekordu linii
RCALL _char_to_byte 'wywołanie podprogramu konwersji
'znaku na bajt
_read_data_pairs: 'odczyt pozostałych bajtów
'danych
RCALL _char_to_byte 'wywołanie podprogramu konwersji
'znaku na bajt
MOV R0, Hex_reg 'zapisanie w R0 mniej znaczącego
'bajtu strony zapisanej
'w buforze
RCALL _char_to_byte 'wywołanie podprogramu konwersji
'znaku na bajt
MOV R1, Hex_reg 'zapisanie w R1 bardziej
'znaczącego bajtu strony
'zapisanej w buforze
_store_word: 'zapisanie aktualnych R1/R0
'słowa w stronie bufora pod
'odpowiednim adresem
LDI Spm_reg, 1 'włączenie SPM (Enable (SPMEN))
RCALL _exec_spm 'wykonanie aktualnego SPM
_check_byte_count: 'sprawdzenie, czy było to
'ostatnie słowo linii
SUBI Rec_size, 2 'zmniejszenie Rec_Size o dwa
'bajty
BREQ _read_checksum 'po zapisie danych czytana jest
'suma kontrolna
SUBI ZL, $FE 'gdy dane jeszcze nie zapisane,
'to inkrementowane dwa mniej
'znaczące bajty adresu
RJMP _read_data_pairs 'odczytanie następnych dwóch
'znaków
_read_checksum: 'sprawdza sumę kontrolna
'następnej linii
RCALL _char_to_byte 'wywołanie podprogramu konwersji
'znaku na bajt
BREQ _checksum_ok 'jeśli 0, to suma kontrolna
'prawidłowa
_checksum_err: 'jeśli suma kontrolna
'nieprawidłowa lub inny
'znaleziony błąd, to
LDI Ser_reg, Asc("!") 'wpisanie znaku ! będącego flagą
'błędu
RCALL _send_ser 'wysłanie załadowanego znaku
_checksum_ok:
_chk_page_full: 'sprawdza, czy strona jest pełna
MOV Tmp_reg, ZL 'wpisanie mniej znaczącego bajtu
'adresu Do Tmp_reg
ANDI Tmp_reg, ((Pagesize - 1 )*2) 'iloczyn logiczny z wielkością
'strony
CPI Tmp_reg, ((Pagesize - 1 )*2) 'porównanie z wielkością strony
'dla tego adresu
BRNE _read_lines 'strona bufora nie jest pełna,
'odczyt następnej linii
_write_current_page: 'zapis aktualnej strony
_erase_page: 'wyczyszczenie strony
LDI Spm_reg, 3 'odblokowanie SPM
RCALL _exec_spm 'wykonanie SPM
_write_page: 'zapisuje stronę
ANDI ZL, $C0 'zapewnienie, że bity Z5...Z0 są
'0
LDI Spm_reg, 5 'zapis strony i odblokowanie SPM
RCALL _exec_spm 'wykonanie SPM
_enable_page: 'włączenie strony dla sekcji
'Read-While-Write
RCALL _wait_spm 'sprawdzenie, czy zapis kompletny
LDI Spm_reg, 11 'ustawienie tylko RWWSRE i SPMEN
RCALL _exec_spm 'wykonanie SPM
_check_end_of_file: 'sprawdzenie, czy to nie jest
'koniec pliku
BRTC _read_lines 'jeśli nie jest to ostatnia
'strona, to kontynuacja odczytu
'linii
_exit_bootloader: 'wyjście z programu Bootloader
JMP $0000 'skok do wektora Reset
'********************************************************************
_send_ser: 'wysyła znak przez RS232
SBIS UCSRA,UDRE 'sprawdza, czy rejestr nadawczy
'USARTu jest pusty
RJMP _send_ser 'jeśli nie, to czekaj
!OUT UDR,ser_reg 'wysłanie znaku
RET 'koniec podprogramu
'********************************************************************
'pobiera jedna linie przez RS232 i zapisuje ją od początku pamięci
'SRAM
_receive_hex_line:
LDI XH, $01 'ustawienie wskaźnika do SRAM na
'adres $0100
LDI XL, $00 'powyżej są wszystkie rejestry
LDI Ser_reg, Asc("?") 'ładuje znak ? dla żądania
'następnego znaku
RCALL _send_ser 'wywołanie podprogramu wysłania
'znaku
_receive_hex_line_char: 'pobiera znak z USARTu i dodaje
'go do bufora
SBIS UCSRA, RXC 'sprawdza, czy otrzymano znak
'z USARTu
RJMP _receive_hex_line_char 'jeśli nie, to ponowne
'sprawdzenie
IN Tmp_reg, UDR 'zapisanie otrzymanego znaku do
'tmp_reg
' MOV Ser_reg, Tmp_reg 'echo dla kontroli odebranych
'znaków
' RCALL _send_ser 'wywołanie podprogramu wysłania
'znaku
CPI Tmp_reg, 13 'porównanie otrzymanego znaku
'z CR,
BREQ _receive_hex_line_end 'jeśli taki sam, to koniec
'linii,
ST X+, Tmp_reg 'w przeciwnym razie zwiększenie
'wskaźnika buforu
RJMP _receive_hex_line_char 'i odczytanie następnego znaku
_receive_hex_line_end: 'linia wykonywana, gdy koniec
'linii
RET 'powrót z tego podprogramu
'********************************************************************
'pobiera dwa znaki z bufora, dodaje sumę kontrolna i zwraca rezultat
'zamiany znaków na bajty w Hex_reg
_char_to_byte:
LD Hex_reg, X+ 'wpisanie znaku do Hex_reg
'i zwiększenie X
SUBI Hex_reg, $41 'odjęcie znaku ASCII $41, (A)
BRCC _char_to_byte1 'skok, gdy wartości są większe
'od $41,
SUBI Hex_reg, $F9 'gdy nie większe, to odejęcie
'$F9
_char_to_byte1:
SUBI Hex_reg, $F6 'odjęcie $F6
LSL Hex_reg 'przesunięcie bitów w Hex_reg o
LSL Hex_reg '4 pozycje w lewo
LSL Hex_reg
LSL Hex_reg
LD Tmp_reg, X+ 'pobranie następnego znaku
SUBI Tmp_reg, $41 'odjęcie znaku ASCII $41, (A)
BRCC _char_to_byte2 'skok, gdy wartości są większe
'od $41,
SUBI Tmp_reg, $F9 'gdy nie większe, to odjęcie $F9
_char_to_byte2:
SUBI Tmp_reg, $F6 'odjęcie $F6
ADD Hex_reg, Tmp_reg 'dodanie Tmp_reg do Hex_reg
ADD Chk_sum, Hex_reg 'dodanie do sumy kontrolnej
'Hex_reg
RET 'powrót z podprogramu
'********************************************************************
_exec_spm: 'wykonuje rozkaz SPM
!OUT SPMCR, Spm_reg 'wysłanie do SPM wartości
'Spm_reg
SPM 'rozkaz SPM
_wait_spm: 'sprawdzenie, czy zapis do
'pamięci Flash kompletny
IN Spm_reg, SPMCR 'pobranie do Spm_reg SPM
SBRC Spm_reg, SPMEN 'sprawdzenie, czy SPM Enable
'flaga jest wyzerowana
RJMP _wait_spm 'jeśli nie, to czekanie aż flaga
'będzie wyzerowana
RET 'flaga wyzerowana, powrót
'podprogramu
'********************************************************************
Sinbad23 napisał:Potrzebowal bym skladnie komend BootLoadera mikrokontrolera AT90S2313, oraz skladnia plikow stosowanych programatorach. Za pomoc bylbym wdzieczny!
Sinbad23 napisał:Z tej prostej przyczyny, ze bootloader powinien być zdolny do programowania, a jeśli np. AT90S2313 nie ma rozkazu spm(Store Program Memory), to nic, pomimo największych chęci nie zapiszesz... W nowszych AVR jest poza tym wsparcie sprzętowe w postaci wydzielenia obszaru bootloadera od reszty pamięci programu (na jej końcu), gdzie można sobie kombinować z uprawnieniami zapisu i odczytu (Lockbits). Szczegóły jak zwykle w pdf-ach :Nie rozumiem dlaczego nie kazdy mikrokontroler moze miec bootlodare zwasza ten mikrokontroler, ktory posiada pamięc Flash.
Sinbad23 napisał:Jeśli mikroprocesor jest w architekturze von Neumana, to zawsze można zapisać do pamięci RAM czy jakiekolwiek innej i skoczyć pod określony adres. Jeśli natomiast jest w architekturze Harvardzkiej to nie ma programowej możliwości wystawienia danych i adresów na liniach pamięci programu, do tego konieczny jest odpowiedni sprzęt i dodatkowe układy wewnątrz procesora. Operacje zapisu do pamięci flash np w procesorach atmel robi się specjalnym rozkazem, natomiast w procesorach microchip przy pomocy rejestrów które służą do zapisu pamięci eeprom.Nie rozumiem dlaczego nie kazdy mikrokontroler moze miec bootlodare zwasza ten mikrokontroler, ktory posiada pamięc Flesh. Przeciez w kazdym mozna napisac jakos sekwencje programowa, ktora po wlaczeniu mikrokontrolera za kazdym razem np sprawdza diody, sygnal dzwiekowy, czy wyswietlacz.
Cytat:
Troche nie rozumiem czemu ma służyc rozkaz skoku do pamięci programu (i gdzie ta pamięc sie znajduje) Jak mozemy zmieniac program, który jest już wgrany do mikrokontrolera.
Sinbad23 napisał:Potrzebowal bym skladnie komend BootLoadera mikrokontrolera AT90S2313....