Začátečník s GCC - Jaký tutoriál?

Zdravím. Nechtělo se mi tu moc zakláat nový thread s podobným tématem jak tu jeden zrovna je, ale radši nový, abych v tom neměl zmatek. Doinstaloval jsem si WIN-AVR. V AVR studiu už mi jde založit nový projekt, ale nevím jak ho psát, co kde ještě případně donastavit, atd. Mohli byste mi prosím začátečníkovi s GCC doporučit nějaký tutoriál ?
S AVR začátečník nejsem, mám docela dost znalostí okolo programování v AVR-ASM, a programování ostatní taky nejsem začátečník. Tutioriál byhc prosil v Češtině, s Angličtinou problém nemám, ale nemám nějak náladu to “luštit”. Jde mi spíš jen o to, že z prvních pár lekcí “chytnu krok”, a pak už půjdu sám dál. Syntaxi C tak nějak znám z jiných podobných jakzyků (php,…) takže tu snad problém nebude.
Díky moc, Honza

Než tě někdo k nějakému dovede, tak tu máš pro začátek :wink:

Ovšem předem upozorňuju, že se syntaxí z PHP a Céčku podobných jazyků si určitě nevystačíš :wink: Pro potřeby mcu budeš potřebovat znát minimálně bitové operace, viditelnost proměnných (včetně globálních a jejich import/export), sestavení projektu z více souborů, preprocesor…

Taky bacha na optimalizace… Občas se stane, že program prostě nefunguje ikdyž by měl - překladač něco “odoptimalizuje”. V tom případě přidávej před podezřele se chovající proměnné “volatile”. To zamezí provedení optimalizace dané proměnné.
To píšu abys nezavrhnul C hned na začátku po prvním neúspěchu, který rozhodně přijde :wink:
tutorial_01.pdf (85.7 KB)

bitové operace - znám, jen si dohledám které omítka, svislá čárka dělá co, “viditelnost proměnných” znám z jiných prog. jazyků, sestvení projektu z více souborů - to sem dělal i v assembleru :stuck_out_tongue: (a nejen zde… třeba v pascalu,…), preprocesor - jestli myslíš direktivy jako IFDEF, IFNDEF, DEF a pdoobné věciřčky, tak znám. Jen prostě nevím, jak “mám přistupovat” k tomu C pro mikrokontroléry. ALe snad na to časem přijdu. A to Cčko rozhodně nezahodím… (zatím to nehodlám dělat)
díkes.
H.

Abych nezapomel - kdyz se budes chtit podivat na asm kod, kterej ten prekladac vypotil, tak v “Other files” je soubor s priponou “lss”. Muzes si tam taky porovnat ruzny programovy konstrukce a pripradne si vybrat tu rychlejsi.
GCC ma ve svy slozce manual, tam se da taky ledascos najit vcetne prikladu.

Na to je ale lepsi simulacny mod, kde sa da pozerat disasembler a po jednotlivych ASM instrukciach krokovat i program napisany v GCC.

Zas neco novyho :slight_smile: Moc hezke, je tam i popis tech instrukci, dik :smiley:

Tak jsem si včera hrál večer ještě s tím GCC… No byl to pro mě úspěch, když mě to asi na desátý nebo vícátý pokus zkompilovalo prázdný program (jen fce main).
Veš kole se u nás vyhazovaly nějaké věci ze staré PC pracovny, mezi nimi i učebnice programování a spol. SLušnou hromádku jsem si jich vzal, mezi nimi i učebnice jazyka C od Pavla Herouta… Ta učebnice se mě moc líbí, jelikož je tam vždycky porovnání s pascalem.
Taky jsem si na builder.cz našel tuten seriál: builder.cz/art/cpp/clanek485263989.html
Takže studuju několik zdrojů zároveň.
Ad podobnost PHP a C - no, podobné je to jen minimálně, ta syntaxe se trochu podobá, jinak je to úplně jiné… (PHP parser sežere téměř aždou blbost co tam vepíšeš, GCC a spol nee)
Na výsledný ASM kod bych se rád podíval, ale zatím potřebuju jen nějaké primitivní blbůstky, až to chytnu do krve, tak to se to pak bude programovat…

