# ARM mikrokontrolleri >  pa Ride7 stm32 softa compileri

## Epis

Ir tāda lieta ka rakstu vienu kodu kas ir uz 2 failiem viens ir fails kurā ir Main() proga un otrā failā ir Interput Service Routines kodi un rodās stūlba situācija ka tas compileris compilējot kodu uzražo reālu brāķi, proti izlaiž kodu rindas tur kur C failā nav redzams mainīgā pielietojums, vai tālākas darbības, kā lai šito noņem, šeit piemērs kur var redzēt ka C kodā kreisā compileris neuzģenerē kodu parastiem mainīgiem:
     int a=6;
    int b= 7;

int* OnOff = &VOnOff;

un tālāk if loopu arī neņem un tai vietā ieliek pirmo izvēli, problēma ir tur ka otrs C koda gabals uzliek tā VOnOff mainīgā vērtību uz 1, un pēc katra izsukuma viņu nomaina līdz ar to vaidzētu If loopam strādāt un mainīt GPIO_Pin_8;9 pinus bet tagat debaggojot uz sava Stm32 circle kita nekas nemainās un disasamblerā debagojot pa Asm kodu arī nekas nenotiek, piebildīšu ka Interput Service Routines failā pareizi nocompilējās kods un VOnOff tiek nomainīts un strādā, un neiet, sūdīgi compilējās tieši galveinais Main() fails. 
[attachment=0:36gc8mi9]Stm32compilerFinish.JPG[/attachment:36gc8mi9]

Ko darīt ??
vēl piebilde ka tas VOnOff main.h failā ir definēts kā EXTERN u32 VOnOff;  es lasīju ka šitā definējot no citiem failiem var tikt klāt pie tā mainīgā, vispār kā pareizāk definēt RAm atmiņā mainīgo un tikt pie tā klāt no dažādiem C failiem ?

----------


## 0xDEAD BEEF

Pareizak ir padot funckijam ta mainiga pointeri vai ari likt mainigo pie globalajiem.
Apskaties, ka tavs kods ir nokompilejies. Ka izskatas assamblera tas if.
Beefs

----------


## Epis

uztaisīju vēlvienu atsevišķu failu Mainigie.c un h 


```
#include "stm32f10x_lib.h"
#include "Mainigie.h"

u32 VOnOff = 0x00;

void LED_blink()
{
int* OnOff = &VOnOff;

loop:
  if(*OnOff == 0x00)
      {
       GPIOB->BSRR = GPIO_Pin_8; //Yello Led ON
       GPIOB->BRR = GPIO_Pin_9; //Red LED off
      }
  else
      {
       GPIOB->BRR = GPIO_Pin_8; //Yello Led off
       GPIOB->BSRR = GPIO_Pin_9; //Red LED  ON    
      }
}
```

 un tad tagat no Main() izsaucu     LED_blink(); funkciju un itkā tagat compileris strādā un compilē kodu pareizi
bet vispār kautkā baigi Tupi sanāk.



