IAR C AVR - kompilovanie funkcie na absolútnu adresu

C,C++,C#

Moderátori: psichac, Moderátori

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa peterple » 25 Jún 2013, 22:23

Ahojte borci,
poradte prosím starému assembleristovi ako prinútit C kompilátor aby funkciu skompiloval na presnú požadovanú adresu. Ideálne pre AVR architektúru a IAR compilátor.

Background problému:
pred dvoma týždňami som nainštaloval IAR copilátor s cieľom rozchodiť AES bootloader od atmelu. Po nejakom čase som dospel k funkčnému riešeniu. Môj problém spočíva v tom že nechcem aby sa bootloader aktivoval stlačením tlačítka pri zapnutí, ale aby si ho mohla zavolať aplikácia. Na to potrebujem aby funkcia loadera bola na pevnej adrese. Bootloader a aplikácia sú totiž dve nezávislé veci a potrebujem aby výkonná rutina bootloadera bola vždy na tom istom mieste, aby sa ľubovolná verzia aplikácie aj bootloadera našla.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

kubri
Stály člen
Stály člen
Príspevky: 159
Dátum registrácie: 27 Aug 2012, 14:00
Bydlisko: Bánovce n/B
Vek: 41

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa kubri » 26 Jún 2013, 00:30

Ahoj, stretol som sa s takym riesenim, ze aplikacia bol jeden samostatny hex a bootloader druhy samostatny hex subor (akoby sa spravili 2 samostatne programy). V Hex editore sa to da do jedneho - bootloader sa posunie na prislusnu adresu. V aplikaci sa potom spusti bootloader tak, ze sa ulozi zaciatok adresy bootloadera do SP a zavola sa ret. Ak je vyuzivane prerusenie, treba nastavit vektory prerusenia na bootloader. Presun z bootloadera do aplikacie je podobny.
0

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 26 Jún 2013, 10:48

Tiez riesim bootloader :--)

1.
void funkcia(void) __attribute__((section(".ARM.__at_0x10000")));

( odskusane pod Keil )

2.
vytvorit samostatny modul ( zdrojak v C ) a v jeho vlastnostiach zadat oblast kde sa ma ulozit.

{ odskusanie pod Keil )

3. niekde som nasiel prikaz pre linker ( tusim CODE:0x000000 ) ak najdem, upresnim.
0
Naposledy upravil/-a xmilos v 26 Jún 2013, 11:03, upravené celkom 1 krát.

anonymousCoward
Stály člen
Stály člen
Príspevky: 150
Dátum registrácie: 12 Máj 2013, 11:09
Bydlisko: KE

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa anonymousCoward » 26 Jún 2013, 10:57

Zdar,

S IAR skusenosti nemam, ale google hovori ze je mozne umiestnit premennu /funkciu na konkretnu adresu: http://supp.iar.com/Support/?note=27498 a http://supp.iar.com/Support/?note=36121.

Ad xmilos: myslim ze toto je GCC specificky atribut - ale mozem sa mylit :)

Najjednoduchsie, a 'najspravnejsie' riesenie je IMHO zavolat bootloader vtedy ked sa volat ma t.j. po resete - v Tvojom pripade, az sa aplikacia rozhodne ze je spravny cas, nastavi watchdog a pojde do nekonecneho cyklu. Pokial teda nemas iny dovod preco toto riesenie nevyhovuje.
0
War is peace. Freedom is slavery. Ignorance is strength.
There is no such thing as a well-adjusted slave.

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 26 Jún 2013, 11:09

A tak, az terazky som si vsimol, ze sa bavime o IAR kompilatore .
Oki, ten nepoznam...

Dalsia moznost obchadzajuca rozne verize kompilatorov je pouzit pevne umiestnenu premennu typu pointer na adresu funkcie a skocit na nu ( na adresu umiestnenu na konkretnom mieste )
0

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 26 Jún 2013, 12:00

