tleski Październik 12, 2015 Udostępnij Październik 12, 2015 Dzięki ale ze mnie czoper hehe 🙂 Myślałem, że to jest pod wersję AMD! Nadal mam wykryte 2 urządzenia (miały być 3)... STMicroelectronics STLink Virtual COM Port (52) i STMicroelectronics STLink dongle Cytuj Link do komentarza Share on other sites More sharing options...
Wojciech Październik 12, 2015 Udostępnij Październik 12, 2015 Dzięki ale ze mnie czoper hehe 🙂 Myślałem, że to jest pod wersję AMD! Nadal mam wykryte 2 urządzenia (miały być 3)... Spójrz w "Portable Devices". Cytuj Link do komentarza Share on other sites More sharing options...
Sebastian_code Październik 12, 2015 Udostępnij Październik 12, 2015 Witam serdecznie, potrzebuję pomocy w rozwiązaniu problemu z Debugerem. Otóż przy pierwszej próbie jego włączenia (tak jak w kursie) nie wystąpiły żadne problemy, natomiast gdy dodałem zmienną "int" na początku main() i inkrementowałem ją w for() wyświetlał się następujący komunikat błędu: Jestem nowicjuszem jeśli chodzi o Eclipse, mój system operacyjny to WinXP a płytka zawiera STM32F401. Za sugestię i okazaną pomoc będe bardzo wdzięczny. EDIT: jeszcze raz uruchomiłem RUN(już bez Debuggera) i w konsoli pojawiły się błędy: Info : auto-selecting first available session transport "hla_swd". To override use 'transport select '. Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD adapter speed: 2000 kHz adapter_nsrst_delay: 100 srst_only separate srst_nogate srst_open_drain connect_deassert_srst srst_only separate srst_nogate srst_open_drain connect_deassert_srst Info : Unable to match requested speed 2000 kHz, using 1800 kHz Info : Unable to match requested speed 2000 kHz, using 1800 kHz Info : clock speed 1800 kHz Error: read version failed //<-- w tym miejscu coś nie tak in procedure 'program' in procedure 'init' called at file "embedded:startup.tcl", line 473 in procedure 'ocd_bouncer' ** OpenOCD init failed ** shutdown command invoked Gdzie szukać przyczyny ? Cytuj Link do komentarza Share on other sites More sharing options...
Wojciech Październik 12, 2015 Udostępnij Październik 12, 2015 Sebastian_code, programy na mikrokontroler nie mogą się zakończyć - dojść do return w funkcji "main". W programie musi istnieć pętla nieskończona. Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
Sebastian_code Październik 13, 2015 Udostępnij Październik 13, 2015 Sebastian_code, programy na mikrokontroler nie mogą się zakończyć - dojść do return w funkcji "main". W programie musi istnieć pętla nieskończona. Witam, zatem czy to jest główna przyczyna całego zamieszania? Oczywiście sam to sprawdzę ale dzięki za wskazówkę. Niby oczywista rzecz a jednak 🙂 Swoją drogą, dlaczego funkcja main() jest typu "int" a nie "void" skoro nic nie zwraca ? ======================== Witam ponownie, sprawdziłem, poprawiłem i teraz wszystko działa bez problemu. Dzięki za pomoc. Mam jeszcze jedno pytanie. Kod napisałem jak na zdjęciu: Wiem wiem, niepotrzebnie przekombinowane z zerowaniem zmiennej, ale chodzi mi o coś innego. Przy ostatniej klamrze czasem pojawia się podkreślenie a błąd :"Control reaches ond of program." Z tym że wiadomo że sterowanie nigdy nie osiągnie końca kodu. Czy należy się tym przejmować? Cytuj Link do komentarza Share on other sites More sharing options...
Chumanista Październik 13, 2015 Udostępnij Październik 13, 2015 Pełne wyjaśnienie dlaczego int main() nasz tutaj: http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c Ogólnie służy to do zwracania w jaki sposób program zakończył pracę. Cytuj Link do komentarza Share on other sites More sharing options...
Sebastian_code Październik 13, 2015 Udostępnij Październik 13, 2015 Pełne wyjaśnienie dlaczego int main() nasz tutaj:http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c Ogólnie służy to do zwracania w jaki sposób program zakończył pracę. No tak tak. Wiem co to oznacza ale zastanawia mnie inna rzecz. Skoro funkcja nic nie zwraca to jej typ powinien byc "void". A funkcja z kursu ma typ "int" a więc powinna zwracać wartość typu int a jednak z powodu tego że jest to program na mikroprocesor nie zwraca niczego bo musi bć ciągła. I kompilator nie zgłasza błędu. Czy w tym przypadku funkcja main() nie powinna być typu void ? Cytuj Link do komentarza Share on other sites More sharing options...
Chumanista Październik 13, 2015 Udostępnij Październik 13, 2015 Main w C MUSI być int zgodnie ze standardem. Praktycznie każdy nowoczesny kompilator dodaje return 0; na koniec main jeśli nie znajdzie nic innego. Jednakże dobrą praktyką jest umieszczenie go tam samemu: int main //Kod while(1) { //Więcej kodu } return 0; //Nigdy się nie wykona } Cytuj Link do komentarza Share on other sites More sharing options...
Treker (Damian Szymański) Październik 13, 2015 Udostępnij Październik 13, 2015 Wiem wiem, niepotrzebnie przekombinowane z zerowaniem zmiennej Racja, przyznam, że zrobiłeś to tak zawile, że nie mogę nawet się domyślić jaki był tego cel. Możesz z ciekawości opisać, co Tobą kierowało 😉? Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Październik 13, 2015 Udostępnij Październik 13, 2015 Funkcja main() na mikrokontrolerach to dość ciekawy temat. Zacznijmy od nieco większych systemów, powiedzmy Linuxa, czy Windows. Sygnatura powinna być następującej postaci: int main(int argc, char* argv) Parametr argc wskazuje liczbę argumentów wywołania programu, natomiast argv to wskaźniki do parametrów. Tradycyjnie pierwszym jest nazwa programu, kolejne są opcjonalne - pojawiają się jeśli program został wywołany z parametrami. Program jest wczytywany (np. z dysku) przez system operacyjny, system przygotowuje pamięć oraz proces dla programu, po czym wykonuje skok do funkcji main(). Więc kod funkcji main to pierwsza instrukcja nowo wczytanego programu. Gdy program się kończy, zwraca on informację do systemu - tradycyjnie 0 oznacza, że program wykonał się prawidłowo, inne wartości oznaczają wystąpienie błędu. Przed uruchomieniem naszego programu działał już system operacyjny, podobnie po jego zakończeniu system nadal kontroluje pracę komputera. W przypadku mikrokontrolerów sytuacja jest nieco inna - nie mamy systemu operacyjnego, więc co jest uruchamiane przed naszym programem i co miałoby działać po nim? Odpowiedź kryje się w pliku startup_stm32f10x_md.S. Zawiera on kod w asemblerze i wspominałem o nim podczas kursu. W rzeczywistości main() wcale nie jest pierwszym kodem, który jest wykonywany po uruchomieniu mikrokontrolera. Nie licząc bootloadera, wykonywanie rozpoczyna się od adresu, który jest zapisany w komórce 0x04. g_pfnVectors: .word _estack .word Reset_Handler Jak widać jest tam adres kodu o etykiecie Reset_Handler. Czyli po uruchomieniu lub resecie, zacznie się wykonywać program: Reset_Handler: /* Copy the data segment initializers from flash to SRAM */ movs r1, #0 b LoopCopyDataInit Pod koniec tego kodu znajdziemy skok do funkcji main: /* Call static constructors */ bl __libc_init_array /* Call the application's entry point.*/ bl main bx lr Instrukcja "bl main" to właśnie skok do main(). Nie przekazujemy parametrów, więc nawet gdyby ktoś zadeklarował argc i argv, nie powinien ich używać - znajdą się tam losowe wartości. Skok bl to tzw. skok ze śladem, więc program może "wrócić" do kolejnej instrukcji. Nie powinno mieć to miejsca, ale jeśli jednak zakończymy naszą funkcję main, to program przejdzie do kolejnej instrukcji, czyli: bx lr Co ta instrukcja zrobi? Też wykona skok. Niestety jest niepoprawna - chyba trzeba to będzie zgłosić od OpenSTM32 - mają tutaj najzwyklejszy błąd. Powinna to być pętla nieskończona, a zamiast niej wyszedł skok pod nieco losowy adres. Prawda jest więc taka - nic nie odczytuje wartości zwracanej z main. Więc czy będzie to int, czy void nie ma różnicy. Nie ma też różnicy jaką wartość byśmy zwrócili. Natomiast kod powinien być zmieniony na: b . Wtedy zamiast nieco losowego zachowania, mielibyśmy nieskończoną pętlę, zaraz "za" funkcją main. Ale ponieważ main nie powinna się kończyć, wiec nikt na taki błąd uwagi nie zwrócił. Cytuj Link do komentarza Share on other sites More sharing options...
Maniek93 Październik 13, 2015 Udostępnij Październik 13, 2015 Witam, mam pewien problem, a właściwie pytanie, ale zacznę od początku. Jakiś czas temu gdy zaczynałem z STM(właściwie nadal zaczynam), zainstalowałem sobie eclipse, zgodnie z poradnikiem frediegochoppina, może ktoś zna, ale potem znalazłem te gotowe oprogramowanie, które pokazujecie w tym kursie, więc przeszedłem na nie. W obu wersjach pojawiał się ten sam problem, gdy próbowałem kompilować kod Co prawda znalazłem w internecie rozwiązanie- w opcjach projektu w zakładce c/c++ build, musiałem zmienić opcje buldier type z external buldier na internal buldier i wtedy było wszystko ok, myślałem że to coś normalnego, ale widzę, że w kursie nie ma o tym mowy, więc pewnie zrobiłem coś źle, podpowie ktoś co? Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Październik 13, 2015 Udostępnij Październik 13, 2015 Prawdopodobnie zainstalowałeś wcześniej kompilator gcc dla arm-ów. I ta wersja jak widać nie bardzo działa. Jeśli instalujesz OpenSTM32 - środowisko instaluje się z kompilatorem, dlatego po zmianie external (zainstalowany wcześniej), na internal (dostarczony z OpenSTM) zaczęło działać. Tak mi się wydaje, bo w sumie ciężko powiedzieć... Spróbuj odinstalować gcc, które zinstalowałeś wcześniej - powinno pomóc. Cytuj Link do komentarza Share on other sites More sharing options...
Maniek93 Październik 13, 2015 Udostępnij Październik 13, 2015 Tak, instalowałem, bo było potrzebne do wersji, gdy używałem "czystego" eclipse, spróbuje zrobić jak mówisz. Cytuj Link do komentarza Share on other sites More sharing options...
Sebastian_code Październik 13, 2015 Udostępnij Październik 13, 2015 Wiem wiem, niepotrzebnie przekombinowane z zerowaniem zmiennej Racja, przyznam, że zrobiłeś to tak zawile, że nie mogę nawet się domyślić jaki był tego cel. Możesz z ciekawości opisać, co Tobą kierowało 😉? Lenistwo 😉 Skoro miałem już pętle for() to zapisałem w niej warunek na zerowanie zmiennej która była iteratorem tejże pętli. To samo można uzyskać w zasadzie dla fora bez wypełnionych pól ale mogłem dzięki temu obserwować inkrementowaną i zerowaną zmienną(debuger). Co do omawianego wątku z funkcją main() i zwracaniem wartości to doskonale rozumiem o co chodzi bo na studiach mam programowanie w C++ aczkolwiek dalej nie rozumiem dlaczego funkcja main() posiada typ zwracany int a nie void skoro i tak nie zwraca zadnej wartości. Skoro nie zwraca to niech będzie void 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Październik 14, 2015 Udostępnij Październik 14, 2015 int jest zwracany dla zachowania zgodności ze standardem. Taką sygnaturę generuje domyślnie środowisko OpenSTM32 i taka dla naszych potrzeb jest całkiem dobra. Natomiast co do main() to nie jest zwykła funkcja. Jest traktowana w specjalny sposób - po pierwsze jest wymagana jako start programu, po drugie return 0 jest przez C++ automatycznie dodawane. Więc nie ma co nad tym int-em dyskutować. Tylko trzeba pamiętać, żeby na mikrokontrolerach z niej nie wychodzić - to nie jest zwykła funkcja. Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!