Skip to content
This repository has been archived by the owner on Jul 20, 2020. It is now read-only.

MDobak/Simple-MCS-51-Debugger

Repository files navigation

Półtora roku temu napisałem w C (wymóg wykładowcy) taki program na studiach (na pierwszym semestrze ;) )- jest to symulator mikrokontrolerów MCS-51. Program wydaje się być poprawny, bez problemu radzi sobie z nawet bardzo złożonymi programami (w przykładowych programach jest nawet tetris :D ), ma kilka ciekawych funkcji debuggerskich, wbudowany deassambler, możliwość dodawania breakpointów czy nawet breakpontów z warunkami i szczerze mówiąc nie pamiętam co on więcej może, bo do tego kodu nie dotykałem się dobre 1.5 roku. Po oddaniu programu na zaliczenie coś jeszcze w nim grzebałem stąd parę niedokończonych funkcji. Pozbyłem się też niestety większości komentarzy bo wiele z nich było już aktualnych i raczej wprowadzało w błąd niż pomagało ;( 

Programu rozwijać raczej nie będę, ale, że jest to kawałek całkiem przyzwoitego kodu i szkoda żeby się marnował oddaje go wam, może komuś się przyda by lepiej zrozumieć działanie mikrokontrolera, może ktoś zacznie go rozwijać a może ktoś wykorzysta fragment kodu ;) 

I to tyle, niech program i jego źródła mówią dalej za siebie. 

Poniższy poradnik jest częsciowo nieaktualny!

WSTĘP
========================

Witaj w programie S51D! Ten program jest rozpowszechnainy na licencji
GNU General Public License (GPL). Teraz...

WPROWADZENIE
========================

S51D jest symulatorem 8-mio bitowych mikrokontrolerów opertych na
architekturze MCS-51. Program był tworzony głównie z myślą o mikrokontrolerze
Intel 8052, co oznacza, że jest także kompatybilny z Intel 8031/8051 oraz
innymi które są kompatybilne z wymienionymi. 

Program zakłada, że dysponujemy 256 bajtami pamięci wewnętrznej RAM,
64kB pamięci zewnętrznej ROM i 64kB pamięci zewnętrznej RAM co stanowi 
maksymlne dopuszczalne wartości. Program obsługuje wszystkie instrukcje
procesora, instrukcje 0xA5 traktuje jak nop. Obsługiwane są wszystkie timery
i przerwania. 

Program wyposażony jest w debugger pozwalający kontrolować działanie
wgranego do pamięci programu, wpływać na jego prace, modyfikować pamięć
ustawiać breakpointy aktywowane na trzy różne sposoby: aktywowane ustawieniem
PC (program counter, lub też IP - instruction pointer) na określoną wartość,
próbą odczytu określonego adresu z wybranej pamięci lub zmianą wartości
wybranych adresów w pamięci.

INSTRUKCJA
========================

                               ...Podstawy...

Po uruchomieniu programu pojawia się znak zachęty, który zazwyczaj wygląda tak:
cmd:>

Po nim, należy podać jedną z obsługiwanych przez program komend. Ich pełną
listę można zobaczyć wpisując komendę `help`.

Po uruchomieniu programu pamięć mikrokontrolera jest wyzerowana, można się
o tym przekonać wpisując komende `hex rom` która spowoduje wyświetlenie
zawartości pamięci rom. 
cmd:>hex rom
0x0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
...
0xFFC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0xFFD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0xFFE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0xFFF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

Wyświetlony listing jest bardzo długi i zazwyczaj nie mieści się w oknie
konsoli. Można więc zapisać go do pliku zmianiając standardowe wyjście 
operatorem `>`.
cmd:>hex rom > pamiec_rom.txt

Po komendzie `hex` należy podać nazwe pamięci do wyświetlenia, np. "rom", 
"intram", "extram", "sfr". Po nazwie można podać adres od którego ma zacząć
być wyswietlana zawartość pamięci i adres końcowy. Np:
cmd:>hex sfr 90 b0
0x0090 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00A0 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00B0 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

Aby załadować do pamięci program należy użyć komendy `load` i podać lokalizacje
pliku intel hex z kodem programu. Np:
cmd:>load examples/hello.hex

