Portar, Atmel 32-bit CORTEX

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Portar, Atmel 32-bit CORTEX

Inlägg av bearing »

Köpte detta utvecklingskort:
http://www.atmel.com/tools/ATSAMD10-XMI ... b=overview

Laddade hem nya Atmel Studio 7, och tog fram exemplet som blinkar en lysdiod:

Kod: Markera allt

void SysTick_Handler(void)
{
  port_pin_toggle_output_level(LED_0_PIN);
}

/** Configure LED0, turn it off*/
static void config_led(void)
{
  struct port_config pin_conf;
  port_get_config_defaults(&pin_conf);

  pin_conf.direction  = PORT_PIN_DIR_OUTPUT;
  port_pin_set_config(LED_0_PIN, &pin_conf);
  port_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE);
}

int main(void)
{
  system_init();

  /*Configure system tick to generate periodic interrupts */
  SysTick_Config(system_gclk_gen_get_hz(GCLK_GENERATOR_0)/1000);

  config_led();

  while (true)
  {
    
  }
}
När jag klickar mig runt bland koden/funktionerna som hanterar porten/pinnarna, hamnar jag i djup djungel av structar och funktioner i många många lager.

Sånt här gör mig nästan förtvivlad. Jag vill bara sätta några bitar i port, inte skicka upp en raket till månen.

Är det såhär det är tänkt att man ska jobba med sådana här processorer?

Känns ju som att det blir ett enormt overhead, för något som på gamla 8-bit-tiden tog en instruktion.
Möjligtvis kommer kompilatorn optimera bort (gissar) 5 fem anropsnivåer och (gissar) 100 rader kod, för att toggla pinnen. Så att det i slutändan blir den där enkla instruktionen. Men jag tvivlar. Tror det blir 10 instruktioner, minst. Sånt här får mig verkligen att tappa kraften i fingrarna. Jag undrar vad jag gett mig in på, och varför i hela friden sånt här är nödvändigt. Jag vill ju ha koll på allt i mitt program. Jag brukar inte ens använda enkla libs när jag programmerar, utan jag skriver hela programmen själv. Så gör vi på jobbet också. Skriver allt själva.

Den här tröskeln var verkligen mycket högre än vad jag hade väntat mig. När Atmel Studio 7 dessutom är otroligt slött, och tar upp 1GB minne, då känner jag att jag nästan vill spy.

Nu sitter jag med ett helt nytt projekt, som är så rent som möjligt (dock är ändå största delen av interrupttabellen redan ifylld...), och inser att jag inte kan lista ut hur jag skriver till porten ens (direkt).
Hör gör jag det?
Känner mig helt maktlös här.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Portar, Atmel 32-bit CORTEX

Inlägg av Icecap »

Den programbit är helt klart för Atmel's system. De har skapad strukturer som gör det "enkelt" att ha olika versioner av µC'n - men det är ganska säkert ett helvete att börja nysta i.

Mitt förslag: ta fram databladet, leta rätt på vilka namn registerna har där och testa att använda de namn.

Någonstans lär det rimligt säkert finnas en .H-fil som definierar registerna för den specifika µC, där står namnen.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Portar, Atmel 32-bit CORTEX

Inlägg av sodjan »

Tröskel? :-) Koden som du visar är ju ganska enkel.
Det är väl meningen att man inte ska bry sig om vad
som finns "där bakom"...

Det där med "LED_0..." är väl något som är specifikt
för labb-kortet. Det syns inte i ditt kodexempel, men
det bör väl laddas några definitioner som hör till just
det kortet.

Sen så kan jag kanske tycka att det är mer logiskt att
köra config_led() *innan* man startar timern, men det
är ju en lite annan fråga... :-)
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Portar, Atmel 32-bit CORTEX

Inlägg av bearing »

Ja, exemplet är ju enkelt att förstå.
Och det går nog rätt fort att "ful-koda" ihop något som funkar. Ska läsa en sensor och skriva ut info på en display. Tar nog inte många timmar.

Med tröskel syftar jag på förståelse på djupet. Jag vill inte släppa ett program där där 90% "sker bakom kulisserna", d.v.s som jag till största delen inte har någon koll på. Listan över "dependencies" är typ 30 filer lång. Jag kan ju inte ansvara för att allt i dom filerna stämmer.

Ja, LED_0 är definierat i en H-fil som hör till den aktuella hårdvaran (utvecklingskortet).

