Ankieta: Jaki system operacyjnym preferujesz
Ankieta jest zamknięta.
Windows 60.78% 31 60.78%
Linux 31.37% 16 31.37%
MAC/OS 7.84% 4 7.84%
Inny 0% 0 0%
Razem 51 głosów 100%
*) odpowiedź wybrana przez Ciebie [Wyniki ankiety]

Odpowiedz 
 
Ocena wątku:
  • 1 Głosów - 5 Średnio
  • 1
  • 2
  • 3
  • 4
  • 5
Programowanie ARM, nauka, środowiska programistyczne IDE
SP5FCS Offline
Adam
*****

Liczba postów: 1,071
Dołączył: 02-02-2009
Post: #97
RE: Programowanie ARM, nauka, środowiska programistyczne IDE
Paweł, fajne zadanie z dobrym opisem. Mam jednak obawy co kryje się pod tą "ciszą" i brakiem pytań. Już w tym zadaniu materiału jest naprawdę dużo do opanowania.

Moduły programu
Nawet rozbudowany program napisany w języku C możemy umieścić w jednym pliku. Niestety wraz z przybywania kolejnych linii kodu jego czytelność jest coraz mniejsza a poruszanie się po całym kodzie trudniejsze. Nawet jeśli pogrupujemy definicje i funkcje w tematyczne bloki to odnalezienie ich w programie liczącym kilka tysięcy linii jest trudne i czasochłonne. W rozbudowanych procesorach takich jak STM32 sama ilość definicji rejestrów, bitów, stałych, funkcji obsługi rdzenia to kilkanaście tysięcy linii kodu. Aby jakoś zapanować nad tym ogromem informacji pogrupowano ją w bloki tematyczne i umieszczono w oddzielnych plikach. Poszczególne fragmenty kodu są włączane do naszego programu dyrektywą #include. Przykład: #include "stm32f4xx.h"

Od początku powstawania programu warto zadbać aby również nasz kod był podzielony na bloki tematyczne, w które zostaną pogrupowane definicje i funkcje do obsługi jednego zagadnienia np. USART, I2C, SPI, DSP, itd.
Dzięki podziałowi kodu na kilka plików:
- poruszanie się po kodzie i jego edycja jest łatwiejsza;
- tematyczne fragmenty kodu mogą być wykorzystywane w kolejnych projektach;
- możliwy jest podział realizacji dużego algorytmu na odrębne tematy i współpraca kilku programistów.

Poszczególne fragmenty kodu możemy łączyć dyrektywą #include w jeden program i kompilować całość. Takie rozwiązanie ma jednak jedną istotną wadę: cały kod musi być kompilowany przy każdej najmniejszej modyfikacji. Rozwiązaniem tej niedogodności są oddzielne moduły kodu które możemy kompilować niezależnie od innych fragmentów programu. Taki niezależny moduł zawiera wszystkie potrzebne elementy kodu: deklaracje zmiennych oraz kod funkcji do obsługi np. portu szeregowego.

Pliki nagłówkowe
Niezależnie skompilowane moduły muszą udostępniać sobie na wzajem pewien zestaw stałych, zmiennych oraz funkcji. Są jednak pewne lokalne zasoby, których muszą pozostać widoczne tylko wewnątrz danego modułu. Gdybyśmy wczytali kod modułu dyrektywą #include do głównego programu to mielibyśmy dostęp do wszystkiego co zawiera wczytany kod. Do rozwiązania tego zagadnienia służą plik nagłówkowe.

Plik nagłówkowy ( np. usart1.h dla modułu usart1.c ) musi zawierać te elementy, które mają być widoczne dla innych modułów. Jeśli jakiś moduł chce obsługiwać w swoim kodzie port USART1 to nie wczytuje źródła modułu usart1.c tylko wystarczy wczytać plik nagłówkowy usart1.h. Taki plik zawiera deklaracje (nie definicje) zmiennych i prototypy funkcji (nie ciało funkcji) z których będziemy mogli skorzystać w swoim kodzie. Zaletą oddzielnych modułów jest to, że możemy je kompilować niezależnie a po modyfikacji musimy kompilować tylko edytowany moduł co znacznie przyśpiesza kompilację całego kodu programu. Drugą zaletą jest to, że programista zajmujący się innym modułem nie musi mieć dostępu do kodu źródłowego innego modułu, wystarczy mu plik nagłówkowy i plik po kompilacji, resztę załatwi linker środowiska.

Uwagi do kodu z zadania nr. 2
Plik nagłówkowy usart1.h zawiera definicję bufora, którą moim zdaniem trzeba przenieść do kodu źródłowego modułu usart1.c bo to jest lokalna zmienna modułu usart1.c, którą będziemy udostępniali innym modułom.
Kod:
char usart_bufor_rx[bufor_size_rx];

W pliku nagłówkowym usart1.h musimy zamieścić deklarację
Kod:
extern char usart_bufor_rx[bufor_size_rx];

dla kompilatora i linkera, że jest taka zmiena zewnętrzna z której możemy korzystać a adres tej zmiennej zastanie dostarczony na etapie linkowania modułów.
Definicja bufora musi być w jednym miejscu ( plik usart1.c ) aby moduły wczytujące header usart1.h nie tworzyły własnych, lokalnych kopii bufora. Deklaracja extern zabezpiecza nas przed tym problemem.

Koledzy więcej aktywności i śmiałości. Dla mnie to też są nowe rzeczy, które staram się jakoś poukładać. Jeśli są jakieś nieścisłości lub braki w opisie proszę o korektę.

73 Adam
17-07-2016 11:46
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
Odpowiedz 


Wiadomości w tym wątku
RE: Programowanie ARM, nauka, środowiska programistyczne IDE - SP5FCS - 17-07-2016 11:46

Skocz do:


Użytkownicy przeglądający ten wątek: 2 gości