Wykonanie tej komendy nie powoduje wyświetlenia żądnego wyniku jeśli
program został wczytany do pamięci bez problemu. Argumenty do komend
można podawać w cudzysłowach dzięki czemu można w nich zawierać spacje, inną
metodą wyłączenia traktowania białych znaków, jako separatorów argumentów jest
poprzedzenie ich znakiem "\" (lewy ukośnik). Analogicznie można poprzedzić
cudzysłowy tym znakiem aby nie traktować ich specjalne. Lewym ukośnikiem
można też poprzedzić sam ukośnik aby go dodać do argumentu. Przykłady:
cmd:>load "../rozne pliki/moj plik.hex"
cmd:>load ../rozne\ pliki/moj\ plik.hex
cmd:>load "..\\rozne pliki\\moj plik.hex"
cmd:>load ..\\rozne\ pliki\\moj\ plik.hex

Możemy przekonać się, że program został załadowany ponownie wykonując
komende `hex`:
cmd:>hex code 6c0 700
0x06C0 9B F5 83 22 20 F7 14 30 F6 14 88 83 A8 82 20 F5 ..." ..0...... .
0x06D0 07 E6 A8 83 75 83 00 22 E2 80 F7 E4 93 22 E0 22 ....u.."....."."
0x06E0 75 82 00 22 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 u.."Hello world!
0x06F0 00 3C 4E 4F 20 46 4C 4F 41 54 3E 00 00 00 00 00 .<NO FLOAT>.....
0x0700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

Do kontroli działania wczytanego programu używamy przedewszystkim
komend `run`, `stop`, `output`, `hexoutput`, `step`, `trace`.

Na początek omówimy komende `step`. Nie przyjmuje ona żadnych argumentów.
Jej działanie jest bardzo proste. powoduje ona wykonanie jednej instrukcji
procesora, wypisanie na ekran informacji o wykonanej komendzie i niektóre
wartości. Adresy w pamięciach IDATA, XDATA i SFR są określane zmieniane w
momęncie zmiany ich wartości.
cmd:>step
0008: 75 81 3A mov   SP, #3Ah
IDATA[00h]=00   XDATA[0000h]=00 SFR[SP]=3A      PSW=01          TCON=00
ACC=00          DPTR=0000       @DPTR=0000      SBUF[out]=00    SBUF[in]=00

Używając komend `byte` i `bit` można wyświetlić, lub zmienić inne wybrane
komórki pamięci:
cmd:>byte sfr p0
SFR[80]=FF
cmd:>bit sfr p0 1
SFR[80.1] = true
cmd:>bit sfr p0 1 0
cmd:>byte sfr p0
SFR[80]=FD

Kolejną komendą pozwalającą wykonać kod jest `trace`. Komenda ta wyświetla
wykonywane instrukcje. Komenda przyjmuje conajmniej jeden argument określający
ilość komend jakie mają byc wykonane.
cmd:>trace 10
000B: 12 06 E0 lcall 06E0
06E0: 75 82 00 mov   DPL, #00h
06E3: 22       ret
000E: E5 82    mov   A, DPL
0010: 60 03    jz    0015h
0015: 79 00    mov   R1, #00h
0017: E9       mov   A, R1
0018: 44 00    orl   A, #00h
001A: 60 1B    jz    0037h
0037: E4       clr   A
Stoped at 0038h after execute 10 instructions.

Podając dodatkowy parametr "1" funkcja wyświetla więcej informacji. Z tym
parametrem jej działanie przypomina wykonywanie kolejno instrukcji step.
cmd:>trace 3 1
0038: 78 FF    mov   R0, #FFh
IDATA[00h]=FF   XDATA[0000h]=00 SFR[SP]=3A      PSW=01          TCON=00
ACC=00          DPTR=0000       @DPTR=0000      SBUF[out]=00    SBUF[in]=00
003A: F6       mov   @R0, A
IDATA[00h]=FF   XDATA[0000h]=00 SFR[SP]=3A      PSW=01          TCON=00
ACC=00          DPTR=0000       @DPTR=0000      SBUF[out]=00    SBUF[in]=00
003B: D8 FD    djnz  R0, 003Ah
IDATA[00h]=FE   XDATA[0000h]=00 SFR[SP]=3A      PSW=01          TCON=00
ACC=00          DPTR=0000       @DPTR=0000      SBUF[out]=00    SBUF[in]=00
Stoped at 003Ah after execute 3 instructions.

W każdej chwili można wyświetlić adres kolejnej instrukcji jaka zotanie
wykonana, czyli aktualny PC. Aby to zrobić należy użyć komendy `pc`.
cmd:>pc
PC = 003A

Podając argument do funkcji można zmienić aktualną wartość PC.