anonymousCoward napísal:Najjednoduchsie, a 'najspravnejsie' riesenie je IMHO zavolat bootloader vtedy ked sa volat ma t.j. po resete - v Tvojom pripade, az sa aplikacia rozhodne ze je spravny cas, nastavi watchdog a pojde do nekonecneho cyklu. Pokial teda nemas iny dovod preco toto riesenie nevyhovuje.
oki, ale skok na absolutnu adresu potrebujes tak ci tak. "Nieco" po resete musi skocit bud do loadera, alebo aplikacie. Ak to "nieco " je sucastou loadera, po teste musi vediet skocit na absolutnu adresu aplikacie.
0

anonymousCoward
Stály člen
Stály člen
Príspevky: 150
Dátum registrácie: 12 Máj 2013, 11:09
Bydlisko: KE

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa anonymousCoward » 26 Jún 2013, 12:42

Pozri AVR231 z http://www.atmel.com/Images/doc2589.pdf‎ , stranu 20 - podla diagramu sa po resete zistuje ci je 'switch SW7 pressed', a ak ano tak sa vykona bootloader; po jeho skonceni sa skace do aplikacie (ak je vsetko OK).
AES bootloader som zatial nepotreboval, a neviem ci OP pouziva postup popisany v appnote AVR231 - iny som zatial nenasiel. Ak ano, pre uistenie pozrime kod k appnote ( rar z http://www.avrfreaks.net/index.php?func ... ks%20Tools), subor IAR/bootldr.c :

Kód: Vybrať všetko

__C_task void main(void)
{
	__disable_interrupt();
	busInit();

	// Loop forever (loops only if Application Section is damaged)
	for (;;)
	{
		// Key pressed? Yes -> run the loader routine
		if (!(PIND & (1 << PD2)))
			// Typecast the function to a not-__C_TASK function (__C_TASK is
			// defined just to remove some unneeded register storing from the
			// loader() function)
			((void (*)())loader)();	
		else
	
		#ifdef CRC_CHECK
		// Check that the Application Section contents is undamaged
		// by calculating the CRC of the whole memory.
		{
			unsigned int crc = 0;
			unsigned char APPFLASH *p = (unsigned char APPFLASH *)0x000000;
			unsigned char APPFLASH *n = (unsigned char APPFLASH *)MEM_SIZE;
	
			do
			{
				crc = CRC(crc, *p++);
			}
			while (--n);
	
			// Application Section damaged
			//   -> do not jump to Reset Vector of the Application Section
			if (crc) {
				DDRB = 0xff;
				do {
					PORTB ^= 0xff;
					__delay_cycles( 1000000 );
				} while(1);
//				continue;
			}
		}
		#endif
		
		((void (*)())0x0000)();
	}
}
Asi to komentovat netreba, ale zda sa ze appnote neklame ( az na PD2 namiesto PD7 ~ SW7 na STK500, ale nevadi :) ) - cize, nemyslim ze bude problem so spustenim bootloadera, a ani so skakanim do aplikacie po jeho dobehnuti, za predpokladu ze OP nepokazi nastavovanie poistiek.

Samozrejme, este vzdy je mozne zavolat bootloader z aplikacie priamo, ci uz cez exportovany loader(), alebo cez asm("jmp 0x3000"), (adresu uz podla datasheetu) - ale este stale tvrdim ze je lepsi napad spustit bootloader po resete, a tiez tvrdim ze bootloader a applikacia by mali byt cim viac oddelene, podla hesla 'bootloader skompilujem a nahram len raz'.
0

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 26 Jún 2013, 12:53

Mozna sa nerozumieme, po dalsom resete musis skocit na absolutnu adresu, resp po skonceni boot loaderu.
Nepolemizijem kam skocit po resete, kedy spustat bootloader, ale potrebujes vediet skakat na konkretnu adresu, zaroven presne stanoveny "zaciatok" aplikacie - miesto kam skocit - to chcel vediet
0

anonymousCoward
Stály člen
Stály člen
Príspevky: 150
Dátum registrácie: 12 Máj 2013, 11:09
Bydlisko: KE

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa anonymousCoward » 26 Jún 2013, 13:16