Icecap:
Om man skriver variabelnamnet OUT i editorn, som är motsvarigheten för typ PORTB i gamla 8-bitare, får texten en annan färg. Men det blir kompileringsfel om man försöker sätta OUT till ett värde. Tror OUT bara är en i mängden av struktar, som sitter i en annan strukt, som heter typ PORT.
Senast redigerad av bearing 11 november 2015, 19:33:32, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Portar, Atmel 32-bit CORTEX

Inlägg av sodjan »

Jag kan skriva en Cobol program till OpenVMS utan att veta ett smack
om vad varken kompilatorn eller OpenVMS gör "bakom kulisserna".
Thats life...
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Portar, Atmel 32-bit CORTEX

Inlägg av bearing »

Okej, jag kan avslöja lite mer då.

Har varit intresserad av Cortex en längre tid, och när det visade sig att även min kollega var intresserad, samt att den här processorn kostar mindre än en tia, d.v.s mindre än de 8- och 16-bitare vi vanligtvis använder, föreslog jag att vi skulle använda denna i ett enkelt kundprojekt på jobbet. Jag hade dessutom erfarenhet av Atmel Studio, så det borde gå enkelt att komma igång, tänkte jag.

På mitt jobb har vi en policy att programmen endast ska innehålla kod skriven av oss själva (för att kunna uppfylla vissa normer / säkerhetskrav). Det kan gå att göra undantag för t.ex. initiering på låg nivå i kod som körs innan main. Men hittills har vi skrivit även den koden själva på både 8, 16, och (en annan, stor) 32-bitare. På den senare tog det mig månader (utspridd arbetstid) att skriva den där initieringskoden. Därför tänkte jag strunta i det den här gången. Men när det då visade sig att bara enklaste I/O också var ett stort lib, d.v.s jag får inte använda det, då gick luften ur mig, kan man säga. Jag har nämligen redan angett vilken tid det här projektet ska ta, och det blir svårt nu.

Så nu lutar det faktiskt åt att strunta i den här processorn, och köra vidare på en gammal 8-bitare. Men någon gång (snart, med tanke på prisbild samt "end of life"-bekymmer) måste vi ju göra övergången. Och det här enkla projektet kändes lämpligt, åtminstone igår.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Portar, Atmel 32-bit CORTEX

Inlägg av Icecap »

Hmmm - känner igen det där - fast från anda sidan. Jag designade ett "universellt" styrkort med tanke på vad vi har av erfarenhet från tidigare projekt osv.

Jag valde en Renesas RX210 (klarar 5V, 32 bit, 50MHz, massor med perifergrejer) och tänkte att det var det rätta.

Och jo, den klarar jobbet ganska bra! Men vilket he...... jag hade med att få gång i det hela! Det har tagit mig väldigt med timmar, en hel del huvudbry och än fler svordomar innan jag kom hit vi är i dag.

Det finns säkerhetsregister som ska skrivas till med specifika värden i specifik orden innan man kan skriva till andra register, sedan ska man "stänga" efter sig osv.

Att initiera en seriell port tar 69 rader C-kod (ingen "tomma" rader!), då är hårdvaran slagit på (strömsparaläget upphävd för den serieport), portpinnarnas alternativa funktion är ställd till att vara seriell port är ställd i rätt läge - efter att ha öppnat säkerhetsregister för detta - rätt prescaler för baudrate är vald, baudrate register är ställd, interrupts är aktiverat, buffer-variabler är initierat, pinnarna är växlad till deras alternativa funktion och interrupt-nivån ställd.

