Goto page 1, 2 Next
Atlantis
Guest
Tue Mar 21, 2017 9:09 am
Ciąg dalszy eksperymentów z antycznymi mikrokontrolerami. :)
Trafiłem na taką oto dziwną sytuację (zawartość pliku .mem wklejona na
końcu wiadomości). Z jakiegoś powodu kilkanaście bajtów na początku
pamięci zostało wyłączonych z użytku przez kompilator sdcc. Ktoś ma
pomysł dlaczego tak się stało i co mogę z tym zrobić?
Może mam coś źle ustawione w makefile albo powinienem deklarować zmienne
w jakiś specyficzny sposób?
Druga sprawa: wykonałem kilka eksperymentów i z tego co widzę
umieszczenie w kodzie tablicy znaków zdefiniowanej jako const char[] nie
powoduje zwiększenia zużycia RAM-u. Mam rozumieć, że 8051/sdcc potrafi
odwoływać się do danych umieszczonych w pamięci programu bezpośrednio,
bez potrzeby kombinowania z jakimś odpowiednikiem AVR-owskiego pgmspace.h?
Internal RAM layout:
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00:|0|0|0|0|0|0|0|0|a|a|a|a|Q| | | |
0x10:| | | | | | | | | | | | | | | | |
0x20:|B|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|
0x30:|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|
0x40:|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|S|
0x50:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x60:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x70:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x80:| | | | | | | | | | | | | | | | |
0x90:| | | | | | | | | | | | | | | | |
0xa0:| | | | | | | | | | | | | | | | |
0xb0:| | | | | | | | | | | | | | | | |
0xc0:| | | | | | | | | | | | | | | | |
0xd0:| | | | | | | | | | | | | | | | |
0xe0:| | | | | | | | | | | | | | | | |
0xf0:| | | | | | | | | | | | | | | | |
0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData,
S:Stack, A:Absolute
Stack starts at: 0x4f (sp set to 0x4e) with 49 bytes available.
Other memory:
Name Start End Size Max
---------------- -------- -------- -------- --------
PAGED EXT. RAM 0 256
EXTERNAL RAM 0 1024
ROM/EPROM/FLASH 0x0000 0x0327 808 2048
MKi
Guest
Tue Mar 21, 2017 9:48 am
-- Wiadomość oryginalna (wysłana 21.03.2017 09:09) --
Quote:
Ciąg dalszy eksperymentów z antycznymi mikrokontrolerami. :)
Trafiłem na taką oto dziwną sytuację (zawartość pliku .mem wklejona na
końcu wiadomości). Z jakiegoś powodu kilkanaście bajtów na początku
pamięci zostało wyłączonych z użytku przez kompilator sdcc. Ktoś ma
pomysł dlaczego tak się stało i co mogę z tym zrobić?
Może mam coś źle ustawione w makefile albo powinienem deklarować zmienne
w jakiś specyficzny sposób?
Druga sprawa: wykonałem kilka eksperymentów i z tego co widzę
umieszczenie w kodzie tablicy znaków zdefiniowanej jako const char[] nie
powoduje zwiększenia zużycia RAM-u. Mam rozumieć, że 8051/sdcc potrafi
odwoływać się do danych umieszczonych w pamięci programu bezpośrednio,
bez potrzeby kombinowania z jakimś odpowiednikiem AVR-owskiego pgmspace.h?
Internal RAM layout:
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00:|0|0|0|0|0|0|0|0|a|a|a|a|Q| | | |
0x10:| | | | | | | | | | | | | | | | |
0x20:|B|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|
0x30:|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|
0x40:|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|S|
0x50:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x60:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x70:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x80:| | | | | | | | | | | | | | | | |
0x90:| | | | | | | | | | | | | | | | |
0xa0:| | | | | | | | | | | | | | | | |
0xb0:| | | | | | | | | | | | | | | | |
0xc0:| | | | | | | | | | | | | | | | |
0xd0:| | | | | | | | | | | | | | | | |
0xe0:| | | | | | | | | | | | | | | | |
0xf0:| | | | | | | | | | | | | | | | |
0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData,
S:Stack, A:Absolute
Stack starts at: 0x4f (sp set to 0x4e) with 49 bytes available.
Other memory:
Name Start End Size Max
---------------- -------- -------- -------- --------
PAGED EXT. RAM 0 256
EXTERNAL RAM 0 1024
ROM/EPROM/FLASH 0x0000 0x0327 808 2048
Pamięć:
Zapewne obszar zmiennych jednego modułu (jednego pliku .c)
musi być ciągły, a obszar "bbbb" jest za duży, aby się
zmieścił od 0x0D do 0x1F. Używasz też zmiennych bitowych,
które zaczynają się zawsze od 0x20.
Rozwiązanie: rozdziel zmienne modułu "bbbb" na dwa moduły.
Dane we FLASH: Jak najbardziej, całe kombinowanie
to dyrektywa const lub code.
Pozdrowienia,
MKi
Miller Artur
Guest
Tue Mar 21, 2017 10:00 am
W dniu 2017-03-21 o 09:09, Atlantis pisze:
Quote:
Ciąg dalszy eksperymentów z antycznymi mikrokontrolerami.
to jest antyczny? spróbuj 8049, 8085, a dla hardcorów - 8080.
Quote:
Trafiłem na taką oto dziwną sytuację (zawartość pliku .mem wklejona na
końcu wiadomości). Z jakiegoś powodu kilkanaście bajtów na początku
pamięci zostało wyłączonych z użytku przez kompilator sdcc. Ktoś ma
pomysł dlaczego tak się stało i co mogę z tym zrobić?
Zapoznać się z mapą pamięci?
Quote:
Druga sprawa: wykonałem kilka eksperymentów i z tego co widzę
umieszczenie w kodzie tablicy znaków zdefiniowanej jako const char[] nie
powoduje zwiększenia zużycia RAM-u. Mam rozumieć, że 8051/sdcc potrafi
odwoływać się do danych umieszczonych w pamięci programu bezpośrednio,
bez potrzeby kombinowania z jakimś odpowiednikiem AVR-owskiego pgmspace.h?
a w asemblera bym może zajrzał... podpowiedź: "architektura Harvard"
oraz "instrukcja MOVC"
a.
J.F.
Guest
Tue Mar 21, 2017 11:16 am
Użytkownik "Atlantis" napisał w wiadomości grup
dyskusyjnych:58d0dfa8$0$651$65785112@news.neostrada.pl...
Quote:
Trafiłem na taką oto dziwną sytuację (zawartość pliku .mem wklejona
na
końcu wiadomości). Z jakiegoś powodu kilkanaście bajtów na początku
pamięci zostało wyłączonych z użytku przez kompilator sdcc. Ktoś ma
pomysł dlaczego tak się stało i co mogę z tym zrobić?
Poczatek RAM to sa rejestry R0-R7. 4 banki takich rejestrow sa, ktore
mozna sobie przelaczac ... albo uzywac jako normalna pamiec, jesli nie
przelaczasz.
Kompilator z tego co widac ominal tylko jeden bank.
Quote:
Druga sprawa: wykonałem kilka eksperymentów i z tego co widzę
umieszczenie w kodzie tablicy znaków zdefiniowanej jako const char[]
nie
powoduje zwiększenia zużycia RAM-u. Mam rozumieć, że 8051/sdcc
potrafi
odwoływać się do danych umieszczonych w pamięci programu
bezpośrednio,
bez potrzeby kombinowania z jakimś odpowiednikiem AVR-owskiego
pgmspace.h?
8051 potrafi, ale wymaga takiego samego kombinowania.
Widac w tym komplitatorze pisze sie const char :-)
uC musi te dane odczytywac innym rozkazem (MOVC), wiec kompilator musi
wiedziec, ze to jest inna pamiec, i ze trzeba uzyc innego rozkazu.
Nie mozesz sobie napisac funkcji np
void funkcja(char * ptr) {...}
i przekazywac jej adresy do roznych obszarow
(Wyjatkiem byl tu Keil, ale to bylo obciazone gorsza wydajnoscia).
Atlantisie - przeczytaj jakas ksiazke o 8051, albo go wyrzuc, szkoda
zycia.
J.
MKi
Guest
Tue Mar 21, 2017 11:36 am
-- Wiadomość oryginalna (wysłana 21.03.2017 11:16) --
Quote:
Nie mozesz sobie napisac funkcji np
void funkcja(char * ptr) {...}
i przekazywac jej adresy do roznych obszarow
(Wyjatkiem byl tu Keil, ale to bylo obciazone gorsza wydajnoscia).
Ale można!
SDCC tworzy trzybajtowy wskaźnik, w pierwszym bajcie
jest informacja, na jaki obszar pamięci wskazują pozostałe dwa bajty.
Chyba tak samo, jak w Keil.
Oczywiście wydajniej będzie kwalifikować jawnie wskaźnik.
Pozdrowienia,
MKi
Marek
Guest
Tue Mar 21, 2017 11:52 am
On Tue, 21 Mar 2017 09:09:11 +0100, Atlantis <marekw1986NOSPAM@wp.pl>
wrote:
Quote:
Druga sprawa: wykonałem kilka eksperymentów i z tego co widzę
umieszczenie w kodzie tablicy znaków zdefiniowanej jako const
char[] nie
powoduje zwiększenia zużycia RAM-u. Mam rozumieć, że 8051/sdcc
potrafi
odwoływać się do danych umieszczonych w pamięci programu
bezpośrednio,
bez potrzeby kombinowania z jakimś odpowiednikiem AVR-owskiego
pgmspace.h?
Tak, wystarczy deklaracja const. Dodatkowo sdcc nie odróżnia
wskaźników do flash/ram (z pkt. widzenia programisty oczywiście).
Można je zamiennie stosować np. jako argumenty standardowych funkcji
z libc. Niestety na tym chyba się kończą zalety sdcc...
--
Marek
niepeĹnosprawny intelekt
Guest
Tue Mar 21, 2017 5:20 pm
no pięknie rodzi się na grupie nowa nauka,
co za maniane zrobi/ł kompilator...
Atlantis
Guest
Tue Mar 21, 2017 8:28 pm
W dniu 2017-03-21 o 11:52, Marek pisze:
Quote:
Tak, wystarczy deklaracja const. Dodatkowo sdcc nie odróżnia wskaźników
do flash/ram (z pkt. widzenia programisty oczywiście). Można je
zamiennie stosować np. jako argumenty standardowych funkcji z libc.
Niestety na tym chyba się kończą zalety sdcc...
Ok, wielkie dzięki.
Jeszcze jedno pytanie. Ktoś z was ma pomysł jak debugować
niedziałającego UART-a w at89c2051?
Software'owy UART działa ok. Hardware'owego nie mogę odpalić, chociaż
mogłoby się to wydawać banalnym zadaniem.
Procedura inicjująca wygląda następująco:
void uart_init (void) {
TMOD &= ~0xF0;
TMOD |= 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = 0xFD;
ES = 1;
TR1 = 1;
}
a w pętli głównej umieściłem następujący zestaw instrukcji:
if (RI) {
RI = 0;
c = SBUF;
SBUF = c;
}
Niestety, znaki wysyłane na przejściówkę USB-UART nie wracają do
komputera. Analizator stanów logicznych też nie widzi żadnego ruchu na
linii TX MCU.
Kierunki linii chyba też są ustawione właściwie we wstępnej konfiguracji
(P3 = 0x01;).
Może coś jeszcze przeoczyłem?
Alojzy
Guest
Wed Mar 22, 2017 6:39 pm
Użytkownik "Atlantis" napisał:
Quote:
Kierunki linii chyba też są ustawione właściwie we wstępnej konfiguracji
(P3 = 0x01;).
To nie kierunki, tylko ustawiłeś 0 do wszystkich linii portu P3, oprócz RXD
to jak ma działać?
Alojzy
Atlantis
Guest
Wed Mar 22, 2017 9:55 pm
W dniu 2017-03-22 o 18:39, Alojzy pisze:
Quote:
To nie kierunki, tylko ustawiłeś 0 do wszystkich linii portu P3, oprócz
RXD to jak ma działać?
Chwilę, a to przypadkiem nie jest tak. że jeśli ustawię 0, to tam jest
dosłownie 0 - pin jest na poziomie masy i nawet jeśli podłączyłbym
zewnętrznego pull-upa, to i tak po stronie pinu będzie on na potencjale
masy i próba odczytania czegokolwiek da zawsze 0.
Natomiast jeśli wpiszę 1, to włącza się słaby, wewnętrzny pull-up. Przy
odczycie normalnie będzie zwracało jedynkę - chyba, że coś z zewnątrz
zewrze pin z masą - wtedy będzie zero.
Dokładnie tak, jak w przypadku PCF8574.
Czyżbym nie miał racji?
J.F.
Guest
Thu Mar 23, 2017 12:38 am
Dnia Wed, 22 Mar 2017 21:55:45 +0100, Atlantis napisał(a):
Quote:
W dniu 2017-03-22 o 18:39, Alojzy pisze:
To nie kierunki, tylko ustawiłeś 0 do wszystkich linii portu P3, oprócz
RXD to jak ma działać?
Chwilę, a to przypadkiem nie jest tak. że jeśli ustawię 0, to tam jest
dosłownie 0 - pin jest na poziomie masy i nawet jeśli podłączyłbym
zewnętrznego pull-upa, to i tak po stronie pinu będzie on na potencjale
masy i próba odczytania czegokolwiek da zawsze 0.
Natomiast jeśli wpiszę 1, to włącza się słaby, wewnętrzny pull-up. Przy
odczycie normalnie będzie zwracało jedynkę - chyba, że coś z zewnątrz
zewrze pin z masą - wtedy będzie zero.
Dokładnie tak, jak w przypadku PCF8574.
Czyżbym nie miał racji?
Jesli chodzi o piny dzielone, to nie. Tzn opis powyzszy jest
prawdziwy, ale taka np TxD/P3.1:
Jesli do P3.1 wpiszesz 0, to pin bedzie zawsze w stanie 0.
Jesli wpiszesz 1, to UART bedzie sterowal pinem.
Gdzies tam w srodku jest bramka OR, laczaca rejestr portu i funkcje
specjalna.
J.
J.F.
Guest
Thu Mar 23, 2017 6:14 am
Dnia Thu, 23 Mar 2017 00:38:44 +0100, J.F. napisał(a):
Quote:
Jesli chodzi o piny dzielone, to nie. Tzn opis powyzszy jest
prawdziwy, ale taka np TxD/P3.1:
Jesli do P3.1 wpiszesz 0, to pin bedzie zawsze w stanie 0.
Jesli wpiszesz 1, to UART bedzie sterowal pinem.
Gdzies tam w srodku jest bramka OR, laczaca rejestr portu i funkcje
specjalna.
No i zle napisalem, bo bramka jest AND.
A raczej NAND - zobacz opis Port 3
http://world4tronix.blogspot.com/2013/08/io-ports-microcontroller-8051.html
Tak czy inaczej - musisz port ustawic na 1, aby "alternatywna funkcja"
mogla pinem sterowac.
J.
Adam Wysocki
Guest
Fri Mar 24, 2017 9:02 am
Atlantis <marekw1986NOSPAM@wp.pl> wrote:
Quote:
Druga sprawa: wykonałem kilka eksperymentów i z tego co widzę
umieszczenie w kodzie tablicy znaków zdefiniowanej jako const char[] nie
powoduje zwiększenia zużycia RAM-u. Mam rozumieć, że 8051/sdcc potrafi
odwoływać się do danych umieszczonych w pamięci programu bezpośrednio,
bez potrzeby kombinowania z jakimś odpowiednikiem AVR-owskiego pgmspace.h?
Bardzo bym się zdziwił. To, co jest w const char[], musi być w RAM-ie nie
bez powodu - te adresy muszą być dostępne dla funkcji, które operują na
RAM-ie. Przykładowo jak wywołasz memcpy(), to ona zakłada, że dostała
adres do RAM-u i używa instrukcji czytających z RAM-u.
8051, tak jak AVR, jest architekturą Harvardzką, co znaczy, że pamięć
programu i operacyjna to dwie osobne pamięci. To, że te architektury mają
instrukcje umożliwiające czytanie pamięci programu, to tzw. zmodyfikowana
architektura Harvardzka.
Dla AVR to odpowiednio instrukcje LD i LPM, dla 8051 - MOV i MOVC. Funkcje
operujące na pamięci muszą wiedzieć, z których instrukcji korzystać dla
danego adresu.
Co do reszty - nie pomogę, dla 8051 pisałem coś ostatnio 15 lat temu :(
--
http://www.chmurka.net/
Adam Wysocki
Guest
Fri Mar 24, 2017 9:04 am
MKi <emkai@to-nalezy-wywalic.op.pl> wrote:
Quote:
Ale można!
SDCC tworzy trzybajtowy wskaźnik, w pierwszym bajcie
jest informacja, na jaki obszar pamięci wskazują pozostałe dwa bajty.
Chyba tak samo, jak w Keil.
Oczywiście wydajniej będzie kwalifikować jawnie wskaźnik.
Czyli "bardzo bym się zdziwił" zmieniam na "bardzo się zdziwiłem" ;)
--
http://www.chmurka.net/
Adam Wysocki
Guest
Fri Mar 24, 2017 9:05 am
Adam Wysocki <gof@somewhere.invalid> wrote:
Quote:
Bardzo bym się zdziwił. To, co jest w const char[], musi być w RAM-ie nie
bez powodu
Doczytałem resztę wątku, odszczekuję

Nie wiedziałem że SDCC robi takie
sztuczki.
--
http://www.chmurka.net/
Goto page 1, 2 Next