Forum: Mikrocontroller und Digitale Elektronik freertos + ATMEGA644 - Portierung


von Christian F. (Firma: ---) (chriz)


Angehängte Dateien:

Lesenswert?

Hallo allerseits,

vorweg muss ich sagen, dass ich absolut kein crack in µc-Programmierung 
bin und versuche mich da lediglich durchzubeissen.
Momentan haben wir ein kleines Roboter Projekt, dessen Programmierung 
wir in Modulen erledigen. Diese Module sollen dann mittels eines rtos 
miteinander kommunizieren.
Wir haben uns dann für das freertos entschieden. Problem bei der Sache 
ist, dass die demo für AVR's für den AVR323 geschrieben wurde und somit 
nicht komplett Registerkompatibel zum ATMega644 ist.
Da macht sich vorallen bei den TIMERn und den benötigten INTERUPTS 
bemerkbar. So haben wir das Problem, dass zum Beispiel zuerst vtask1 
abläuft (schaltet z bsp. alle LEDs an) dann sorgt nen vtaskdelay dafür, 
dass vtask2 aufgerufen wird (schaltet z bsp. alle LEDs aus). Da wir nur 
2 tasks zum probieren verwenden, müssten die LEDs immer im wechsel alle 
on-off-on-off-.. gehen. Resultat ist jedoch, die LEDs gehen kurz an 
(task1) , dann gehen sie aus und bleiben aus. Also läuft der task1 und 
task2 nur genau 1 mal ab und es wird niewieder in einen derbeiden tasks 
gesprungen und das os hängt in einer idle-schleife(mit dem debugger 
nachvollzogen). Also scheint es so, dass die Register/Timer die wir 
verändert haben (Portierung vom avr323 zum ATmega644) nicht wirkluch 
funzen. Die Frequenzen und prescaler müssen wohl auch noch alle 
irgendwie angepasst werden. Aber das scheinen wir bis dato wohl 
irgendwie falsch gemacht zu haben.

Ich weiss, dass so etwas nicht gern gesehen ist, aber falls uns jemand 
kurzfristig sagen könnte, was wir wie zu ändern haben, wäre ich äußerst 
dankbar, da ich mir seit Tagen immer und immer wieder die 
ApplicationsNotes und Datasheets und den quellcode angucke und absolut 
nicht weiterkomme bei der Umportierung.

Anscheinend müssen wohl die folgen Parameter angepasst werden. Das sind 
jetzt hier die Original Settings für den avr323 bzw auch den ATMEGA32.
1
aus der PORT.C
2
/*-----------------------------------------------------------
3
 * Implementation of functions defined in portable.h for the AVR port.
4
 *----------------------------------------------------------*/
5
6
/* Start tasks with interrupts enables. */
7
#define portFLAGS_INT_ENABLED                ( ( portSTACK_TYPE ) 0x80 )
8
9
/* Hardware constants for timer 1. */
10
#define portCLEAR_COUNTER_ON_MATCH           ( ( unsigned portCHAR ) 0x08 )
11
#define portPRESCALE_64                      ( ( unsigned portCHAR ) 0x03 )
12
#define portCLOCK_PRESCALER                  ( ( unsigned portLONG ) 64 )
13
#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( unsigned portCHAR ) 0x10 )
14
15
/*-----------------------------------------------------------*/
1
aus der PORT.C
2
/*-----------------------------------------------------------*/
3
 * Setup timer 1 compare match A to generate a tick interrupt.
4
 */
5
static void prvSetupTimerInterrupt( void )
6
{
7
unsigned portLONG ulCompareMatch;
8
unsigned portCHAR ucHighByte, ucLowByte;
9
10
  /* Using 16bit timer 1 to generate the tick.  Correct fuses must be
11
  selected for the configCPU_CLOCK_HZ clock. */
12
13
  ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
14
15
  /* We only have 16 bits so have to scale to get our required tick rate. */
16
  ulCompareMatch /= portCLOCK_PRESCALER;
17
18
  /* Adjust for correct value. */
19
  ulCompareMatch -= ( unsigned portLONG ) 1;
20
21
  /* Setup compare match value for compare match A.  Interrupts are disabled 
22
  before this is called so we need not worry here. */
23
  ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff );
24
  ulCompareMatch >>= 8;
25
  ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff );
26
  OCR1AH = ucHighByte;
27
  OCR1AL = ucLowByte;
28
29
  /* Setup clock source and compare match behaviour. */
30
  ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64;
31
  TCCR1B = ucLowByte;
32
33
  /* Enable the interrupt - this is okay as interrupt are currently globally
34
  disabled. */
35
  ucLowByte = TIMSK;
36
  ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;
37
  TIMSK = ucLowByte;
38
}
39
/*-----------------------------------------------------------*/