Numera har jag ett antal filer som jag inkluderar i projekt efter behov, då har jag full tillgång till de funktioner jag behöver. Inkluderar jag hårdvara-filen kallar jag Start_Hardware(), då ställs alla portar i rätt läge, den interna oscillator slår på i den valda frekvens (ska definieras innan vid att "projekt-definiera" USE_HOCOxxMHZ"), en kod kopieras till ett minnesarea (för att kunde skriva till egen FLASH/EEPROM).

Jag kan numera slå på funktioner vid att t.ex. "projekt-definiera" USE_RS232_A, då aktiveras interrupt-service-rutinerna (ISR) i vektortabellen osv.

Jag har färdiga rutiner för att räkna på RTC-data, läsa och skriva från/till EEPROM & RTC på I²C-bussen osv. Jag har en färdig rutin för att läsa 1-Wire via interrupt-styrning osv.

Men det har varit ett helvetets slit! Först få funktionen till att fungera, det kan i sig vara intressant (not in a good way), sitta med 1600+ sidors datablad och lusläsa och Renesas är inte speciellt bra på att skriva logiska datablad, de är dock bättre än Atmel men Microchip är ju stjärnan.

Det har varit ett drygt år med detta - men numera skapar jag projekt snabbt och enkelt.

Jag har just monterat ett display som ska kommunicera med en solpanel-inverter och skryta till omvärlden med hur mycket som är hämtat.

Detta innebär styrning av LED-moduler, inställning av parameter i EEPROM, automatisk ljusintensitetsreglering samt kommunikation med RS485 till invertern. Självklart måste jag kunde snacka med båda RS232 serieportar för kommandon och debug, A/D-omvandlaren ska startas för att styra intensiteten osv.

Projektet innehåller 22 st källkodsfiler - men bara 5 st i själva projekt-biblioteket, resten är mina "standard-filer". Jag har räknat med vissa .H-filer som är essentiella, resten har jag bortsett ifrån i dessa tal.

Att skapa projektet tog kanske 2 minuter inkl. definitionerna som aktiverade de rätta funktioner. Sedan var det en fråga om att skriva programmet och initieringsdelarna var ju nästan klara: serieportar, systemtimer, PWM (Intensitet) på rätt pinne, starta A/D-omvandlare osv.

NU är det enkelt - men jag har nog lagt det mesta av 1,5 år på att komma hit!

Alla exempel till deras starter-kit jag hoppades på att nasa på innebär ett RTOS - så det kunde jag ju glömma. Jag har suttit en hel del med den processor-register-definitions-fil jag har ("RX200.h") och gått igenom den för att se hur F.. de har tänkt sig att man ska skriva till den DJÄ... port.

Det visade sig att det inte var enkelt men till slut insåg jag att det var typ "SYSTEM.Pxx.BIT.yy" eller "SYSTEM.PRCR.WORD", "MSTP(MTU)", "MTU0.TCR.BYTE" osv.

Självklart var det även ett register som inte var definierat i den filen men som fanns i verkligheten, alltså fick jag skriva in detta register. Och då definitionsfilen har två delar (Little Endian & Big Endian) fick jag göra detta två gångar i samma fil.

Men nu - där jag har avklarat det mesta av dessa svårigheter - är det ju enkelt ;-)

Så jag förstår ditt tänk! Men hur man än gör är starten svår! Har man funktionerna klara och i grunden bara behöver knyta ihop dom med hårdvaran är det inte så illa men ska man skapa allt från grunden blir det tungt.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Portar, Atmel 32-bit CORTEX

Inlägg av lillahuset »

Jaja, så märkvärdigt är det väl ändå inte.
Jag är insyltad i flera projekt med STM32Fxxx som jag misstänker liknar Atmels Cortex ganska mycket. Jag tror dessutom att STs bibliotek är ungefär lika kassa som Atmels. Vår policy är att läsa referensmanualen och snegla i STs bibliotek och skriva allt utom möjligen initieringskoden själva. Principen är att leverantörens bibliotek suger kungligt men kan ge en viss inblick i hårdvaran.
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Portar, Atmel 32-bit CORTEX

Inlägg av bearing »

På den andra 32-bitaren var också alla register definierade som struktar. Men på ett annat sätt, där det hela sedan var mappat direkt till minnet. Om det är gjort på det viset har jag inget emot det. Bättre än när registrena bara är defines.

Men om man ska behöva anropa funktioner för att sätta I/O, då tycker jag att det börjar kännas som att koden ligger för långt ifrån hårdvaran. Känns riktigt obehagligt. :D

Får väl ta en titt imorgon igen. Men om det inte ger sig, får det blir en riktigt gammal och kodineffektiv 8-bitare, som sitter i äldre produkter.
Användarvisningsbild
adent
Inlägg: 4245
Blev medlem: 27 november 2008, 22:56:23
Ort: Utanför Jönköping
Kontakt:

Re: Portar, Atmel 32-bit CORTEX

Inlägg av adent »

Jag känner igen det här, det är tyvärr detta som bromsat mig från att ta steget bort från AVR:er på hobbynivån.
Men jag skulle vilja stega upp. En vacker dag får jag bita i det sura äpplet.

MVH: Mikael
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Portar, Atmel 32-bit CORTEX

Inlägg av lillahuset »

Det är inte surt. :D
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Portar, Atmel 32-bit CORTEX

Inlägg av bearing »

Nu har jag hajat det här. Skapade en variabel som heter PortA. Sen kan jag skriva direkt till önskade port-register. Här är variabeln global, för att jag ska känna mig mer hemma. Men det går så klart lika bra att definiera den lokalt där den ska användas. Var ju inte så svårt detta, trots allt. Ganska likt den andra 32-bitarn jag jobbat med.

Kod: Markera allt

