[OT] Zarządzanie konfiguracją modułów ko

Nie. plik lokalny dla projektu nadpisuje parametry domyślne.

Reply to
Sebastian Biały
Loading thread data ...

Kopię? Od tego są systemy kontroli wersji. Robimy brancha nowego i dostosowujemy. Jak coś się zmieni w głównej gałęzi (np straszny bug wykryty) to mergujemy samą zmianę. W gicie robi się to pięknie...

Takie problemy występują podczas rozwoju każdego oprogramowania, warto poczytać o schematach/rozwiązaniach przetestowanych w takim środowisku.

formatting link
Marek

Reply to
marek

Dnia 06-05-2012 o 17:21:11 mk <reverse_lp.pw@myzskm> napisał(a):

Skłaniam się ku pierwszej opcji: obligatoryjne określenie, nawet jeśli zwykle będzie to przypisanie wartości domyślnej. Chcę jakoś sobie to określanie usprawnić semi-automatyzując zadanie. Na razie mam tylko autowykrywanie przez próbę kompilacji gdzie parametr nie jest zdefiniowany. Chciałbym ułatwić sobie dodawanie tego parametru do plików konfiguracyjnych, oraz mieć wykrywanie ustawienia parametrów, które stały się "obsolete".

ae

Reply to
Andrzej Ekiert

Używając #undef???

IMO zdecydowanie lepsze jest jednak włączenie najpierw pliku z konfiguracją użytkownika, a potem nagłówek z konfiguracją domyślną -- to zresztą powszechna praktyka. Plik nagłówkowy "defaultconfiguration.h" nie definiuje parametrów już zdefiniowanych (#ifndef), a jedynie te które jeszcze nie zostały zdefiniowane nadając im wartości domyślne (+ ewentualnie jakiś komunikat przy pomocy #warning), obliczając je (np. na podstawie parametrów podanych przez użytkownika) lub walnąć błędem (#error) jeśli parametr ma być obligatoryjne określony przez użytkownika.

pzdr mk

Reply to
mk

Póki rejestry UART są rozmieszczone identycznie względem bazowego, to w zwykłym C napiszesz jedną obsługę do wszystkich UARTów bez żadnych define'ów.

Chętnie zobaczę.

Reply to
Zbych

Uzywając def.

Np. tak:

default-config: #define UART_STOP_BITS 1

project-config: #include "default.h", #define UART_STOP_BITS 2

Zdecydowana lepszośc tutaj dyskusyjna. Oba rozwiązania działają.

W drugą stronę działa to tak samo (nie)skutecznie bez #ifndef, kwestia implementacji.

IMO to nie konfiguracja powinna szukać bledów w #define i wyliczać pośrednie parametry tylko implementacja. Więc detekcje źle ustawionych parametrów robię w pliku c. To dlatego że to w pliku c wiadomo jaka konfiguracja jest nielegalna, np. uart avr ie obsługuje 2 bitów stopu. Gdyby te zależności miał wyliczać globalny plik default-config.h to wiedza o uart avr wyciekła by z implementacji specyficznej dla hardware do globalnej przestrzeni gdzie ją ciężko utrzymać.

W moim rozwiązaniu zależności są detektowane i obliczane w c drivera bo nie ma innej możliwości. I dzieki temu plik default-config jest czysty o specyficznej wiedzy o hardware. Nie zawsze, ale zazwyczaj. Innymi słowy wszystko co dotyczy avr znajduje się w katalogu /avr/ i nie przecieka do inych plików.

Przy czym żeby było jasno - oba podejścia są tak samo mizerne.

Reply to
Sebastian Biały

Redefiniowanie makra nową wartością jest nielegalne!!!

Jak gdzie (patrz wyżej). Można by odwołać jak wspomniałem z użyciem #undef, ale użycie #undef jest niezgodne np. z MISRA-C i w ogóle niepotrzebnie zaciemnia plik konfiguracji użytkownika.

Niezgodne ze standardem.

To zależy i to już trochę inny temat... część rzeczy można i należy sygnalizować już na wczesnym etapie rozpoznania konfiguracji użytkownika np. zgodność wersji modułu bibliotecznego i jej użytkownika, czy wiele innych parametrów o globalnym charakterze. Rozmowa na temat czy "default.h" należy czy nie należy do implementacji jest również czysto akademicka, tak jak i gdzie najlepiej określać parametry default.

pzdr mk

Reply to
mk

Masz rację, jak zwykle pisze skrótami i nie wszystko podaje. Oczywiscie że jest #undef ale tylko dlatego że nie da się zrobić wprost #define ponownie (w gcc da się). Samo undef jest wyłacznie wytrychem a nie sednem metody. Sendem metody jest ponowne zdefiniowanie symbolu nadpisując default.

Jak napisałem - dla mnie nie ma znaczenia którą metodą inkludowania wybierzesz - obydwie sa mizerne i sprwadzają się do tej samej sieczki w define.

Nie mam targetu na misra-c. Więc ich zalecenia nie są dla mnie kluczowe. Czy zaciemnia - to już inna sprawa. W odwrotnej konfiguracji zaciemnia #ifdef. Tak czy inaczej - to nie wygląda dobrze.

Prawde mowiąc korzystam znacznie częściej ze statycznego polimorfizmu. #define to odprysk w kilku miejscach.

Mam taki nieskończony projekcik (który strasznie zaniedbałem, ale obiecuje poprawę) na SF, możesz sobie zerknąć co mam na myśli:

formatting link

W moim przypadku nie sposób w momencie inkludowania default wykryć czy dopuszczalne jest mieć uart o 2 bitach stopu. Przy czym "nie sposób" w sensie, że jakikolwiek sposób powoduje wyciek wiedzy o hardware do miejsca o innym poziomie abstrakcji. Im niej zależności tym lepiej dla projektu.

Z tej akademickiej dyskusji wynikają dobre praktyki. Dla mnie on nie jest akademicka, bo dzieki takiemu podejsciu nie mam burdelu w kodzie.

Reply to
Sebastian Biały

W dniu 2012-05-06 17:41, Andrzej Ekiert pisze:

Nie rozumiem nadal dlaczego nie posługiwać się wartością domyślną konfiguracji zdefiniowaną gdzieś w module bibliotecznym...

#ifndef ALPHA #error ALPHA parameter must be defined in your configuration file. #endif

lub

#ifndef ALPHA #warning Using defalut value X of ALPHA parameter. Specify an explict definition of ALPHA parameter in your configuration file to suppress this warning. #define ALPHA X #endif

lub po cichu

#ifndef ALPHA #define ALPHA X #endif

#ifdef ALPHA #warning ALPHA parameter is obsolete configuration value. Use BRAVO instead. #endif

Jeśli wzbraniasz się przed konceptem konfiguracji domyślnej wtedy po prostu pozostaje jakaś automatyczna modyfikacja plików wielu projektów

-- zwykle z wykorzystaniem języków skryptowych, albo zaawansowanego edytora.

W sumie można sobie wyobrazić jakiś system zarządzania konfiguracjami np. w postaci jakiejś bazy danych czy coś... Nie nie spotkałem się z czymś takim.

pzdr mk

Reply to
mk

Dnia 06-05-2012 o 22:25:15 mk <reverse_lp.pw@myzskm> napisał(a):

To w zasadzie mam teraz, tyle że warning lub błąd wynikający z niezdefiniowania ALPHA generuje się samoczynnie w miejscu jego użycia (bezwzględnie tego pilnuję). Nie trzeba więc nawet takiego #ifndefa pisać.

Można. Ale wciąż wymaga ręcznego dopisania #define ALPHA wszędzie, jeśli się nie chce tych warningów. A to mnie właśnie boli, ze względu na bezproduktywną pracochłonność.

Ryzykowne - otrzymujący mój kod mogą nie zauważyć nowych opcji, które np. mogą okrajać dotychczasową funkcjonalność. Sam mogę zapomnieć ustawić w jednym z projektów.

Można, ale wymaga trzymania całej historii. Średnio mi się podoba taki śmietniczek.

No właśnie sobie to wyobraziłem. Chyba będę pisał, bo niczego sensownego nie znalazłem. Jeśli mi się uda skończyć, to opublikuję pod GPL.

ae

Reply to
Andrzej Ekiert

GCC jest tu tolerancyjny, ale i tak daje warningna.

Takie uroki tworzenia kodu uniwersalnego. Sieczki programowania generycznego C++ często wcale nie wyglądają lepiej :-)

