AVR g++ - Wysokopoziomowe odwołanie do pinów

2

No ok, ale równie dobrze pakujesz w C funkcje static inline i efekt jest ten sam.

EDIT: btw, w nagłówkach masz przeca makra _BV, PD0, PD1 itd. Ja wiem, że macros are evil. Ale jednak do pisania 0b00001 zmuszony nie byłeś ;)

1

Men, ale jak chcesz to przekazywać w formie wskaźników f-kcję (bo tak to zamierzasz podmieniać, nie?) to chyba cała Twoja zabawa w optymalizację to trochę krew w piach może być... Nie daję głowy, i mówię to na czuja (jutro to chętnie zmierzę ;)) ale imho trochę od tyłu się zabierasz za to...

1

Może zerknij tutaj to Ci wiele wyjaśni:
https://www.dropbox.com/s/52en505x65dj9fv/TemplateAVR.zip?dl=0

0

Zastanawiam się, jak proste i niewymagające szybkiej reakcji programy piszecie w ten sposób na AVR. Operacje na portach powinny być atomowe, a przynajmniej po pierwszym spojrzeniu na wywołanie operacji powinno być wiadomo co konkretnie się wykona. Rdzeń AVR ma rozkazy bezpośredniego zapisu bitów do I/O i pewnie te gotowe już makra kompilują się właśnie w ten sposób. Już nie raz przejechałem się na tym, że przyszło przerwanie zmieniające stan portu w chwili pomiędzy pobraniem stanu portu a zmianą bitu i zapisem w sekcji wywłaszczonej. Czy sprawdzaliście ile trwa takie wywołanie funkcji static z klasy? Czy to jest jakoś optymalizowane, czy pobierany jest wskaźnik na tablicę wskaźników na metody klasy a z niej dopiero właściwa metoda?

No chyba, że to nie są ATmegi, tylko jakieś inne, sporo szybsze układy z rdzeniem AVR i służą one jedynie do mrugania diodą?

2

W przypadku mojego kodu, który przytoczyłem w poprzednim poście, nie ma żadnych wywołań niczego. Jest tylko jedna instrukcja sbi/cbi, dokładnie tak jakby napisać to ręcznie/użyć makr.

Oczywiście wymaga to użycia kompilatora i technik programowania z ostatniego dziesięciolecia. W embedded wciąż nie jest to dla wszystkich oczywiste z jakiegoś powodu. Również w pracy się z tym spotykam, więc to chyba po prostu normalne.

0

<quote="1218978">O, ja właśnie coś takie napisałem/piszę. Ostatecznie kod wygląda np. tak:

Avr::Io::Gpio<0>::setDirection(Avr::Io::Direction::OUTPUT);
Avr::Io::Gpio<0>::setValue(true);
Avr::Timer::BusyDelayMs(1.0);
Avr::Io::Gpio<0>::setValue(false);

OK, nawet jeśli ten kod generuje pojedyncze instrukcje, to i tak chyba użyje się tego raz na samym dole, żeby przygotować jakiś HAL? Nie wyobrażam sobie, żeby w kodzie zostawały takie zależne od architektury konstrukcje. I w takim razie, czy warto tak kombinować a później używać i tak jakiegoś wrappera na to?

PS. Do tej pory znalazłem tylko kilka zastosowań C++ w embedded i dotyczyły głównie polimorfizmu gdy musiałem wykonywać podobne operacje na wielu rodzajach podłączonych czujników z różnymi interfejsami.

3

Przecież to jest konkretnie obsługa sprzętu dostępnego w mikrokontrolerze z rodziny megaAVR, to chyba oczywiste, że jest zależna od sprzętu. Nie pisałem jakiegoś uniwersalnego embedded-czegoś bo do niczego mi to nie było potrzebne. Gdyby było, to tak, to była by najniższa warstwa.

Oczywiście, że warto tak pisać. Kod z makrami i funkcjami rodem z C wygląda okropnie - jest krytycznie nieczytelny.

W pracy tak samo używamy C++ w dużych i małych projektach (i ma to kilka warstw, tak jak mówisz). Już od dawna tak pisze się embedded.

0

Do Łukasza: PortA::SetBits(PA3||PA5); też jest atomowe - w embeed jest popularna "Magic syntax" czy co? Jak ktoś nie używa PORTA |= 0xfa; to nie jest PRO? Ja jestem hobbystą, więc dlatego nie rozumiem takiego punktu widzenia, szczególnie po przeczytaniu "Clear Code".

W przypadku braku mocy na coś większego polecam DMA w xmedzie - łyka wszystko.

1
Endrju napisał(a)

Oczywiście, że warto tak pisać. Kod z makrami i funkcjami rodem z C wygląda okropnie - jest krytycznie nieczytelny.

Myślę, że kod może wyglądać źle nie zależnie od używanego języka i C++ nie gwarantuje, że kod będzie wyglądał dobrze. W drugą stronę programy napisane w języku C mogą być bardzo dobrze i czytelnie napisane. Najgorzej jest, kiedy ktoś, kto zna C++ zaczyna pisać program w C, w stylu C++, i odwrotnie.

Czy naprawdę uważacie, że to:

 AVR::IO::Port_A0.clear();

jest lepsze, od tego:

 gpio_clr_bit(PORTA, 0);

Kto będzie teraz bardziej pro?

Należy się zastanowić też ile czasu potrzebujecie na przygotowanie obsługi peryferiów w stylu C++, jeśli ktoś wcześniej takiej obsługi nie implementował? A co w przypadku przerwań? Ciekaw jestem propozycji obsługi USART w AVR z wykorzystaniem przerwań, napisanej w języku C++.

Nie twierdzę, że C++ w embedded nie można używać, ale proponuję obiektywne spojrzeć na wady i zalety. W C++ można opakować każdy peryferial, stworzyć kilka warstw aplikacji, itd, aż pojawia się pytanie, na ile zbliża nas do różnego rodzaju rtos'ów.

0

Namespace nie słyszał? W c# microsoft nie potrzebnie układał wszystko w System.Text; System.Threading; Bo wszystko można zapisywać _system.task_get(HFDSDF &a, int *P, char f);
Dla kogoś KTO NIE MIAŁ STYCZNOŚCI Z TYM KODEM 1. będzie bardziej przyjazne. A Rtos na 16 mhz da się, ale trochę słabo. Nawet jakiegoś std nie ma na AVR, właśnie takie coś chciałem zrobić - zbiór fajnych metod ukrywających zawiłości mikroprocka. A czy gpio_set_bit(PORTA,0) jest lepsze od SBI 0x15,0? Zamiast STD::Cin piszesz scanf()? W asmie najlepiej pisz.

Teraz taki teścik: Co robi ten kod

public X c_of_fact(int a)
{
for(int k;k=<a,k++)
Console.WriteLine(X_Fact.G(a-1));
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1