Komenda `run` uruchamia program w tle. W trakcie, gdy jest on uruchomiony
niektóre komendy moga nie działać (zostanie wyświetlony komunikat), 
jednak cały czas możemy analizować działąnie programu i zatrzymać go w 
dowolnym momencie komendą `stop`. Program, może sam zatrzymać wykonywanie
programu gdy mikrokontroler wyśle sygnał PD (power down), natrafi na pętle
z której nie może się wydostać przyjednoczesnym braku zezwoleń dla przerwań lub
po ukatywnieniu jednego z breakpoint'ów.

W każdej chwili można zresetować mikrokontroler komedną `reset` która przywraca
mikrokontroler do stanu początkowego. Zeruje pamięci z wyjątkiem pamięci ROM.

Ostatnimi komendami są output i hexoutput. Powodują one uruchomienie 
programu wraz z sukcesywnym wysyłaniem zawartości SBUF i pobieraniem
kodu klawiszy z klawiatury. Działąnie programu można zatrzymać w dowolnym
momęcie kombinacją klawiszy Ctrl+Q (można zmienić komendą `setexitkey`).
cmd:>load hello.hex
cmd:>terminal
Hello world!

W każdym momencie można wywołać komende `state` która wyświetla podstawowe
informacje o mikrokontrolerze.
cmd:>state
Cycles: 2116
Oscillator clocks: 25392
Oscillator frequency: 11059200 Hz
Executed instructions: 1312
Run time: 0.00229384 seconds
Sim time: 0.00200000 seconds
Max value of stack pointer: 0x51
Highest used ROM address: 0x06F0
Highest used IDATA address: 0xFF
Lowest used IDATA address: 0x00
Highest used XDATA address: Not used.
Lowest used XDATA address: Not used.
Microcontroller state: OK

Ostatnią rzeczą o jakiej warto wspomnieć w instrukcji jest disassembler.
Do jego wywołania służą funkcje `disassemble` i jej prostszy zamiennik `deasm`.
Komenda przyjmuje dwa argumenty, adres od którego wyświetla kod i ilość
istrukcji do wyświetlenia.
cmd:>deasm 0 10
0000: 02 00 08 ljmp  0008
0003: 12 00 B7 lcall 00B7
0006: 80 FE    sjmp  0006h
0008: 75 81 3A mov   SP, #3Ah
000B: 12 06 E0 lcall 06E0
000E: E5 82    mov   A, DPL
0010: 60 03    jz    0015h
0012: 02 00 03 ljmp  0003
0015: 79 00    mov   R1, #00h
0017: E9       mov   A, R1

Skoro dotarłeś tak daleko w czytaniu tego mam małą niespodziankę :-) !
Wykonaj tę komendę:
cmd:>exec for.fun

                            ...Breakpoint'y...

Żaden porządny debugger nie obejdzie się bez możliwości stawiania breakpointów.
Aby utworzyć breakpoint nalezy użyc komendy `breakpoint` lub jej krótszego
zamiennika `break`. Jej użycie jest bardzo proste. Bo argumencie podajemy 
adresy w pamięcy rom przy których działanie programu ma zostać przerwane.
cmd:>break 041b
cmd:>run
cmd:>pc
PC = 041B
                           ...Pauzy warunkowe...

S51D obsługuje dwa rodzaje pauz warunkowych, `conditionPause` i jej
prostszy zamiennik `cond`, i `accessPause` z zamiennikiem `access`.

`conditionPause` zatrzymuje działanie kiedy wartość w pamięci ram lub
sfr spełnia określony warunek. Składnia komendy wygląda tak:
conditionPause mem value operator addr ...
gdzie mem określa rodzaj pamięci, value jest wartością względem której
określone addresy (addr) mają być sprawdzone używając operatora.

Poniższy przykład zatrzyma wykonywanie programu, kiedy pierwszy bit w komórce
pod adresem 0xFD w pamięci zewnętrznej RAM będzie w stanie wysokim:
cmd:>load sieve.hex
cmd:>cond xdata 1 and fd
cmd:>terminal
10 iterations

cmd:>hex xdata f0 ff
0x00F0 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 ................

`accessPause` zatrzymuje działąnie kiedy program spróbuje odczytwać, lub
zapisać coś do określonych komórek w pamięci. W przypadku podania pamięci
rom, program nie zatrzyma się przy próbie odczytwania wartości przez
interpreter instrukcji, do tego służą breakpointy!
cmd:>load hello.hex
cmd:>access code 06ec
cmd:>terminal
Hello wo
cmd:>hex code 6e0 6ef
0x06E0 75 82 00 22 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 u.."Hello world!

About

The MCS51 Microcontroller emulator written in C (very old abandoned project)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages