PIC-ów

Jak już kiedyś wspominałem, od jakiegoś czasu planuję się bliżej przyjrzeć procesorom STM32. Ostatnio jednak stwierdziłem, że zanim się za to zabiorę, rzucę okiem na PIC-i. Generalnie jakiś czas temu, przy okazji innego zamówienia kupiłem sobie jedną czy dwie sztuki PIC18F67J60 (MCU ze zintegrowanym kontrolerem Ethernetu, będącym odpowiednikiem ENC28J60). Jakiś programator też leży u mnie w szufladzie:

formatting link
Nie mam zamiaru poznawać tej rodziny MCU "od podszewki", a jedynie przyjrzeć się jej na tyle, żeby móc zrealizować jakiś projekt, rozumiejąc podobieństwa i różnice w stosunku do AVR-ów.

Przeczytałem już kilka tutoriali, rzuciłem okiem na notę katalogową i zaczynam rozumieć specyfikę tego układu. No cóż, wydajność w MIPS-ach mniejsza niż w AVR-ach a do tego są rzeczy, na które trzeba uważać (nie wszystkie piny mają sprzętowego pull-upa, nie wszystkie mają jednakową wydajność prądową. Są jednak i pewne zalety (możliwość pracy na niskim napięciu z maksymalną prędkością, wbudowany Ethernet).

Pewnie sklecę sobie płytkę na tym układzie pod kątem jakiegoś projektu.

Mam jednak kilka pytań na początek:

1) Jak to jest z tymi toolchainami? Jest kilka różnych kompilatorów, które mogą współpracować z MPLAB. Są między nimi jakieś istotne różnice, np. w składni języka C? A jeśli tak, to które rozwiązanie jest najbardziej "standardowe"? 2) Jest jakiś odpowiednik biblioteki pgmspace z AVR-ów, pozwalającej na umieszczanie danych w pamięci programu? Jakie polecenia odpowiadają np. PROGMEM albo PSTR("tekst")? 3) Ograniczenia dotyczące stopnia optymalizacji kodu w darmowych wersjach kompilatorów mają jakieś znaczenie w praktyce, czy nie trzeba się tym przejmować?
Reply to
Atlantis
Loading thread data ...

Jeśli zamierzasz wykorzystywać projekt ethernetowy, to microchip, z tego co pamiętam, ma zawsze jakiegoś aktualnego gotowca do ściągnięcia. Ten gotowiec to jest kompletny projekt pod jakiegoś mplaba czy innego MplabX (koplilator XC8 60dniowy jest do ściągniecia). Podejrzewam, że nic się nie zmieniło i wystarczy skompliować, sprawdzić czy działa, potem powyginać pod swoje potrzeby.

jp

Reply to
jacek pozniak

Co do optymalizacji, nie jest ona niezbędna, a automatyczna nawet nie wskazana. Pisząc program na PIC18 - "ręcznie" optymalizowałem fragmenty

- podglądając co wychodzi w asm. Wbrew pozorom nie było to takie trudne

- często zmiana wywołań, lub sposobu podawania argumentów f-cji już dawał przyrost rzędu kilkunastu bajtów (x ilość wystąpienia w programie) potrafiło dawać relatywnie duży zysk zarówno na objętości jak i czasach wykonania.

To co robił automatycznie kompilator przy średnim poziomie optzmalizacji

- powodowało że program w ogóle nie dział, a uruchomienie go było prawie niemożliwe - jak już działał to praktycznie losowe miejsca się nie wykonywały.

pozdr, MK.

W dniu 2014-06-18 18:35, Atlantis pisze:

Reply to
invalid unparseable

W dniu 2014-06-18 20:50, markofes markofes <AT> pisze:

O czym ty w ogóle piszesz? I do kogo?

JK

Reply to
JK

Masz do wyboru 3: C18 - "starszy" kompilator Microchipa dla środowiska MPLAB. Jest dedykowanym kompilatorem do rodziny mcu oznaczonych symbolami pic18f* (architektura PIC16). XC8 - najnowszy kompilator Microchipa, następca C18. SDCC - kompilator GNU mający wsparcie dla pic18f*, ale wygenerowany kod nie jest tak optymalny jak C18 i XC8 Jest jeszcze HiTec , który został przejęty przez Microchip i na nim powstał XC8.

pozwalającej na

C18 wymaga odpowiedniego prefixu przed deklaracją stałych (np. tablic), nie można mieszać wskaźników do rom z wskaźnikami do ram. Ten problem wyeliminowano dopiero w XC8. Sdcc podobnie jak XC8 nie "odróżnia" wskaźników rom/ram więc jest wygodniejszy, ale generuje większy kod niż XC8/C18

Z darmowych to pozostaje Ci tylko SDCC, ale generuje spuchnięty kod w porównaniu z XC8/C18. Może być nawet 2x większy. Używałem dużo sdcc, nie miałem problemów z stabilnością kodu natomiast przesiadłem się na C18 ze względu na lepszą optumalizację pod względem wielkości kodu.

Podsumowując: C18 stabilny kod, dobra optymalizacja pod względem wielkosci kodu wynikowego, w miarę szybka kompilacja, działa pod wine, ma pewne odstępstwa od standardów np: wskazniki ram/rom, domyślny brak zerowania zmiennych przy inicjalizacji, domyślne ograniczenia wielkosci zmiennych w ram do rozmiaru jednego banku tj. 255 bajtów (można to ominąć łącząc banki w skrypcie linkera). Wspiera chyba wszystkie 18f*

XC8 dobra optymalizacja pod wzgledem wielkości kodu, koszmarnie wolna kompilacja w porównaniu do super szybkiego sdcc.

