Programowanie uC...

Sep 27, 2005 49 Replies

Sebastian Bialy napisał(a):

Dobrze, że napisałes to ostatnie zdanie, bo ono obnaża bezsens w/w trick'ów: Dla kilku bajtów zysku piszesz s*it, którego sam nie jesteś pewnien. Każdy poważny programista , jak spotka taki problem , to weżmie procesor z wieksza pamiecią zamiast odstawiać takie dziadostwo. Albo przynajmniej napisze ten kawałek w asemblerze i będzie o wiele bardziej czytelny.

Chyba nie ma sensu dalej udowadniać sobie, że da się w C napisać program z efektywnością asemblera. Chodzi o propagowanie dobrego stylu, zwłaszcza jak kogoś chcemy uczyć.

Miłosz K. napisał(a):

mógłbyś jakoś rozwinąć ten ,,s*it''? co Ci się nie podoba w takiej konstrukcji? jeśli ją przetestować, wrzucić w makro o nazwie bit_test_32() i zapomnieć, jak była napisana, nadal będzie jeżyć włos na głowie?

śmiem uważać, że makra z <avr/sfr_defs.h> są znacznie mniej czytelne od przykładu Sebastiana. mimo tego, ludzie z nich pośrednio korzystają i nie narzekają, że użyto sporej ilości kodu, żeby ułatwić pisane w C dla tych procesorów.

rozumiem, że jeśli zabraknie mi pamięci w ATtiny15, to mam czekać aż ATtiny25 będzie dostępny w okolicznym warzywniaku?

dziadostwem byłoby używanie wstawek asemblerowych, gdzie wystarczy czyste C. lepiej mieć mniej czytelny, ale za to przenośny kod, który w zależności od możliwości kompilatora i procesora, zostanie odpowiednio zoptymalizowany.

w.

Wojtek Kaniewski napisał(a):

Przecież sam sprawdziłeś pod nowszym kompilatorem , że to nie ma sensu .

Jak sie zabieram za projekt, to nie szacuję potrzebnych zasobów na styk. Rzadko ma to sens ekonomiczny. Jak dwa razy wiecej flashu kosztuje 1zł więcej , to szkoda mi czasu na wymyślanie tylko na swoje potrzeby takich wygibasów dla oszczednosci.

Przypominam, że ta dyskusja sie zaczeła od uczenia dobrego stylu programowania. Niech więc każdy sobie pisze taki kod jak mu wygodnie, tylko nazywajmy rzeczy po imieniu. Jak bez kilku zdań komentarza nie potrafie zrozumiec jakiejś zagmatwanej linijki kodu to dla mnie jest to s*it, chocby był super efektywny. Ja tez takie s*it'y w swoim kodzie walę ale się tym nie chwalę ani innych nie uczę.

Wiesz, o godzinie 00.30 po 13 godzinach pracy człowiek nie jest pewny jak się nazywa.

Zastanawia mie co jest w/g Ciebie tam nieczytelnego. Patrze sobie na ten kod i praktycznie nie ma tak żadnych niebezpieczeństw związanych z budową kompilatora czy budową procesora. Po prostu to powinno się sprawdzić w każdej architekturze 8-bit, a jedyne co może wymagać zmiany to [BIT/8] na [(sizeof(long)-(BIT/8))-1].

A po co udowadniać? Powyższy problem to REALNY problem z którym miałem do czynienia. Z taką wstawką mój program zmieścił się w przerwaniu, a bez niej nie. Oczywiście, mógłbym być "trendy" i wziąśc arma do dekodowania sygnału kwadraturowego zamiast AVR. W ogóle to mógłbym kupić gotowy dekoder.

Nie użyłem żadnych konstrukcji zabronionych/nietypowych/nieprzenośnych.

A kogo tu chcemy uczyć ? Napisałem odpowiedź na pytanie: "Czy ktoś mi może powiedzieć jakie funkcje z języka C są potrzebne do programowania uC". Przy okazji wyniknęła dysusja o tym czy stosować konstrukcje z wskaźnikami i po co. Pokazałem po co. I juz.

3.4.3

Miejmy nadzieje, bo takich bzdurnych i bezsensownych przykładów jest sporo. Przy okazji zerknę sobie na nowszą wersję, może generuje bardziej optymalny kod. W dodatku to ładowanie longa jest własnie bardzo złym pomysłem - po 3 bajty na instrukcje :/

W teori powinno się zoptymalizować (wystarczyło by zauważyć, że r24/26/27 nigdy nie były uzyte w tej sekcji).

PS. Inną sprawą która mnie dobija to generowanie przez gcc procedur in-line i jednocześnie wstawianie ich kopii gdzieś do pamięci bez odwołań do nich. Sporo pracy przed developerami jeszcze, chyba że to poprawili w 3.4.4 :)

Ja nic nie radziłem, jedynie pokazałem jakie konstrukcje można spotkać w C dla uC. Swoją drogą miałem w rękach (a znaleźć nie mogę teraz) helloworld.c które miało ponad 30kB kodu. Ale tak, był faktycznie napisane bardzo porządnie porządnie ...

Heh, smiem wątpić w Twój optymizm. Znam wielu DOBRYCH programistów w C którzy sobie nie radzą na uC ("wyrabianie się" w przerwaniach,optymalizacjia długości kodu, mało RAM, etc) Dobry programista w C zamiast stdio użyje iostream. Dobry programista uC w większośc projektów niczego nie użyje bo wie, że nie zmieści się.

