Altera FPGA, Nios II i błąd u UART IRQ handler

Chciałbym ostrzec użytkowników Niosa w FPGA Altery przed błędem w obsłudze przerwania od odbiornika w ichnim UARTcie...

Błąd siedzi sobie tam w bibliotece i nie bardzo jest jak mu zapobiedz. Otóż obsługa przerwania budzi task czekający na zdarzenie od portu szeregowego ZANIM sprawdzony zostanie status błędu przystości lub status błędu ramki... W przypadku błędu taki znak jest usuwany z bufora kołowego i nigdzie nie ma informacji o żadnym błędzie (handler przerwania po prostu robi pusty "return;") ale task jest już obudzony wcześniejszym zawołaniem funkcji systemowej ALT_FLAG_POST...

Tu jest ich obsługa przerwania od odbiornika RX:

static void alt_avalon_uart_rxirq (alt_avalon_uart_dev* dev, alt_u32 status) { alt_u32 next;

/* * In a multi-threaded environment, set the read event flag to indicate * that there is data ready. This is only done if the circular buffer was * previously empty. */

if (dev->rx_end == dev->rx_start) { ALT_FLAG_POST (dev->events, ALT_UART_READ_RDY, OS_FLAG_SET); } /***** TUTAJ BUDZĄ TASK UŚPIONY NA FLADZE ALT_UART_READ_RDY ****/

/* Determine which slot to use next in the circular buffer */

next = (dev->rx_end + 1) & ALT_AVALON_UART_BUF_MSK;

/* Transfer data from the device to the circular buffer */

dev->rx_buf[dev->rx_end] = IORD_ALTERA_AVALON_UART_RXDATA(dev->base);

/* If there was an error, discard the data */

if (status & (ALTERA_AVALON_UART_STATUS_PE_MSK | ALTERA_AVALON_UART_STATUS_FE_MSK)) { return; } /*** TUTAJ KOŃCZĄ OBSŁUGĘ PRZERWANIA BEZ WSTAWIENIA ZNAKU DO BUFORA ***/

dev->rx_end = next;

next = (dev->rx_end + 1) & ALT_AVALON_UART_BUF_MSK;

/* * If the cicular buffer was full, disable interrupts. Interrupts will be * re-enabled when data is removed from the buffer. */

if (next == dev->rx_start) { dev->ctrl &= ~ALTERA_AVALON_UART_CONTROL_RRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL(dev->base, dev->ctrl); } }

Bardziej szczegółowy opis moich zmagań z wyprodukowaniem prostej funkcji "ReadUARTwithTimeout" w tym środowisku zamieszczam tutaj:

formatting link
Nie wiem jak spowodować w tym środowisku aby poprawiony przeze mnie moduł C z biblioteki HAL trafił do mojego kodu... Może wystarczy wstawić kopię tej funkcji do mojego projektu i linker poprawnie zlinkuje kod zastępując funkcję biblioteczną moją wersją? Muszę tego spróbować...

Reply to
Pszemol
Loading thread data ...

A zgłaszałeś ten problem na stronie Altery?

Reply to
invalid unparseable

Nie, a co ? :-)

Reply to
Pszemol

Poprzez stronę Altery jest wsparcie dla Quartusa. Może coś wiedzą i powiedzą.

Paweł

Reply to
invalid unparseable

Zgłosiłem to przez mySupport. Zobaczymy. Na razie zauważyłem że jak włączę cały ten moduł biblioteczny do mojego projektu to lokalna funkcja zgodnie z oczekiwaniami nadpisuje biblioteczną, więc jest dobra metoda na poprawienie tego błedu zanim Altera zareaguje...

Teraz borykam się z debuggerem, który zdaje się zatrzymywać na breakpoincie którego nie ma w moim kodzie... Nie ma "kropki" i przełączanie toggle breakpoint też nie pomaga. W efekcie nie działa mi debugger w ogóle bo nie umiem tego breakpointa wyłączyć w procedurze przerwania... Altera ma wiele jeszcze do dopracowania w tym swoim pakiecie dla Niosa II :-(

Reply to
Pszemol

Opanowałem debugger i breakpointy... Okazuje się, że jak ustawię breakpointa w module źródłowym biblioteki, a potem włączę tak samo nazwany moduł z tymi samymi funkcjami lokalnie do projektu (inny plik w folderze projektu!) to debugger głupieje i staje na numerze linii odpowiadającym ustawionemu breakpointowi w kodzie biblioteki... dwie godziny na to dziwactwo dziś straciłem... Pomogło dopiero usunięcie modułu lokalnego, skompilowanie kodu spowrotem z funkcją z oryginalnej biblioteki - debugger skoczył do breakpointa i wtedy udało się breakpointa wyłączyć... potem znów kod przekompilować z lokalnym modułem i od tej pory szafa gra. Na wszelki wypadek zmieniłem modułowi lokalnemu nazwę pozostawiając tylko nazwy funkcji takie same wewnątrz aby się wołało co trzeba :-)

Niestety - zmodyfikowałem obsługę przerwania tak, aby budziło task dopiero po sprawdzeniu błędu parzystości i ramki i dalej mam problem z funkcją read() zwracającą kod zero mimo iż wołam read() dopiero gdy dostanę sygnał z OS że ustawiono flagę w ISR... shit! Nie mam pojęcia co jest grane.

Reply to
Pszemol

Skoro już dłubiesz przy NIOS-ie, czy możesz zdradzić ile komórek on pożera w projekcie i na jaką rodzinę układów realizujesz projekt? Jak dotychczas w swoich eksperymentach używałem jedynie 8-bitowego TSK52A z biblioteki Altium Designera, który pożera z grubsza połowę mojego testowego Cyklona.

Paweł

Reply to
invalid unparseable

No odpisali mi:

