This repository has been archived by the owner on Jul 20, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
The MCS51 Microcontroller emulator written in C (very old abandoned project)
License
MDobak/Simple-MCS-51-Debugger
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
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 0
No packages published