Und das sind hier noch die Standardeinstellungen für den AVR323 in der 
FREETROSCONFIG
1
/*-----------------------------------------------------------
2
 * Application specific definitions.
3
 *
4
 * These definitions should be adjusted for your particular hardware and
5
 * application requirements.
6
 *
7
 * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
8
 * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 
9
 *----------------------------------------------------------*/
10
11
#define configUSE_PREEMPTION    1
12
#define configUSE_IDLE_HOOK    1
13
#define configUSE_TICK_HOOK    0
14
#define configCPU_CLOCK_HZ    ( ( unsigned portLONG ) 16000000 )
15
#define configTICK_RATE_HZ    ( ( portTickType ) 1000 )
16
#define configMAX_PRIORITIES    ( ( unsigned portBASE_TYPE ) 4 )
17
#define configMINIMAL_STACK_SIZE  ( ( unsigned portSHORT ) 85 )
18
#define configTOTAL_HEAP_SIZE    ( (size_t ) ( 4000 ) )
19
#define configMAX_TASK_NAME_LEN    ( 8 )
20
#define configUSE_TRACE_FACILITY  0
21
#define configUSE_16_BIT_TICKS    1
22
#define configIDLE_SHOULD_YIELD    1
23
24
/* Co-routine definitions. */
25
#define configUSE_CO_ROUTINES       0
26
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
27
28
/* Set the following definitions to 1 to include the API function, or zero
29
to exclude the API function. */
30
31
#define INCLUDE_vTaskPrioritySet    0
32
#define INCLUDE_uxTaskPriorityGet    0
33
#define INCLUDE_vTaskDelete      0
34
#define INCLUDE_vTaskCleanUpResources          0
35
#define INCLUDE_vTaskSuspend      0
36
#define INCLUDE_vTaskDelayUntil      0
37
#define INCLUDE_vTaskDelay      1
38
39
40
#endif /* FREERTOS_CONFIG_H */

Ok ich hoffe man darf hier soviel code reinknallen, ohne das es 
unhöflich erscheint. =) Aufjedenfall haben wir an diesen Settings und 
Registerbezeichnungen Veränderungen vorgenommen, jedoch ohne Erfolg. Im 
Anhang hab ich das fehlerfrei compilierbare OS mit den simplen LED 
an-aus, und den von uns vorgenommen Änderungen (die jedoch nicht 
greifen), angehangen.

Ansonsten erstma danke fürs Durchkämpfen des Textes.

Chris

von Markus (Gast)


Lesenswert?

Da beide Tasks so wie ich es verstanden haben einmal gelaufen sind 
funktioiert der Task wechsel schonmal was darauf schließen lässt dass 
der Timer richtig funktioniert.

Ich vermute euer Problem eher bei dem Aufruf von vTaskDelay(5);
Probierts mal mit vTaskDelayUntil

Markus

von Christian F. (Firma: ---) (chriz)


Lesenswert?

Hab ich eben gerade mal ausprobiert, dasselbe in grün. Alle LEDs gehen 
einmal an und dann wieder aus und bleiben aus. Ich denke es liegt 
definitiv an den TIMERN  INTERRUPTS  TICKS ect. pp. Ich meine das 
springen vom Task1 zum Task2 hat ja nix mit den Timern zu tun. Aber das 
wieder "aufwecken" der tasks, nachdem beide einmal durchgelaufen sind, 
dass hat dann wohl etwas mit den TIMERN zu tun. Und das scheint beim 
Code noch komplett schief zu laufen.

Ich habe mal nen bissl gegooglet. In dem link hier meint einer der 
freertos Entwickler genau das, was ich vermute.

"Also - are you sure the tick interrupt is running. If not, then your 
task
will never unblock."

http://www.embeddedrelated.com/usenet/embedded/show/78564-1.php

Genau dort scheint der Fehler zu stecken, sprich wir haben die Timer 
nicht richtig portiert vom ATmega32 zum ATmega644. Und ich krieg das 
irgendwie auch nit hin.

Wäre für weitere Hilfe dankbar.

Chris

von Markus (Gast)


Lesenswert?

Nutzt du den Code den du hier im Forum gepostet hast oder den den du 
angehängt hast?
Im Post ist der Wert für das portFLAGS_INT_ENABLED richtig auf 0x80 
gesetzt im Angehängten Code aber auf 0x20.

Markus

von Christian F. (Firma: ---) (chriz)


Lesenswert?

Boah ;) exakt da lag der Fehler. Die Register der Timer die wir geändert 
haben, haben gestimmt, aber aus irgend einem Grund haben wir auch des 
InteruptEnable geändert.
Dickes Dankeschön Markus ... 4 Augen sehen doch mehr als 2.

schönes Wochenende noch

Chris

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.