" Hi Przemek,

I agree with you. This should be the bug of the HAL code. Thank you for reporting it to us. We will fix this issue in the later version.

Have a nice day.

-Dylan "

:-)))) Yahoo! :-))))

Reply to
Pszemol

nie wiem jakiego cyclone miales, ale ja w EP1C6 wfitowalem sredniego NIOSa z

2 kontrolerami SDRAM i jeszcze zostalo troche na obsluge PCI pod gigabit ETH. Czekam az mi zmontuja plytki, to odpale w naturze..
Reply to
Greg(G.Kasprowicz

Też w tej chwili używam EP1C6 w obudowie 256 pinów. Najmniejszy rdzeń Nios II zajmuje mi 1114 LC. Do tego dochodzą kontrolery magistrali Avalon: cpu_data_master arbitrator - 289 LC, cpu_instruction_master 30 LC, cpu_jtag_debug_module_arbitrator 25 LC, kontroler zewnętrznej magistrali trzystanowej do CFI flasha i SRAM (nie używam DRAMu na tej płycie) 126 LC. Do niego dodałem timer sys_timer 140 LC, jtag_uart 164 LC, kilka prostych UARTów bez programowanych dzielników prędkości nadawania ani bez handshake po 144-185 LC każdy (zależnie od ustawionej prędości nadawania). Oczywiście do tego dochodzą takie pierdółki jak PIO (ok 70 LC) itp. W sumie mam proca, wewnętrzną pamięć ram 4k/32bit, zewnętrzną magistralę o której wspominałem, jeden uart 9600 baud, 4 uarty po

2400 baud każdy i cztery kanały danych zlożone z portów 24 bitowych i innych dupereli - plus cztery kanały obróbki danych 24 bitowych 80MHz z 8 rzędowym FIFO - całość zajmuje 4871 LC z 5980 dostępnych i 43776 komórek pamięci z 92160 dostępnych, a więc zostało sporo miejsca :-) To jest płyta "prototypowa". Docelowo system ma mieć 8 takich kanałów i zamiast Cyclone I ma używać Cyclone II EP2C8 czyli ciut większą kostkę.

Jak chcesz, to Ci mogę wysłać raport "resource utilization per entity".

Reply to
Pszemol

przyznam ze Support Altery jest w porzadku, od razu widac ze tam tez sa zwykli ludzie z podobnymi problemami:) mam przyjemne wrazenia ...swego czasu robilem projekt na Cyclone jak dopiero wchodzily do sprzedazy.. problemow bylo mnostwo..Quartus byl jeszcze w wersji 3.0..troche problemow rozwiazalismy wtedy..

Reply to
Greg(G.Kasprowicz

Już wiem! Mój kod otwiera wielokrotnie ten sam uart i zamyka go - wygląda na to, że nieodczytane znaki (i ustawione flagi w przerwaniu od odbiornika) powodują że po następnym otwarciu portu uart task nie jest zatrzymywany na fladze gdyż jest ona już ustawiona przy odebraniu znaku z poprzedniej sesji...

Zmodyfikowałem swój kod w taki sposób że zamykam "kurek" który prowadzi pin zewnętrzny do odbiornika uarta gdy odczytam ostatni znak sesji i zamykam programowo uart funkcją close(). W ten sposób uart nie dostaje żadnych znaków po odczytaniu ostatniego... Czyli flaga nie zostaje ustawiona i uart już nie budzi mnie w następnej sesji zanim nie przyjdzie nowy znak.

Problem w tym, że oznacza to że jest tam następny bug w sofcie Altery :-) mianowicie flaga ta ustawiana w przerwaniu odbiornika nie jest kasowana wraz z zamknięciem uarta i ponownym otwarciem go!

Muszę dodać tą notkę do tego samego zgłoszenia bo to właściwie ten sam problem "brudnego" kodu obsługującego przerwania uarta.

Reply to
Pszemol

Ja z suportu Altery jestem niezadowolony. Głównie z powodu tego, że nie oferują pomocy telefonicznej - support przez website jest wprawdzie lepszy niż nic, ale czas na odpowiedź jest długi i często trzeba kilka razy piłeczkę przepykać na drugą stronę boiska zanim się dojdzie do ładu i składu o co właściwie chodzi. Przez telefon załatwiłoby się taką wymianę pytań w 5 minu... A czas to pieniądz. Z drugiej strony, wnioskując po czasie w którym pojawia się odpowiedź (przynajmniej ostatnio koło 9-10 w nocy w Chicago) można odgadnąć że support mają gdzieś po drugiej stronie globu. Pewnie w Indiach, bo j. angielski jakiego używa pomoc nie jest w 100% tym, do czego przywykłem kontaktując się z firmami w USA.

Reply to
Pszemol
[ciach]

I jaki tak wypchany Cyclone ma fmax i która to wersja (speed grade)?

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Analizy czasowej jeszcze nie robiłem...

Funkcjonalnie wszystko pyka, ale sam Nios daje jakieś 300 ostrzeżeń na które nie mam żadnego wpływu bo siedzą w kodzie Altery... Trochę to znieczula na ostrzeżenia kompilacji Quartusa.

Docelowo ma to pracować przy zegarze cpu_clk 82MHz i cpu_clk ma również zatrzaskiwać licznik danych i fifo. Całość ma hulać na wersji speed grade C8... Myślisz że będą problemy?

Na razie zaczynam testowanie od cpu_clk 41MHz... Wszystko w porząsiu jak dotąd.

Reply to
Pszemol

Szkoda. Jak zrobisz, to się pochwal.

Nie mam pojęcia. Straszyli mnie tu kiedyś gwałtownym spadkiem wydajności przy zapełnianiu układu i właśnie chciałem się przekonać empirycznie. :-)

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

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.