SDCC prosty kompilator, bardzo szybki w kompilacji, w miarę trzymajacy się standardów, najnowsze mcu z seri 18f mogą nie być wspierane (brak plików nagłówkowych definiujacych rejestry, ale można zapożyczać je z C18 bo zachowano pewną kompatybilność w przestrzeni nazw rejestrów z C18.

Do prostych projektów nada się SDCC, ale trzeba zwrócić uwagę na wielkość kodu, bo jeśli w trakcie rozwoju softu może się okazać że kod nie zmieści się w flash.

Jeśli chcesz korzystać z eth, to raczej polecam C18/XC8 bo pod nie masz gotowe źródła stosu tcpip Microchipa.

Reply to
Marek

optzmalizacji

Jaki kompilator opisujesz?

Reply to
Marek

W dniu 2014-06-19 01:43, Marek pisze:

Postawiłem jednak na XC8. Pamiętasz może jaki to prefix? No i jak to się obsługuje? Po prostu korzystam z takiej tablicy tak, jakby to była zmienna? Mogę się odwoływać do niej przez jej nazwę albo wskaźnik, czy trzeba korzystać z jakiegoś odpowiednika pgm_read_byte()? Istnieje jakiś odpowiednik PSTR("tekst"), umożliwiający umieszczenie tekstu w pamięci programu podczas wywoływania funkcji, bez potrzeby wcześniejszego deklarowania osobnej tablicy?

Tak swoją drogą jedna rzecz mnie zastanawia. Eksperymentowałem trochę z MPLABX i z tego co widzę dodawania bibliotek jest tam inaczej zorganizowane niż w takim Atmel Studio. Gdy dodaję pliki biblioteki projektu, nie są one fizycznie kopiowane do katalogu projektu, ale jakoś linkowane. Mogę też utworzyć katalogi logiczne, które chyba nijak się mają do rzeczywistego układu katalogów.

W jaki sposób dodawać biblioteki do projektu, żeby nic się nie pomieszało (to znaczy, żeby program ni pogubił niczego)? Podczas pisania kodu która struktura katalogów ma znaczenie? Ta rzeczywista (na dysku) czy logiczna w oknie projektu?

Reply to
Atlantis

pgm_read_byte()?

O XC8 czytałem tylko pobieżnie co się zmieniło, uruchomiłem raz, zniechęciła mnie powolność kompilacji i jakieś udziwnienia przy kompilacji z kilku plików źródłowych. Kod wynikowy przykładowego projektu wielkościowo (porównując z C18} znacznie nie odbiegał od C18, więc uznałem że na razie zostane przy sprawdzonym narzędziu. O ike dobrze pamiętam z dok. do XC8.możesz odwolywac się poprzez tablica[index] lub przez wskaźnik. Wskažnik już nie musi być deklarowany "rom typ" jak było w C18 np. rom char *wsk ale po prostu char *wsk. Wsk w XC8 może wskazywać na tablice w flash (rom) lub w ram. W C18 wsk do rom mógł być tylko przypisywany do tablic w rom. Nie wiem co to PSTR("tekst"), ale użycie stałej łańcuchowej w kodzie np. printf("text") spowoduje, że "tekst" będzie w pamięci programu (rom), inaczej być nie może przecież.

Nie używam mplabx, używam vim + Makefile z własnymi regułami i skryptami linkera. Biblioteki buduje narzędziem do tworzenia bibliotek z pakietu narzędzi do C18.

Reply to
Marek

W dniu 2014-06-21 01:24, Marek pisze:

Nie w AVR-GCC. Tam taki zapis jest traktowany jak odwołanie do standardowej tablicy, której kopia jest tworzona w RAM-ie przy starcie programu. Aby operować na tablicy tylko i wyłącznie we flashu, trzeba skorzystać z następującego zapisu: printf(PSTR("tekst"))

Reply to
Atlantis

Nie bardzo rozumiem, taki domyślny model initializacji wyklucza użycie tablic o rozmiarach (sumarycznie lub jednostkowo) większych niż dostępny ram. W XC8 na pewno nie ma takiego modelu, stałe łańcuchowe można używać bez specjalnych kombinacji, zawsze będą odczytywane bezpośrednio z flash, pic ma wsparcie odczytu tablic z rom w instrukcjach cpu (TBLRD, RETLW itp.)

Reply to
Marek

Przypomniało mi się jeszcze o braku domyślnej promocji do int w C18 i być może w XC8, sprawdź aby nie było zaskoczenia, przykład:

unsigned char a,b; unsugned int c;

a=b=200; c=a+b;

w powyższym kodzie c nie będzie równe 400 a 144, bo promocja jest do największego operandu w wyrażeniu a+b czyli usigned char.

Reply to
Marek

W dniu 2014-06-21 12:21, Marek pisze:

Można, tylko wtedy trzeba taką tablicę zdefiniować jako PROGMEM, wówczas program będzie operował bezpośrednio na pamięci flash. W przeciwnym razie stosowana jest domyślna "strategia" operowanie na kopiach w pamięci RAM.

Dlatego właśnie pytałem o PSTR() - definiowanie osobnej tablicy z każdym napisem we flashu byłoby bardzo uciążliwe, więc to makro bardzo ułatwia sprawę.

Jednak rozumiem, że w PIC-ach po prostu nie jest potrzebne, bo ogólna filozofia jest nieco inna.

Reply to
Atlantis

Swoją drogą nie wiem czy nie lepiej byłoby na Twoim miejscu zainteresować się czymś 32 bitowym. Chcesz zamienić 8 bitowce, na których masz doświadczenie na inne 8 bitowce, trochę takie dreptanie w miejscu. Oczywiście 8bitowce się przydają do prostych projektów, szczególnie low power. Ale 32 bitowiec daje większą swobodę w programowaniu (dużo ram, dużo flash, "normalny" gcc), o "mocy" obliczeniowej nie wspominając. Możesz użyć np. pic32 (jest poręczna wersja w dip), źródła softu Microchipa (np. stos tcp, usb i inne) są uniwersalne dla wszystkich architektur pic, możesz je kompilować na pic18f a także na pic32. Oczywiście są też pic32 z eth, ješli Ci na tym zależy ale klasycznie z zew. enc28j60 po spi też działa.

Reply to
Marek

W dniu 2014-06-21 19:23, Marek pisze:

Generalnie taki jest plan. PIC-ów nie mam zamiaru uczyć się "dogłębnie", opanowując nazwę każdego bitu i rejestru. De faco do takiego poziomu zaawansowania nie doszedłem nawet w przypadku AVR-ów i często podpieram się notą katalogową. Po prostu chciałbym opanować je na tyle dobrze, żeby z niewielką pomocą móc zrobić na nich jakiś projekt. To zawsze nieco większa swoboda - mając pod ręką pasujący do moich wymagań model PIC-a zamiast AVR-a, mogę go wykorzystać. Zresztą widzę, że te rodziny aż tak diametralnie się nie różnią na poziomie kodu w C. Trochę inna obsługa przerwań, inny sposób manipulowania pinami (na pierwszy rzut oka łatwiejszy niż w ATmegach), inne nazwy rejestrów i nieco inne podejście do konfiguracji peryferiów. Chyba więcej czasu zejdzie mi na rozgryzaniu MPLABX niż samych mikrokontrolerów. ;)

