RTV forum PL | NewsGroups PL

Wyjaśnienie nieaktywnej pamięci na AT89C2051 oraz zarządzanie danymi z SDCC

Pamięć at89c2051

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Wyjaśnienie nieaktywnej pamięci na AT89C2051 oraz zarządzanie danymi z SDCC

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. Smile

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. Smile
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ę Smile Nie wiedziałem że SDCC robi takie
sztuczki.

--
http://www.chmurka.net/

Goto page 1, 2  Next

elektroda NewsGroups Forum Index - Elektronika Polska - Wyjaśnienie nieaktywnej pamięci na AT89C2051 oraz zarządzanie danymi z SDCC

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map