Ale to z plikiem konfiguracji użytkownika użytkownik będzie w pierwszej kolejności pracować. Nadawanie konfiguracji domyślnej to już bebechy...

Nie ma co sobie obrzydzać, tak wygląda język C :-)

Inny język, inna bajka... Świecą mi się oczy jak widzę takie rzeczy, choć C++ daleki jest w programowaniu generycznym od tego co można sobie wymarzyć. W wolnej chwili nie omieszkam lepiej się przyjrzeć projektowi.

I dla odmiany (też jeśli chodzi o rozwiązania generyczne i też jeśli chodzi o zarządców pamięci): mam ostatnio do czynienia z biblioteczką lwIP (stos TCP/IP). Mam tu w szczególności na myśli pule pamięci z tego projektu (pliki memp.c, memp_std.h).

Wygląda to mniej więcej tak:

const u16_t memp_sizes[MEMP_MAX] = { #define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), #include "lwip/memp_std.h" };

i na końcu pliku memp_std.h odwołujemy makro LWIP_MEMPOOL. Plik memp_std.h tworzy ciało listy inicjalizacyjnej tablicy memp_sizes.

następnie znowu: static const u16_t memp_num[MEMP_MAX] = { #define LWIP_MEMPOOL(name,num,size,desc) (num), #include "lwip/memp_std.h" };

itd...

W ten sposób dzięki podmienianiu definicji LWIP_MEMPOOL obskoczono wytwarzania wszystkich struktur danych niezbędnych do pracy pól pamięci :-) Grrrrrrrrrrrrrrr... No i teraz próbuj to człowieku debugować... Aż się prosi o szablony i trejty (ale to nie C++).

Ale w boost też tą technikę (redefiniuj makro i włącz nagłówek) się stosuje... Paskustwo!

Oczywiście, że taki warunek jest związany ściśle z implementacją hardware, więc warunek ten powinien być możliwie blisko tyłka drajwera tego modułu.

pzdr mk

Reply to
mk

Bo nie było kiedyś m.i. variadic templates.

M.i. dlatego zacząłem programowanie magisterki od kompilacji g++ 4.7 - mam lamby, mam variadic, mam inicjalizację przez {}, mam enum class, mam constexpr etc.

Reply to
Michoo

ecosconfig czyli konfigurator eCos'a jest takim narzedziem.

To nie bedzie bardzo skomplikowane. Trzeba tylko"

  1. "Spaczkowac" projekt - wydzelic moduly, ktore maja byc opcjonalnymi komponetami i dodac opis w jezyku CDL w katalogu cdl danej paczki a. Jesli projekt nie bzedzi linkowany z zewnetrznym modulem, w pliku cdl dodac opcje do budowania na wzor opcji CYGBLD_BUILD_REDBOOT_BIN z dowolnego Hal'a.
  2. Stworzyc "targety" - opis paczek skladajacych sie na konkretny modul sprzetowy.
  3. Stworzyc przynajmniej jeden "template" - dodaje wspolne paczki dla wielu targetow - chyba opcjonalnie.
  4. Powyzsze aktywnosc wykonac w jezyku CDL ->

formatting link
Wszystko umiescic w katalogu packages zgodznie z drzewem eCos'a

  1. Stworzyc plik ecos.db i dodac do niego wszystkie paczki oraz targety.
  2. $ ecosconfig new TARGET TEMPLATE $ ecosconfig tree

i juz powinismy dostac oczekiwana konfiguracje, makefile, a $ make zbuduje wszystko.

Reply to
Nijak

Dnia 07-05-2012 o 15:52:59 Nijak snipped-for-privacy@brak.pl napisał(a):

Kiedyś przenosiłem RedBoota na swoją płytkę i wtedy sobie dodałem definicję "targetu" do plików obrabianych przez ecosconfig. Musiałbym się tym trochę więcej pobawić, ale może faktycznie czas zaakceptować fakt, że lepiej czegoś podobnego sam nie napiszę i przeczytać tę przydługą dokumentację. Narzędzie wydaje się umieć spełnić moje wymagania - oraz 100 rzeczy, których nie wymagałem ;-)