PortGroup *const PortA = &(PORT->Group[0]);
void SysTick_Handler(void)
{
  //port_pin_toggle_output_level(LED_0_PIN);
  PortA->OUTTGL.reg = 1 << LED_0_PIN;
}
Sen jämförde jag kodstorleken, och kom att tänka på det jag skrev igår:
bearing skrev:Möjligtvis kommer kompilatorn optimera bort (gissar) 5 fem anropsnivåer och (gissar) 100 rader kod, för att toggla pinnen. Så att det i slutändan blir den där enkla instruktionen. Men jag tvivlar. Tror det blir 10 instruktioner, minst.
Där hade jag fel. Storleken på programmet ändrades inte. Smart optimering i kompilatorerna numera!
Utan optimering är det tre funktionsanrop, och en del kod. Se nedan:

Kod: Markera allt

static inline void port_pin_toggle_output_level(
		const uint8_t gpio_pin)
{
	PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
	uint32_t pin_mask  = (1UL << (gpio_pin % 32));

	/* Toggle pin output level */
	port_base->OUTTGL.reg = pin_mask;
}

static inline PortGroup* port_get_group_from_gpio_pin(
		const uint8_t gpio_pin)
{
	return system_pinmux_get_group_from_gpio_pin(gpio_pin);
}


static inline PortGroup* system_pinmux_get_group_from_gpio_pin(
		const uint8_t gpio_pin)
{
	uint8_t port_index  = (gpio_pin / 128);
	uint8_t group_index = (gpio_pin / 32);

	/* Array of available ports */
	Port *const ports[PORT_INST_NUM] = PORT_INSTS;

	if (port_index < PORT_INST_NUM) {
		return &(ports[port_index]->Group[group_index]);
	} else {
		Assert(false);
		return NULL;
	}
}
Men jag gissar att om man istället för en konstant använder en variabel, blir det annorlunda, för då är det ju inte känt vid kompilering vilken pinne som ska togglas, och därför behöver alla funktioner anropas.
Och det visade också mitt test:

Kod: Markera allt

PortGroup *const PortA = &(PORT->Group[0]);

static volatile uint32_t led0     = 1 << LED_0_PIN;
static volatile uint8_t  led0_pin = LED_0_PIN;

#define fall 5

void SysTick_Handler(void)
{ 
  #if fall == 1
  PortA->OUTTGL.reg = 1 << LED_0_PIN;       //Program Memory Usage 	:	2576 bytes
  #elif fall == 2
  PortA->OUTTGL.reg = led0;                 //Program Memory Usage 	:	2584 bytes
  #elif fall == 3
  PortA->OUTTGL.reg = 1 << led0_pin;        //Program Memory Usage 	:	2588 bytes
  #elif fall == 4
  port_pin_toggle_output_level(LED_0_PIN);  //Program Memory Usage 	:	2576 bytes
  #elif fall == 5
  port_pin_toggle_output_level(led0_pin);   //Program Memory Usage 	:	2604 bytes
  #endif
}
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Portar, Atmel 32-bit CORTEX

Inlägg av lillahuset »

Många kompilatorer är bra på att optimera.

För drygt fem år sedan skrev jag en väldigt tidskritisk interruptrutin för Cortex-M3 i assembler. Jag fick till den på 14 instruktioner och var ganska mallig. Sedan tänkte jag att jag skulle se vad GCC kunde åstadkomma. 12 instruktioner. När jag läste koden fattade jag precis vad GCC gjorde och varför. Lätt stukad insåg jag att jag inte behärskade alla detaljer i arkitekturen. Sedan dess börjar jag aldrig att skriva ens en liten interruptrutin i assembler utan att först låta GCC visa vad den kan. Det har inte blivit så mycket assembler sedan dess.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Portar, Atmel 32-bit CORTEX

Inlägg av Icecap »

Kompilers nu för tiden är verkligen effektiva.

Tyvärr kan det medföra konstiga saker som att vissa delar blir optimerat bort.

Jag hade problem med en 1-Wire rutin som ju skulle hålla ett visst delay. Det hade fungerat perfekt tidigare men i det nya projekt - som delar 1-Wire filen med andra fungerande projekt - fungerade INTE! Efter att ha mätt med oscilloskopet insåg jag att det var timingen som var fel och i desperation ändrade jag variabeln som den använde som delay (for(;;)) till volatile - och *POOF*, det fungerade igen, även med den optimering som är vald som standard.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Portar, Atmel 32-bit CORTEX

Inlägg av lillahuset »

Man ska inte underskatta "volatile". Betyder ungefär "ge fan i den här variabeln för den vet du för lite om". :D
Skriv svar