Zaciatok aplikacie je na adrese 0 (aspon u vacsiny, ak nie vsetkych, AVR). Bootloader zacina na inej adrese (toto sa lisi podla modelu), v regione flash oznaceneho ako BOOTLOADER_SECTION, ktoreho hlavna vlastnost je to, ze je NRWW (No Read While Write), cize je v nom mozne pouzivat instrukcie SPM pre programovanie RWW regionov flashu t.j. tych kde je aplikacia.

To, ci sa po resete zacne vykonavat aplikacia (t.j. zacne sa od adresy 0), alebo bootloader (adresa 0x1800, 0x1300 ... whatever) zavisi od nastavenia poistky BOOTRST. Ak bude BOOTRST naprogramovana (cize 0), tak sa po resete skoci do bootloadera. Ten zisti ci ma data na preflashovanie, a ak ano preflashuje. Ak nie, resp. po dokonceni preflashovania (a ak je CRC OK), skoci na adresu 0 t.j. zacne sa vykonavat aplikacia.
0
War is peace. Freedom is slavery. Ignorance is strength.
There is no such thing as a well-adjusted slave.

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 26 Jún 2013, 13:23

Tak to dava zmysel.
Zial u procesora, pre ktory riesim loader nie je tato moznost, aspon som ju zatial nenasiel. Je moznost rozdelit pamat na dve az 4 bunky a skakat do nich podla aktualnosti tej ktorej verzie. Horsie je, ze ani oblast vektorov sa neda presunut.

Oki, to je ale iny HW, nez sa dotycny pyta, takze tak trochu O.T.
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa peterple » 26 Jún 2013, 21:32

Ahojte,
ďakujem všetkým za odpovede. Problém je vyriešený takou okľukou zdola. Trochu viac popíšem situáciu na ozrejmenie.
Požívam riešenie že bootloader je samostatný hex ktorý sa napáli do BOOTLOADER_SECTION a BOOTRST je naprogramovaná takže sa po resete spúšťa program z adresy 0xF000. Tam sa skontroľuje CRC aplikačnej časti FLASH a ak je chybné volá sa funcia loader(), ktorá počká na upgrade aplikácie. Inak sa štartuje aplikácia ktorá je ale komplet samostatná a nie je ani kompilovaná IAR kompilátorom. V žiadnom prípade ich nechcem dávať dohromady nejako pokútne v hex editori. Jedna z funkcií aplikácie je upgrade firmware. AVR je batériová aplikácia ktorá sa používa v teréne, takže sa sama nepozerá po upgradoch. Ovláda sa cez bluetooth z telefónu (android aplikácia). Tiež tam ale nemusí byť internetová konektivita. Doteraz som mal riešenie že do telefónu stiahnem, nahram hex súbor aplikácie, aktivujem cez bluetooth bootloader a pošlem nový obsah aplikačnej pamäte. Slabé miesto je to že sa ktokoľvek dostane k hexu. Či už na webe alebo v telefóne. Ak by som to aj šifroval tak to odchytí pri nahrávaní z telefónu do AVR. Jediná cesta je teda prenášať šifrovane až do AVR. No a tu je od atmelu hotové profi riešenie ktoré funguje výborne. Vrátane ľahkej tvorby toho zašifrovaného súboru.

Takže potrebujem aby loader funkcia bola na pevnej adrese aby som ju mohol volať z mojej aplikácie. Iba resetom to nezvládnem, lebo CRC bude ok a tak sa bootloader neaktivuje. Mačkanie nejakých tlačítok neprichádza do úvahy. Zariadenie je do náročných podmienok a preto žiadne tlačítka nemá.

to #pragma segment som skúšal ale nejak to s adresou funkcie nič neurobilo. Tiež som skúšal vložiť ukazatel na loader do FLASH ale tam kompilátor pindal až sa hory zelenali. Exportovaný loader tiež neprichádza do úvahy nakoľko sú to dva odlišné zdrojáky, ktoré o sebe nič nevedia.