No i chyba łatwiej będzie się przesiąść na procki 32bitowe, gdy będzie się miało dwa punkty odniesienia za miast jednego. Łatwiej wtedy zrozumieć, że coś jest tylko elementem specyfiki danej rodziny, a nie jedynym możliwym rozwiązaniem.

W pickit2 chyba tak czy inaczej się zaopatrzę, bo jak na razie mam jakiś "dziwny" programator wg niemieckiego projektu. A To narzędzie chyba warto mieć w warsztacie.

Chyba jednak zacznę od STM32. Mam już parę podręczników do tej rodziny, trochę o niej poczytałem w sieci. Oczywiście nie znaczy to, że w pewnym momencie nie rzucę też okiem na PIC32, na takiej samej zasadzie, jak teraz z ośmiobitowymi PIC-ami.

Generalnie mam takie podejście, by nie uzależniać się od jednej rodziny. Dlatego właśnie unikam uczenia się assemblera, który po jakimś czasie i tak się zdezaktualizuję.

Procka 32bitowego i tak pewnie niedługo będę potrzebował - planuję zrobić coś w rodzaju "routera" pośredniczącego w komunikacji pomiędzy lokalnym Ethernetem a kilkoma różnymi magistralami (radiowa, CAN, rs485). Chodzi o to, żeby program nie musiał czekać w pętli na odpowiedź z magistrali, tylko mógł przechodzić do obsługi kolejnych żądań. Trzeba będzie więc zorganizować tabelę, coś w rodzaju NAT, żeby urządzenie wiedziało gdzie odesłać odpowiedź. Może się okazać, że nawet duży ośmiobitowiec będzie za mały, żeby to wygodnie zaimplementować.

Z MCU 8it oczywiście nie mam zamiaru do końca rezygnować, chociażby z tej racji, że trochę ich leży w szufladzie i w mniejszych projektach będę mógł je spokojnie wykorzystać.

Swoją drogą jak wygląda kwestia wbudowanego Ethernetu w PIC32? To kompletny sterownik MAC+PHY, tak jak w rodzinie PIC18Fx7Jxx (generalnie szkoda, że nie istnieje jej odpowiednik wśród ośmiobitowych AVR-ów), czy jedynie sam MAC, wymagający zewnętrznego interfejsu PHY na kilkunastu liniach IO?

Reply to
Atlantis

(generalnie

kilkunastu

W PiC32 jest sam MAC i niestety musi być zewnętrzny PHY. Z tego powodu, że i tak jest potrzeby zewnętrzny komponent to ja używam pic32 bez mac i dodaje encj.

Reply to
Marek

W dniu 2014-06-21 13:55, Marek pisze:

Dzięki za informację. Rozumiem, że po wymuszeniu konwersji do int wszystko będzie działało tak, jak powinno?

unsigned char a,b; unsigned int c;

a=b=200; c= (unsigned int)a + (unsigned int)b;

Jeszcze jakieś inne "pułapki", o których powinienem pamiętać?

Reply to
Atlantis

W dniu 23.06.2014 08:07, Atlantis pisze:

Inicjalizację zmiennych globalnych (i statycznych) też trzeba sobie ręcznie włączyć.

Reply to
Zbych

W XC8 domyślnie nie jest włączone?

Reply to
Marek

Pisałem o C18, nie wiem jak to wygląda w XC8.

Reply to
Zbych

To była uwaga, że w C18 tak było. Wystarczy aby jeden operand był int.

Reply to
Marek

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.