Mimochodem, jedna věc (vlastně dvě) co mě na Cčku štvou už teď: nemá to typ boolean (a kvůli tomu používat int který žere RAMku jako tatrman, to ne. To budu dělat asi stejně jao v ASM. Prostě si vyhradím jednu proměnou typu unsigned char (8bitů) a budu používat její jednotlivé bity. Používat však celou proměnnou jako jeden boolean mi příde dost neúsporné, i když to ve většině případů stačit bude.
Druhá věc, a to, že znaková konstanta třeba ‘k’ je typu int, a ne char, jen kvůli nějaké fci související s EOF, která vrací -1

bool tam neni, ale zas tech priznakovych promennych neni vetsinou potreba nijak velky mnozstvi, takze s unsigned char nebyva problem. Int je 16 bit, je dobry si predem rozmyslet jaky rozsah skutecne potrebujes :wink:

Takovy ty krasny veci jako prinf scanf a podobne tedy nepouzivam. zaplacnou 1/4 flash procesoru kuli tyhle funkci mi prijde skutecne zbytecny. Jeste se mi nestalo, ze bych se bez nich neobesel. Pro retezce lze normalne pouzivat char nebo uchar.

S tou syntací - ono i gcc je dost benevolentni, do ansi C ma hodne daleko…

Zo zaciatku som tiez setril pamatou.

priklad:

//...

#define VYSOKA_TEPLOTA 0
#define NIZKA_TEPLOTA 1
#define ZAPNI_RELE 2
#define JE_NIEKTO_DOMA 3

// GCC (a urcite i ine prekladace) tieto makra prelozia do ASM velmi efektivne

#define SET(BYTE, BIT) (BYTE |=(1<<BIT))
#define RES(BYTE, BIT) (BYTE &=~(1<<BIT))
#define TST(BYTE, BIT) (BYTE & (1<<BIT))


int main(void)
{
uint8_t priznaky = 0;

 // .... cista ilustracka :-)

   if (teplota >= ZELANA_TEPLOTA) SET(priznaky,VYSOKA_TEPLOTA);
   else RES(priznaky,VYSOKA_TEPLOTA);

   if (teplota < TEMPEROVACIA_TEPLOTA) SET(priznaky,NIZKA_TEPLOTA);
   else RES(priznaky,NIZKA_TEPLOTA);

   if TST(priznaky,VYSOKA_TEPLOTA) RES(priznaky,ZAPNI_RELE);
   else if (TST(priznaky,NIZKA_TEPLOTA) && TST(priznaky,JE_NIEKTO_DOMA)
   {
        SET(priznaky,ZAPNI_RELE);
   }
  
// ...

}

lenze po case som usudil, ze ak je dost pamate tak je program kratsi/rychlejsi (ale aj tak sa 95% casu skrabe diodou v rozkroku :slight_smile: ), ak porovnava iba jeden bajt na hodnotu a hlavne je okolo toho menej pisaciek.

Aj vy pri programovani najcastejsie pouzivate kombinaciu klaves Ctrl+C a Ctrl+V ?

Takze zvacsa pouzivam


#define TRUE 0xff
#define FALSE 0x00


#define HYSTERZIA 20 // v desatinach stupna

int main(void)
uint8_t vysoka_teplota = FALSE;
int16_t skutocna_teplota, zelana_teplota; // v desatinach stupna

//...

   if (skutocna_teplota > zelana_teplota) vysoka_teplota = TRUE;
   if (skutocna_teplota < (zelana_teplota - HYSTERZIA)) vysoka_teplota = FALSE;

//...
   
   if (vysoka_teplota) fn_zapni_kotol();

//...

Potom je este jedna moznost definicie booleanu cez bitove pole. Ale vsetky tieto konstrukcie vedu k vacsiemu programu.

piityy: jo máš recht, int je 16bitový (2B). Ale sakra pak jaký rozdíl je mezi int a short int? Dyť je ot to samý!
builder.cz/art/cpp/clanek1666892044.html

To zalezi vzdy na prekladaci… ve win32 je standardne int 32bit, short 16bit a long 64bit. Tady v GCC je short a int shodne, az long je 32bit.
V zasade plati short <= int <= long. Konkretni rozsah datovyho typu si musis vzdy najit v dokumentaci prekladace (a nebo si to proste zkusit, coz byva rychlejsi :wink:).
Tu najdes treba v instalacni slozce (u me konkretne “C:\Program Files\WinAVR-20090313\doc\avr-libc\avr-libc-user-manual.pdf”);
Pokud pouzijes zapis jako “uint8_t”, tak vis hned na cem jsi :wink: Akorat mas smulu, ze ti to IDE nezvyrazni, protoze to neni klicove slovo, ale je to vytvoreno pomoci TYPEDEF…

V tom pdfku lze najit toto:
//================
typedef signed char int8_t
typedef unsigned char uint8_t
typedef signed int int16_t
typedef unsigned int uint16_t
typedef signed long int int32_t
typedef unsigned long int uint32_t
typedef signed long long int int64_t
typedef unsigned long long int uint64_t
//================

Zatim sem nic krom nekonečného cyklu nezprogramoval, ale docela mě už deptá tohle: program jen s nekonečnou smyčkou, a vono už to má tolikle:
Program: 62 bytes (0.8% Full)

Mimochodem, proč musí míát fce main návratovou hodnotu typu int - k čemu je ta hodnota dobrá?

tady v mcu neni dobra k nicemu :slight_smile:
muzes to napsat jako “void main(void){}”, akorat se cas od casu stane, ze hodi prekladac varovani, ze navratova hodnota main neni int… Tohle 1 varovani kdyz se vyskytne (obcas je, obcas ne…) muzes s klidnym svedomim ignorovat. Ostatni ale dusledne cti, nekdy se stane, ze zapomenes vlozit hlavickovej soubor a on to stejne prelozi ovsem jen s varovanim…

Tech par bajtu je rezije Ccka, s tim nic neudelas, to tam bude vzdy.

Jo, já jen že do 62 bajtů se toho v asm dalo naprogramovat docela hafo…

Přesně tak, na void main () mi to hlásí přesně ten warning jak říkáš. Ale nechápu čim to je. To je jedno. Až zprogramuju něo zajmavějšího, dám vědět…

Ci je

int main(void)

alebo

void main(void)

na kod nema nejaky vplyv.
Ten zaklad C-cko jednoducho potrebuje. Preco, to by som neriesil. Mozes sa rozculovat, na co vsetko si v ASM zvyknuty a co je v C inak. Ale to C za tu cenu bude (skoro - samotne C-cko urcite, ale tie ostatne #define a niektore funkcie) rovnake ci robis na AVR, ARM7, Cortex, alebo PC

Nad C-ckom nema zmysel uvazovat ak mas 1kB Flash a 64B RAM.
Na druhej strane zapis

if (teplota > 21.6) {
fn_zapni_klimatizaciu();
fn_vypni_kurenie();
}

if (teplota < 18.2) {
fn_vypni_klimatizaciu();
fn_zapni_kurenie();
}

je daleko zrozumitelnejsi, udrziavatelnejsi a prenositelnejsi ako haky-baky v ASM. A to uz nehovorim o prenose na inu platformu (aj ked to nemusi byt casta potreba). A cena za to je napriklad i tych 62B zdanlivo navyse :slight_smile:
(a vela dalsich veci navyse)
V zasade mozes pocitat s cca 1.5-2x vacsim a 1.5-2x pomalsim kodom.
Ale fakt sa to oplati. Neveril som, odskusal som a nemenil by som. :slight_smile:
Aj ked niektore ulohy riesim v ASM. Hlavne tie napriklad na ATtiny13, alebo ATtiny10.
Kolega programoval jednoduchy protokol v ASM na ATtiny13 cez I2C rozhranie. Vysledok bol 584B.
Mne to iste v C (GCC) na ATtiny13 vyvstalo na 828B a asi o polovicu pomalsie.

Martine, nejsem v programování žádný začátečník, už mám praxi asi 5 let programování (začínal jsem v 11ti letech s pascalem). Jde spíš o to, že jsem ještě nikdy nenačuchnul k jazyku co se hodně podobá ANSI C. Já si zatim nestěžuju, jen dávám najetvoi to, co je pro mne nové, a zatím nepochopitelné. Třeba to časem pochopím.
Do 1kB procesůrků nemá snad ai smysl o C uvažovat. S C jsem začal především kvůli tomu, že jsem se chtěl dostat k programování nějakých větších procíků, ako ATmega128 a dojít až na ARM. navíc asm zas není moc vhodné na delší programy, ale na klasické aplikace stylu “blikání LEDkama” si myslím že to stačí.
Ale protsě ASM už zvládám velmi slušně, tak jsem chtěl něco pohodlnějšího. PRostě beru to vešechno postupně. Příjde mi výhodnější nejprve se naučit AVRASM, a až pak GCC, než obráceně.

Tak… už jsme do sebe trochu toho Cčka dostal. Nyní bych si rád zablikal LEDkou… (klasika).
Existuje v tom GCC nějaká funkce, do které zadám čas/počet tiků hodiny, který se má MCU pozdržet? Něco jako “delay”.
Úplně ideální by asi byla funkce, do které byhc nacpal poet tiků hodin, abych si mohl vytvářet zpoždění od pár us až po sekundy. Jak se dá tohle v tom GCC udělat?
Díkes, H.

zkus v tom manualu gcc najit “delay()”. Urcite to v nejakym hlavickoym souboru je. Ale casy jsou v ms. Na us si budes muset uplacat neco svyho (nejakej ten cyklus s promennou s prefixem volatile a v simulatoru si to zmerit).

edit:
Tak je tam i fce na us… str.283 <util/delay.h>

util delay jsme našel. Už to i zkouším… ale jen “tak”, hardware nemůlžu programovat, zdechnul mi zdroj k notebuku.
Jen jsem po tom přečtení popisu znejistěl…
void _delay_ms ( double __ms )

Perform a delay of __ms milliseconds, using _delay_loop_2().

The macro F_CPU is supposed to be defined to a constant defining the CPU clock frequency (in Hertz).

The maximal possible delay is 262.14 ms / F_CPU in MHz.

When the user request delay which exceed the maximum possible one, _delay_ms() provides a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of 1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency). The user will not be informed about decreased resolution.

Tak dá se s tim udělat čekání víc jak 200ms nebo ne? Nějak mě s tim docela zamotali palici…

snad jo, pokud prekrocis tu max. dobu, mela by se ta funkce “prepnout” do druhyho rezimu, kdy jde delat tech 6s