Riešenie starého assembleristu - do asm súboru ktorý mi inicializuje periferie v bootloaderi som prihodil toto.

Kód: Vybrať všetko

ASEGN MYASM :CODE , 0x1fe00
          rjmp	loader
No a je to.
Ak by niekto vedel ako to vyriešiť pre IAR C tak by som sa potešil. Stačilo by mi len to, ako vložiť ukazateľ na adresu 0x1fe00 tak aby ukazoval na funkciu loader.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 27 Jún 2013, 07:33

tak tu je jedno riesenie:

Kód: Vybrať všetko

typedef struct point {void (*pf)(void);}point; 

int main (void)
{
 // zadefinovanie umiestnenia pointra ( miesto v pamati kde je ulozena adresa funkcie )
struct point *ppp = (struct point *) 0x00001000;

// naplni pamatove miesto 0x00001000 adresou funkcie semSkoc
ppp->pf = semSkoc;  
}

void semSkoc(void)
{
....
}
A opat je to v Keil pre ARM, a je mozne ze sa to da aj jednoduchsie.

Predpokladam ze aj tvoj c kompilator pozna prikaz pre kod v asm.
0

stefanSK
Pokročilý člen
Pokročilý člen
Príspevky: 752
Dátum registrácie: 24 Jún 2010, 00:00
Bydlisko: Trnava
Vek: 68

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa stefanSK » 27 Jún 2013, 09:00

podľa mňa stačí:

void (*pf)(void);

inicializácia:
pf= 0x1fe00;

volanie:
pf();
0
S.K.

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa peterple » 27 Jún 2013, 21:44

Ďakujem obom za reakcie.
Skúsil som jedno aj druhé, ale nie je to to pravé orechové.
xmilos:
ARM čo som v rýchlosti pozrel má linearny adresný preiestor 4GB a jednotlivé druhy pamäťových priestorov sa nachádzajú na rôznych adresách. Elegantné riešenie na mocnom železe. Pamätám si ako som sa tiež tešil že si nemusim robiť starosti so segmentáciou pamäte na I386. Lenže AVR je nižšia váhová kategória s Harvardskou architektúrou. Tam to takto ľahko nefunguje.

stefanSK:
jednoduchší zápis, z tej štruktúry som trochu zamotaný. Lenže toto vyrobí ukazateľ na adresu 0x1fe00 a nie že na adresu 0x1fe00 vloži ukazateľ na danú funkciu. Keby to fungovalo tak by to šlo vyriešiť pomocou *pf=loader; lenže ono to z princípu fungovať nemôže. Bežiaci program nemôže meniť pamäť programu lebo je to FLASH. To sa dá iba programátorom a potom ešte SPM inštrukciou ale to je na iné veci. Takže potrebujem niečo čo to skompiľuje rovno do CODE segmentu aby som to mohol napáliť.
Tak som sa s tým ešte trochu pohral a tu je vysledok:

Kód: Vybrať všetko

void loader(void){
}

__flash  void ( *pf1)(void)=loader @ 0xff00;  //4   Error[Pe065]: expected a ";"
__flash  void ( *pf2)(void) @ 0xff00;	//3
__flash  void ( *pf)(void)=loader;	//2
__no_init int a @ 0x300;		//1
int main( void ){
  pf();
  pf2();
}