> Pareizak ir padot funckijam ta mainiga pointeri vai ari likt mainigo pie globalajiem.


 kā tu to domā, un ko domā ar globālajiem (#define VOnOff )  vai?  
a kādēļ vispār tādi compilera gļuki, vai ta viņš tik tups, ka neko nesaprot vai ?

----------


## Epis

pamēģināju tagat uztaisīt pēc jaunā varianta ar jaunu Mainigais.c un H vailu bet bez nekādiem Pointeriem, proti, pa taisno rakstīt un lasīt no Extern VOnOff mainīgā un strādā  ::  visar šito Extern mainīgā piemēru es ņēmu no USB paraug koda un cik lasīju kautkādos tutoriālos tad tas Extern definējums itkā ir Globāls visiem failiem, bet tad kad nekas nestrādāja un nekompilējās tad protams ka radās šaubas, un finālā sanāk tā ka tai Failā kurā ir MAIN() funkcija Extern mainīgais Nestrādā, bet citur gan iet. 
rekā tagat izskatās:


```
#include "stm32f10x_lib.h"
#include "Mainigie.h"

u32 VOnOff = 0x00;

void LED_blink()
{
  if(VOnOff == 0x00) //*OnOff == 0x00)
      {
       GPIOB->BSRR = GPIO_Pin_8; //Yello Led ON
       GPIOB->BRR = GPIO_Pin_9; //Red LED off
      }
  else
      {
       GPIOB->BRR = GPIO_Pin_8; //Yello Led off
       GPIOB->BSRR = GPIO_Pin_9; //Red LED  ON    
      }
}
```

 un Interupt.C failā :


```
void TIM2_IRQHandler(void)
{
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
if(VOnOff == 0x00)
        {
    VOnOff = 0x01;        
        }
    else{ VOnOff =0x00;}
}
```

 un šādi ziskatās mainīgā.h fails:


```
#ifndef __MAINIGIE_H
#define __MAINIGIE_H

extern u32 VOnOff;
#endif
```

 nu sūdīgi ka tas extern u32 VOnOff; nestrādā Main() funkcijas failā,  ko tā a?

----------


## 0xDEAD BEEF

NEESMU droish, bet man skiet, ka extern pie mainiga definicijas nozime to, ka tas tiek definets citur. Bet visa visuma tai stelei ar manigajiem butu jabut gauzam vienkarsai un vienu mainiga nosaukumu vajadzetu varet tikai vienu reizi includot.
Beefs

----------


## G-man

To mainīgo vajag definēt kā  - volatile u32 VOnOff; Tas dos kompilātoram norādi, lai neoptimizē griešanos pie mainīgā. Citādi jau vīņš nekādi nevar zināt, ka kaut kāds tur interrupts paņem un izmaina mainīgo.

----------


## Delfins

http://en.wikipedia.org/wiki/External_variable

----------


## 0xDEAD BEEF

Es ari iedomajos par volatile, bet man liekas, ka sis keywords ir pavisam nesen pievienojies programesanas valodam un vairak ir aktuals .net vide. Bet iespejams, ka kludos.

----------


## jeecha

Mainiigais VOnOff buutu shai gadiijumaa visur (vai attieciigi kautkur koplietoshanas .h failaa) jaadeklaree kaa "extern volatile u32" un attieciigi vienaa .c failaa kaa "volatile u32", jo simbolam kautkur ir jaarodas (bet tikai vienaa vietaa, preteejaa gadiijumaa linkeris izlamaasies par dublikaatu :: 

Extern lai pateiktu ka simbols buus jaamapo linkojot nevis kompileejot un volatile lai kompilators neveiktu optimizaacijas saistiibaa ar doto simbolu.
Shai gadiijumaa kompilatora optimizaacija vareeja visu nochakareet (un visdriizaak arii nochakareeja) vismaz divos veidos:
1) TIM2_IRQHandler() kodaa izoptimizeet nafig aaraa visu kas saistiits ar VOnOff jo pieshkjirtaa veertiiba dotajaa modulii nekur netiek izmantota;
2) main() VOnOff veertiibu iekeshot regjistros jo veertiiba dotaa modulja ietvaros netiek mainiita, attieciigi kaut arii atminjaa vinju interrupta handleris nomaina, main() uz to ir pajaat jo vinsh lieto iekeshotu veertiibu un tik dragaa.

Silti iesaku nafig vispaar atrubiit kompilatoram optimizaacijas visas kameer tu baksties un maacies C... Jo kompilatoram ne vienmeer izdodas pareizi uzmineet ko tad koderis ir iisti domaajis savaa galvaa sarakstot liiku kodu... taakaa shai gadiijumaa nevis "tupais C kompilators kas neko nejeedz" bet gan "tupais koderis kursh nejeedz kompilatoram pateikt ko tad vinsh iisti grib"  ::

----------


## Velko

> Es ari iedomajos par volatile, bet man liekas, ka sis keywords ir pavisam nesen pievienojies programesanas valodam un vairak ir aktuals .net vide. Bet iespejams, ka kludos.


 Grāmatā par C, kura sarakstīta 1989. gadā ir aprakstīts _volatile_ keywords (tikko pārbaudīju). Nedomāju ka to var uzskatīt par "pavisam nesen". Tajā laikā par .NET neviens pat nefantazēja.

Par kompilatoru: Nē jamais nav ne tups, ne gļukains. Tieši otrādi - pārāk gudrs - izoptimizē ārā kodu, no kura tāpat nav nekādas jēgas. Par globālajiem mainīgajiem, _extern_ un _volatile_ jeecha jau visu pateica.

Un kas tas par _loop:_? C ciklus raksta izmantojot _for_, _while_ vai _do_. Ja izmanto labeli, tad nepieciešams arī _goto_. Vispār jau gan neiesaku to darīt. Nopietni - ar labeļiem un goto var tiešām baigo putru kodā sataisīt (tas gan nenozīmē, ka bez tiem nevar  :: ).

