Musisz w istocie powielić ten fragment kodu który pokazałeś wyżej i zmienić w nim symbole na takie jak użyłeś dla tego drugiego obszaru. Jak ładujesz program przez debugger, to on ładuje też sekcję zmiennych, więc w istocie może się czasem wydawać, że są zainicjalizowane <: Ten startup i skrypt linkera nie jest przygotowany na takie automatyczne...
Myślałem żeby załaczyć Ci mój projekt ale - 1. jest komercyjny 2. jest zbyt myślę złożony Tak że na szybko sama idea - jest to zrobione w 5 minut i skrypt linkera powinno sie przerobic lepiej. Funkcje też są do kitu - bo parametry trzeba przekazywać wskaznikiem do nich) wtedy nie jesteś ograniczony ich ilościa itd itd. Nie jest to reentrant i bezpieczne....
W zakładce linkera - memory settings definiujesz nowy obszar. Przy czym tak zdefiniowana pamięć i tak nie będzie wprost dostępna - wymagane jest jeszcze przeniesienie sterty - wtedy stanie się dostępna do alokacji przez malloc. Przeniesienie stosu i obszaru zmiennych statycznych/globalnych też jest możliwe, ale raczej nie ma sensu.
Co do umieszczania kodu w odpowiednich przestrzeniach to trzeba zmodyfikować skrypt linkera oraz użyć atrybutów do danych i kodu aby kompilator odpowiednio stworzył obiekty. Ale to nie jest wystarczające. Trzeba dopisać trochę kodu w startupie jeżeli mają być zainicjalizowane (zerowanie też uznamy dla uproszczenia za inicjalizację aby nie tworzyć dodatkowych...
Widzę, że zadałem trudne albo głupie pytanie. Pewnie GCC jest tak toporne, że nie podoła zadaniu. Akurat GCC nie jest tak toporne jak narzedzia komercyjne ;). Wiec: Na czym polega mój problem? Jak zmusić gcc, aby w module: - program zaczynał się od zdefiniowanego adresu Ustawiasz to w skrypcie linkera: MEMORY { CODE (rx) : ORIGIN =...
A dat jakiego jest typu? Bo skąd ten biedny kompilator ma wiedzieć o ile bitów przeskakiwać po tej pamięci? Nie potrzebujesz przypadkiem czegoś w stylu: [syntax=c]*((volatile uint32_t *) adres) = dat;[/syntax] ?? Poza tym prościej chyba sobie zrobić sekcję linkera i tworzyć zmienne normalnie + atrybut umieszczający je w odpowiednim obszarze niż cudować...
Gdzie trafi zmienna lokalna w main zainicjowana i nie niezainicjowana ? Zależy co rozumiesz przez "lokalna". Generalnie do celu tej dyskusji proponuję się ograniczyć do podziału na "statyczne" (m.in. globalne) i "automatyczne" (czyli zmienne "w" funkcjach, oczywiście bez "static"). Te pierwsze lądują w .data lub .bss (zależnie od tego czy są zainicjalizowane...
Pytanie po 1 dotyczy attolica. Przecież w Attolicu też są zmienne absolutne. A to jak się je akurat w nim deklaruje się takie zmienne to tylko kwestia zajrzenia do helpu, kwestia zupełnie poboczna w tym temacie. Osobiście nie pamiętam, bo dawno w nim nie pracowałem. Po 2 po co wpierniczać się w to co robi linkera skoro spokojnie można po prostu dać...
Tam na mbed w pliku eeprom.c jest taki trik z zasłonięciem używanego przez eeprom obszaru atrapowymi zmiennymi: Świetny trik (; Dzięki temu każde wgranie programu (np. podczas debuggowania) kasuje całą zawartość tego EEPROMu (; Nie no, serio, jedyną sensowną opcją jest wydzielenie sobie do tego celu jakiegoś obszaru przez skrypt linkera...
Pierwsza opcja to oczywiście zdefiniowanie NAPRAWDĘ DUŻEGO stosu, ale to średnie rozwiązanie jak wiadomo [; Do rozbudowanej aplikacji na ARMa myślę że należy liczyć minimum 1kB, jeśli używa się jakichś potwornych funkcji standardowych (printf!) i to głęboko to lepiej zaopatrzyć się w 2kB (o apetycie tych funkcji na pamięć pisałem ostatnio http://www.elektroda.pl/rtvforum/topic13...
No więc faktycznie nie ma dostępu bit-band do obszaru 0x10000000. Szkoda, że kompilator nie ostrzega przed próbą takiego dostępu. Problem z automatycznym umieszczaniem zmiennych w dodanej sekcji (0x22000000) można zrealizować dzięki funkcji linkera ImageLength(<nazwa sekcji>), której zwróconą wartość można wykorzystać przy deklarowaniu adresu...
Naprawdę kopiowane są wszystkie funkcje a nie tylko to, które są wykorzystywane? Może to kwestia włączenia optymalizacji? Trochę OT, ale wyjaśnię. W uproszczeniu, w standardowym kompilatorze (np. gcc :wink:), wytworzenie programu wykonywalnego składa sie z dwóch faz: 1. fazy kompilacji .c --> .o (albo np. .s ->> .o) 2. fazy łączenia .o (razy N) -->...
Jeśli chcesz ograniczyć możliwe pozycje dla takiej struktury do kilku pierwszych kB firmware'u, to trzeba modyfikować skrypt linkera. A w takim wypadku mogę sobie równie dobrze umieścić ją gdzie mi się podoba z dokładnością do jednego bajta (; No chyba ze o czymś nie wiem i znasz sposób na wymuszenie lokalizacji jakiejś zmiennej w jakimś obszarze pamięci?
Obszar .bss podzieliłem na symbole i zmienne globalne (działa w 100% ok): .bss1 (NOLOAD) : { . = ALIGN(4); _sbss = . ; *(.bss .bss.*) . = ALIGN(4); _ebss = . ; } >IRAM0 AT>IRAM0 .bss2 (NOLOAD) : { . = ALIGN(4); *(COMMON) *(.gnu.linkonce.b*) . = ALIGN(4); } >IRAM1 AT>IRAM1 Problemem okazało się przepełnianie się pamięci w obszarze stosu przy zmianie...
W Zmienne globalne — wiedz, kiedy są modyfikowane Zmienne globalne muszą być ostrożnie obsługiwane, gdy są używane z przerwaniami, ponieważ te są generalnie asynchroniczne. I jeżeli zmienna globalna jest modyfikowana przez ISR, może zostać zmieniona w dowolnym momencie. Musimy mieć na uwadze następujące aspekty: Odczyt/zapis zmiennych globalnych...
Kontynuuję temat ponieważ natrafiłem na kolejny problem. W tej chwili kompiluję aplikację i bootloader jednocześnie. W rezultacie po modyfikacjach w programie głównym ulega zmianie także obszar bootloadera w pliku hex. Wydaje mi się że to przez zmianę alokacji zmiennych w pamięci ram lub stałych z dyrektywy #define używanych w funkcjach bootloadera....
asm("LDI R26,0xAA" "\n\t" "STS 0x2000,R26" ); asm("LDS R26,0x2000"); Dostępy na moje oko prawidłowe. Jeśli nie chcesz pisać reszty w asemblerze, musisz zawartość komórki RAM przeładować z/do zmiennej i dalej już operować nią w C Innym sposobem jest alokowanie sekcji danych w obszarze external SRAM (dyrektywami linkera), ale w tym Ci już nie pomogę,...
1. Wiemy podczas pisania programów na architekturę ARM programista decycyduje za pomocą skryptu linkera gdzie w pamięci leżą sekcje programu generowane przez kompilator. Najczęściej wygląda to w ten sposób: Nie do końca tak to wygląda dla ARM, choćby dlatego, że zwykle między flash a RAM jest spora "dziura", a więc między .rodata a .data na obrazku...
Linkera to nie obchodzi czy ta pamięć działa czy nie działa. Jeśli umieścisz w niej jakieś zmienne, to przed ich inicjalizacją trzeba tą pamięć skonfigurować. Jeśli inicjalizacja jest robiona w startupie, to przed tą inicjalizacją, w moim startupie, jest wywoływana magiczna funkcja low_level_init_0() oraz low_level_init_1() - trzeba sobie taką funkcję...
(at)BlueDraco Teoretycznie tak, ale jak to zrobić "elegancko". Mam dwie "standardowe aplikacje". Jedna, to "loader", która zawsze startuje po resecie procesora, druga "zwykła", która jest uruchamiana przez "loader'a". Obydwie rezydują w osobnych obszarach flash i na początku kodu mają własne tablice przerwań. Dodatkowo "loader" zna położenie "zwykłej"...
Jest zasadnicza różnica pomiędzy tymi deklaracjami. Obie z pozoru maja robić to samo. Pierwsza inicjuje zawartość tablicy wprost, wartościami dla wygody podawanymi jako znaki. Kompilator a dokładnie linker zbiera wszystkie inicjowane zmienne "do kupy". Umieszcza je w obrazie a następnie, tuż po starcie specjalny kod (czasami kompilator go generuje,...
W między czasie, patrzę na przykłady z STM32 i nie mogę się nadziwić.... no cóż czasem człowiek potrafi skomplikować proste sprawy... ja piszę tak: FSMC_Bank1->BCR3 = FSMC_BCR3_MBKEN | FSMC_BCR3_FACCEN | FSMC_BCR3_WREN ST tak: FSMC_Bank1->BTCR O zmiennych w innych obszarach jest już conajmniej kilka tematów... tylko poszukać... 4\/3!! Czyli nie ma...
I gdzie jest Twoja zmienna? : O to Ci chodziło? U mnie pod SW4STM32 identycznie debuger pokazuje takiego rodzaju śmieci. Ale jak się przypatrzeć to widać wyraźnie że błędnie lokalizuje tą zmienną w obszarze RAM (np. 0x20000070). Bierze adres stąd (output.map): .mySection 0x20000070 0x3b load address 0x08002634 .mySection 0x20000070 0x3b Src/main.o...
Tak że kompilując gcc lub gcc podobnym kompilatorem jest tak jak opisałem. Nope. Dane const i dane do inicjalizacji zmiennych o typie static gcc standardowo dodaje do secji .rodata. Pierwsze tak, drugie nie. Inicjalizatory zmiennych - czyli tego co jest w sekcji .data - znajdują się w dokładnie tej samej sekcji co te zmienne - czyli w sekcji .data....
Witam, poczytałem sporo informacji nt. skryptów linkera, ale niestety jednej rzeczy nie mogę zrozumieć. Mam przykładowy zapis (sam napisałem): [syntax=c] .text : { . = ALIGN(4); __text_start__ = .; /* zmienna zawierająca początek sekcji text */ *(.text) /* kod wykonywalny aplikacji */ *(.text.*) *(.rodata) /* dane tylko do odczytu przechowujemy we flashu...
Pytanie dotyczyło przyczyny generowania różnego kodu wynikowego. W jakim celu chcę nad tym zapanować chyba nie jest istotne. Jak chcesz nad wszystkim panować pisz w asm. Dokładnie określisz pod jakim adresem co ma się znajdować, które funkcje mają byc na początku kodu, a które na końcu. W C nie widzę możliwości aby zrealizować to w prosty sposób. Można...
Czyżby? Czy dla AVR ktokolwiek przejmuje się skryptami linkera, startupem, tablicą wektorów i Makefilem? Przecież dla tej platformy jest DOKŁADNIE TAK SAMO jak dla ARM, a jakoś nikomu nawet na myśl nie przyjdzie zajmować się tymi plikami - każdy korzysta z gotowców zawartych w pakiecie avr-gcc. Te pliki tam fizycznie są, nikt nie zajmuje się tym jak...
Raczej nic to nie zmieni. W funkcjach variadic float jest traktowany jak double (zajmuje 8 bajtów lub 2 rejestry), stąd problem. Kompilator dba o stos podczas pracy programu, ale to co dostaje na wejściu musi być wyrównane do 8-miu bajtów. Jeśli chcesz znaleźć źródło problemów, to olej na chwilę FreeRTOSa i po prostu w jakimś programiku zwykłym przetestuj...
Co do dołączania - jakby kolega pisał poważne projekty, gdzie dołączanych jest sporo plików, nie tylko nagłówków, ale źródłowych, które umieszczają zmienne w EEPROM to by nie pisał takich bajek. Co do działania linkera to też polecam manuala. C to nie Bascom. hehehe co? jak ci brak argumentów do dyskusji to zwykle sięgasz po opowieści o swoich wyimaginowanych...
Zmodyfikowałem ten handler do postaci https://obrazki.elektroda.pl/7811206300_... Gdy dodałem jako atrybut do funkcji "naked" (/* uprzednio weak -> błąd pisarski */) żeby kompilator nie dodawał na wejciu odkładania na stos to wchodzi i działa ale tak czy inaczej zawiesza się potem gdy chce zapisywać do BKP wartości z ramki stosu do...
Mikrokontrolery STM32H7 posiadają kilka domen zasilania i kilka bloków pamięci. Niby nic wielkiego, ale sprawa trochę się komplikuje kiedy trzeba korzystać z DMA przy obsłudze peryferiów i dość dużych struktur pamięci. https://obrazki.elektroda.pl/4349869800_... Pamięć danych jest dostępna jako (zielone obszary): DTCM - Pamięć danych...
To zależy, co masz na myśli mówiąc regulować. Standardowo cała dostępna pamięć jest przeznaczona na stos, zmienne statyczne i zmienne dynamiczne. Tzn. na początku pamięci jest obszar zmiennych statycznych, potem ewentualnie obszar zmiennych dynamicznych, który rośnie "w górę". Na końcu jest stos, który rośnie od końca pamięci "w dół". Jeżeli pamieci...
Dzisiejszy świat pulsuje możliwościami, jakie mają do zaoferowania duże modele AI, takie jak ChatGPT. Potencjał sztucznej inteligencji do zrewolucjonizowania sposobu, w jaki ludzie pracują i bawią się, jest zdumiewający, a dla niektórych również nieco przerażający. Aby pokazać pewną perspektywę względem tego zjawiska, wystarczy spojrzeć na akcje firmy...
Tak w uproszczeniu kompilator generuje 3 sekcje - text, data i bss. Pierwsza zawiera kod, druga zainicjowane zmienne, trzecia jest pusta i zawiera tylko deklaracje rozmiaru i jest przeznaczona na zmienne niezainicjowane (obie sekcje są na zmienne statyczne/globalne). Jak działa uruchomienie to zależy od architektury. W normalnych komputerach, gdzie...
(uint8_t*)5 tobi z literału 5 wskaźnik wskazujący na komórkę pamięci o adresie 5 (w tym przypadku EEPROM). Deklarując zmienną w obszarze EEPROM nie musisz znać jej adresu! Odwołując się do niej pobierasz po prostu jej adres przy pomocy operatora &. Dzięki temu to kompilator i linker myślą jak rozmieścić zmienne, a nie ty. I o to mniej więcej by chodziło...
Pytanie jest o deklaracje main.c Kod: unsigned int *msg; oraz w spi.h Kod: static unsigned int *msg; Czy ja dobrze rozumiem, że są to dwie zmienne, z czego pierwsza widziana jest tylko w pliku main.c a druga tylko i wyłącznie w pliku spi.c? Mylisz się. Pierwsza zmienna msg jest zadeklarowana wewnątrz funkcji main() i tylko tam jest widoczna. W przypadku...
Cześć! Poszukuję wsparci gdyż powstał mętlik w głowie. Mam program, który komunikuję się z modułem GSM, używa wielu globalnych tablic, funkcji operujących na strumieniach typu strcpy, str n cpy, strstr, strtok, poniżej wklejam większość deklaracji dużych zmiennych: Dodano po 1 Przeniosłem deklarację StackPoint z .int1 do .int3 i program zaczął wyświetlać...
sekcja linkera skrypt linkera stm32 linkera
mcp23017 raspberry zastosowanie przemiennego rozdzielić kabel domofon
wymiana złoża stacja wymiana złoża
Bosch WAN vs WGE Washing Machines: Key Differences, Features, and Efficiency Mercedes OM654 – koszt wymiany dźwigienek i popychaczy, ceny części i robocizny 2024