Takže môj záver
1. ide urobiť premenú v SRAM na absolútnej adrese.
2. ide urobiť ukazateľ vo FLASH na funciu tak že ukazuje na funkciu a korektne to funguje (odskúšané krokovaním v simulátore)
3. ide urobiť ukazateľ ktorý je vo FLASH na absolútnej adrese, ale nie je inicializovaný. Teda on je ale na 0x0000
4. nejde urobiť ukazateľ do FLASH ktorý ukazuje na funkciu a je na absolútnej adrese. Prekladač očakáva bodkočiarku za loader.
Je možné že to ide. Ale ako, to je pre nejakého IAR guru. No a kedže sa mi to podarilo vyriešiť pomocou asm modulu nebudem už ďalej pátrať Cčkovým smerom.
Ešte vysvetlenie prečo je tuto 0xFF00 a v assemleri je 0x1FE00. Jedno je ak adresujem FLASH po wordoch a druhé po byte (0xFF00 * 2 = 0x1FE00

Všetkým čo odpísali ďakujem za ich čas.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

stefanSK
Pokročilý člen
Pokročilý člen
Príspevky: 752
Dátum registrácie: 24 Jún 2010, 00:00
Bydlisko: Trnava
Vek: 68

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa stefanSK » 28 Jún 2013, 07:43

myslým, že ten môj zápis by mnal byť správny.
void (*pf)(void); je deklarácia smerníka na funkciu, ktorá nevracia žiadnu hodnotu a nemá žiadny vstupný parameter - teda
je v RAM

pf= 0x1fe00; naplním smerník adresou funkcie tu 0x1fe00, samozrejme že môže byť ĺubovolná (dá sa vyskúšať aj mimo bootloader naplnením adresy existujúcej funkcie)

pf(); zavolanie funkcie ktorej adresa je v smerníku pf

skúška:

void myFnc(int a)
{
...
}
void (*pf)(int);

main(void)
{
pf = myFnc;
pf(2); malo by to zavolať funkciu myFnc a v registri pre prvý parameter bude hodnota 2 (t.j. môžeš odovzdať funkcie
aj parameter)
...

}


}
0
S.K.

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 28 Jún 2013, 07:50

2 Stevo adresa smernika musi byt absolutna, ale jeho hodnota je "pohybliva" adresa funkcie.

Kod co sam dal bol "odkrokovany" na simulatore a je O.K. na adresu 0x00001000 ulozil adresu funkcie.

Oki, hlavne ze to bezi.

2 peter zaujima ta komunikacia cez BT. Aky modul si pouzil?
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa peterple » 28 Jún 2013, 15:52

StevoSk: to čo si napísal je pravda. Len ja som chcel niečo iné. To čo popísal xmilos bolo OK len akonáhle som to dal z RAM do FLASH tak to skončilo rovnakými chybovými hláškami ako v tom mojom zhrnutí. Ešte som pre úplnosť vyskúšal @ aj na funkciu. Tam kompilátor rovno napísal že funkcia nemôže mať definovanú absolútnu adresu. Teraz ma napadla ešte jedna cesta - prehlásiť funkciu loader za obsluhu prerušenia a potom by to kompiler vyriešil skokom v tabulke vektorov na túto funkciu a ten skok už bude na absolútnej adrese na začiatku BOOT_SECTION. Ale už sa mi to nechce bádať ako sa to robí a či to bude funkčné. Mám čo som potreboval. A ako píšeš bootloader raz nahrať a zabudnúť. Dúfam že to tak už konečne bude už sa okolo toho motám viac ako dva mesiace.
Ešte musím napísať update pre android.

xmilos:
modul je tam BTM222.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 29 Jún 2013, 11:01

Synchronizaciu zabezpecuje firmware v module, alebo musis ju robit ty?
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa peterple » 29 Jún 2013, 11:22

Neviem akú synchronizáciu máš na mysli. Komunikácia s telefónom funguje štýlom pošli príkaz, počkaj na odpoveď. Ak si myslel riadenie toku DTR/DSR tak mám to pripojené ale zatiaľ to nekontroľujem. Už som si veľakrát povedal že to tam dorobím ale vždy je niečo súrnejšie a zatial to nič badatelne pri prenose netratí. Idem pomaly iba 19200 baud.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Používateľov profilový obrázok
xmilos
Ultimate člen
Ultimate člen
Príspevky: 3671
Dátum registrácie: 04 Máj 2011, 00:00
Bydlisko: Povazie

Re: IAR C AVR - kompilovanie funkcie na absolútnu adresu

Príspevok od používateľa xmilos » 29 Jún 2013, 11:39

tak zle som sa vyjadril.
Parovanie BT zariadeni - kto to robi.
0

Napísať odpoveď