----------


## Delfins

Birkām nav nevainas. Tiesa, tās ir vecumdienu paliekas/atrauga, bet ja ir samērā vnk kods iekš batnika - tās tomēr darbojās līdz šai pat laikam   ::

----------


## Texx

Kas ir batniks?

----------


## Delfins

.bat

----------


## Epis

iemēģināju to Volatile variantu, protams no sākuma ar pirmo mēģinājumu 
extern  u32 VOnOff;  otrā failā volatile u32 VOnOff =0x00; nekas negāja meta ārā erroru, un tad es mēģināju, gan tā gan tā, skatījos google un beigās pamēģināju šādi:
extern volatile u32 VOnOff;otrā failā volatile u32 VOnOff = 0x00; 
un tad aizgāja, un vairs neoptimizē,negriež ārā nekādus kodus saistītus ar to VOnOff  ::   nu čakars vispār baigais, daļa čakara tādēļ ka grūti atrast google kādus normālus, salasāmas, pa tēmu pamācības, kodus priekš MCU, tur ir visāda draza, bet ne tas ko vaig, salīdzinot ar visuālo studīju C# un ASP tur tiko uzklikšķini google ko vaig tā uzreiz tonnām kodu, paraugu par jebkādu jautājumu, +msdn.microsoft bibloteka, ir pamācības pa kurām rakāties, a šeit Ride7 softā ar tiem tutoriāliem ir pašvaki, proti jārokās pašam pa tiem C include, sorec failiem lai kautko sarastu no Example kodiem. (labi ka nav jāčakarējās ar Make failiem un linkeriem !!)
Nākošais ko kodēšu būs quad enkoder timer Capture/compare perifērijas inicializācija  un tad uzstādīs PWM taimeri un finālā griežot enkoderi griezīses motors  ::  un tad inicializējot vēlvienu CCP kanālu step/dir signālam + iemetot PID kodu sanāks nepilnīga servo tipa soļinieks (ar atgriezenisko saiti, bet bez jaudas kontrolles, jo man draiveris ārā dod konstantu jaudu, ja pieliktu klāt jaudas regulāciju tad būtu Tīrs SERVO stepperis. kad kautkas kustēsies un griezīsies tad atkal kautko uzrakstīšu.

----------


## Delfins

> daļa čakara tādēļ ka grūti atrast google kādus normālus, salasāmas, pa tēmu pamācības, kodus priekš MCU, tur ir visāda draza


 tu pats esi viens liela DRAZA - paņem jebkuru C/CPP manuāli un pārraksti piemērus, moš tad sāks strādāt fiška... C/CPP nav atkarīgs nenokādiem MCU un t.t. 
C ir C un CPP ir CPP - visur viena sintakse un pieeja.

----------


## Velko

Jāsaka gan, ka kurā katrā C manuālī _volatile_ var arī nebūt aprakstīts. Rakstot programmas priekš datora šis keywords tiek izmantots ārkārtīgi reti. Tā ka tutoriāļa autors var pamanīties to izlaist.

To nu tomēr vislielākās iespējas bija izmakšķerēt no kāda MCU orientēta apraksta. Un būtu pilnīgi vienalga, vai šis apraksts būtu par ARM, AVR, vai vēl kādas citas arhitektūras kontrolieriem.

Katrā gadījumā, Epi, nav ko atkal sākt burkšķēt, ka C ir "stūlbs". Tas ir skills, kuru jāiemācās tikai vienreiz, pēc tam tie paši principi darbojas priekš visām arhitektūrām. Tas pats attiecas uz makefailiem un linkošanu.

----------


## Epis

nu goglējot uz atslēgvārdiem  extern volatile int    volatile int visādās kombinācijās vismaz pirmajās lapās neko sakarīgu atrast kā piemēru nevar.
apstījos savās esošajās Pdf  grāmatās un vienā caur serch atrada Extern volatile vārdu kombināciju un kodu paraugu, bet tā ir baigā C bībele 
The New C Standard
An Economic and Cultural Commentary
Derek M. Jones 
1616 lapuses,

----------


## Delfins

> bet tā ir baigā C bībele


 a tu domāji inženieri top no gaisa? muehehe... study, study, practice, study, practice... die

----------