Dzięki wszystkim za tę sugestię.

Pozdrowienia, ae

Reply to
Andrzej Ekiert

czasami w przypadku koniecznosci zachowania wstecznej kompatybilnosci biblioteki stosuje sie w c++ namespace-inlining (a w c wersjonowanie symboli na poziomie skryptu gnu/linkera).

na zalaczonym przykladzie masz w bibliotece obslugujacej costam wersje v1, ktora byla na poczatku wszechswiata :) potem programista wpadl na pomysl by rozwiazanie ulepszyc i dodal wersje v2, ale, ze lubil uzytkownikow, to nie chial ich zmuszac do poprawiania w starych projekatach wszystkich wywolan api i za pomoca prostego #define USE_LEGACY w aktualnej wersji biblioteki udostepnia stary interfejs/implementacje. autor biblioteki wewnetrznie (w lib.cpp) juz sobie rozwizuje problem jak stare api przempowac na aktualna implementacje, a uzytkownicy sa szczesliwi.

Reply to
Paweł
[...]

Z jakiej choinki się urwałeś, że na grupie dyskusyjnej załączniki wpychasz?

[...]
Reply to
RoMan Mandziejewicz

zalacznik tekstowy jest gorszy od wklejenia przykladu do tresci wiadomosci? przeciez to nie megabajtowe pliki, zeby je slac na bin.*, a tak wszystko widac od reki i mozna latwo sobie zapisac przyklad na dysku.

Reply to
Paweł

Tak, bo go część serwerów wytnie. A inna część serwerów wytnie razem z wiadomością.

[...]
Reply to
RoMan Mandziejewicz

Dnia 08-05-2012 o 08:50:07 RoMan Mandziejewicz snipped-for-privacy@pik-net.pl.invalid> napisał(a):

Eee tam marudzisz, gazeta niczego nie wycieła i widać wszystkie załączniki, a ważą raptem mniej niż kilo.

Reply to
janusz_kk1

In the darkest hour on Tue, 08 May 2012 15:13:27 +0200, janusz_kk1 <janusz snipped-for-privacy@o2.pl screamed:

Gazeta nie, ale inne tak. Przyjmij do wiadomości, że załączników się nie wysyła.

Reply to
Artur M. Piwko

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.