Obawiam się, ze ludzie piszący na uC (w szczególności małe) własnie nie stosują się do teorii pięknego kodu a jedynie cykli, bajtów etc. Więc wątpie, żeby powstała ksiązka łącząca obydwa.

Jesli funkcja nie jest static to musi istniec jej wersja 'do wywolania'.

Miłosz K. napisał(a):

trochę pokrętne wyjaśnienie. pisałem, że różnica między kodem niezoptymalizowanym, a zoptymalizowanym przez programistę maleje, ale nadal jest. jeśli komuś brakuje 12 bajtów, to ten wynalazek będzie jak znalazł.

przed chwilą pisałeś o napotkaniu problemu, a o to ciężko w fazie planowania zasobów. zresztą to i tak niczego nie zmienia. nadal nie jestem w stanie zaplanować użycia ATtiny25/45/85 zamiast ATtiny15, gdybym potrzebował układu w SO-8, bo ich nie dostanę w promieniu kilkuset kilometrów. pisząc na styk i stosując optymalizację, mam szansę się zmieścić w tym co jest dostępne tu i teraz.

czyli to, czy czyjś kod jest ,,shitem'' czy nie, zależy od tego, czy go rozumiesz? a to ja przepraszam ;)

w.

Jesli nigdzie w kodzie nie istnieje odwołanie do jej adresu ? Można to było sobie darować.

Sebastian Bialy napisał(a):

na etapie kompilacji nie wiadomo, czy dany symbol nie będzie używany z innego modułu. było już wałkowane.

w.

Wojtek Kaniewski napisał(a):

Powinnyśmy chyba rozgraniczyć dwa przypadki:

  1. Hobbystyczny projekt, w którym ważna jest dostępność częsci w sklepie za rogiem, a technologia montazu nie pozwala na zejscie poniżej SO-XX. Robimy dla siebie, tak jak umiemy, i z tego co mamy. Nie przejmujemy się czytelnoscią kodu.

  1. Projekt dla kienta. Niezawodność kodu i łatwość jego rozwoju ( czyli również czytelnośc ) niekoniecznie przez tych samych ludzi którzy go napisali jest pierwszorzędna. Jak wiekszy procek się nie miesci na płytce , zamiast SO dajemy MLF itd.

Ja rozumiem. że nasza dyskusja dotyczy cały czas przypadku 1.

Jak coś piszesz dla siebie i sam będziesz sie potem domyślał o co ci chodziło, to twoja sprawa. Ale, jakbym miał zatrudniać programistę tylko na podstawie oceny jego kodu, to wybiorę tego czyj kod bedzie dla mnie lepiej zrozumiały i czytelny ( nawet kosztem efektywności ). Bo zasoby sprzętowe stanieją a brzydko napisany kod będzie tylko podrażał utrzymanie.

Po pierwsze nie s*it, tylko przemyslana pod katem optymalizacji konstrukcja. Po drugie czesto uzywana w swiecie embedded w tej czy innej postaci. Po to mozesz sobie podefiniowac rozne makra, zeby bledow przy liczeniu bitow nie robic.

A szef mu powie - niech se poszuka innej powaznej pracy i nie zawraca glowy, jak takich podstawowych konstrukcji nie uzywa. Poza tym co znaczy 'powazny'? Taki co pisze program przez rok czasu wygladajacy pieknie, ale ilosc bledow to e^x (x=ilosc 'bajerow' w programie)?

A po co? Toz to raptem linijka w C...

A nikt tego (chyba) tu nie udowadnial?

A o tym tez jeszcze nie bylo ;-)

Przemyslana, ale inny kompilator bedzie mial lepszy optymalizator i sie okaze ze niepotrzebnie sie narobiles :-)

Nie - taki ktory ktory bierze 100$ za godzine, do czego moze i my kiedys dojdziemy :-) A im prostszy program tym mniejsza szansa zrobienia bledu.

Ktos to bedzie musial poprawiac kiedys. Np ty sam ..

J.

Dziêkuje wszystkim za wyczerpuj±ce odpowiedzi na moje pytanie...

Tam na pocz±tku walnê³y mi siê linki :D mia³ byæ

formatting link

IMHO znacznie ³adniej:

#define BIT(x) (1 << (x))

if (a & BIT(19)) [...]

Pozdrawiam Piotr Wyderski

Tak powinno byæ. Tzn. linker powinien je pó¼niej pousuwaæ, ale generowane byæ musz±, bo ka¿da funkcja musi mieæ jednoznacznie okre¶lony adres.

A to nie pomaga?

__attribute__((__always_inline__)) inline void zrob_cos() {

}

Pozdrawiam Piotr Wyderski

Zaimplementuj w³asn± wersjê putc() (albo putchar, nie pamiêtam) i bêdziesz móg³ u¿ywaæ printf z jakimkolwiek urz±dzeniem wyj¶ciowym.

Pozdrawiam Piotr Wyderski

Co siê przetworzy do (nawiasy moje):

(1 + (2*3)) + 4 :-)))

Wyniki te¿.

Pozdrawiam Piotr Wyderski

Atrybut __always_inline__ równie¿ rozwi±zuje sprawê. Nie nale¿y nadu¿ywaæ makr.

Pozdrawiam Piotr Wyderski

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required