global variable corruption on at90can128

Hi, I’m having a problem with a global variable I use in my main.c. I use CANFIFO as a buffer to store measured data. When I start the debugger and the program counter is at the beginning of main, there are already values different from zero in CANFIFO. The amount of values already written in CANFIFO seems to be dependent on how many tasks I create. E.g. if I create only one task, about four values in CANFIFO are written and the rest can be used as intended for buffering data. If I create more tasks, there are only a few elements left in which data is stored in the course of the program. I’m not sure whether my problem is only a compiler issue or about FreeRTOS. Could someone please give me a few ideas on what could be the cause of this effect? Please pardon the german comments in my code. Best regards. compiler: avrgcc 4.5.1 (AVR Studio 4.19) debugger: Olimex AVR-JTAG-USB main.c
/*
    FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.

Changes from V4.0.5

   + Modified to demonstrate the use of co-routines.

*/

#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>

/* EEPROM routines used only with the WinAVR compiler. */
#include <avr/eeprom.h> 

/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
//#include "croutine.h"
#include "semphr.h"

/* My file headers. */
#include "systemtasks.h"
#include "sensors.h"
#include "init.h"
#include "buffer.h"
#include "datablock.h"
#include "spi_lib.h"
#include "bma020.h"

/* Priority definitions for most of the tasks in the application.  Some
tasks just use the idle priority. The higher the Value, the higher is the actual priority.*/
#define mainLED_TASK_PRIORITY          ( tskIDLE_PRIORITY )
#define mainTIME_TASK_PRIORITY         ( tskIDLE_PRIORITY + 2)
#define mainREADC_TASK_PRIORITY            ( tskIDLE_PRIORITY + 1 )
#define mainHALL_TASK_PRIORITY         ( tskIDLE_PRIORITY + 1 )
#define mainREAD_TEMP_ADC_PRIORITY     ( tskIDLE_PRIORITY )
#define mainREAD_SPI_TEMP_PRIORITY     ( tskIDLE_PRIORITY )
#define mainREAD_SPI_3DBS_PRIORITY     ( tskIDLE_PRIORITY )        //die SPI-Tasks muessen gleiche Prio haben, sonst muss ein Mutex für SPI eingefuert werden!

/* Baud rate used by the serial port tasks. */
#define mainCOM_TEST_BAUD_RATE         ( ( unsigned long ) 38400 )

/* Scheduler TickPeriod in ms*/
#define mainTICK_RATE_MS               ( 1000/configTICK_RATE_HZ )

/* LED used by the serial port tasks.  This is toggled on each character Tx,
and mainCOMTESTLED + 1 is toggles on each character Rx. */
#define mainCOM_TEST_LED               ( 4 )

//Idle Hook Task
//void vApplicationIdleHook( void );

//Flashing of LEDs Task
//void vLEDFlashTask( void *pvParameters );

//Flashing of LEDs Co-Routine
//void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex );

//Read Port C Task
void vReadPortCTask( void *pvParameters );

//ADC Sample Battery Voltage Task
void vReadBattVolt(void * pvParameters);

//ADC Sample Intake Temperature Task
void vReadIntakeTemp(void * pvParameters);

//Incrementing of Systemtime Task
void vRefreshSystemTime( void *pvParameters );

//Read Counter 3 counting Result Task
void vReadHallPeriod( void *pvParameters );

//Read MAX6675 Temperature over SPI
void vReadSPITemp (void * pvParameters);

//Read BMA020 Acceleration
void vRead3DBS (void * pvParameters);

/-----------------------------------------------------------/

//Systemzeit
struct time_s SysTime;

//Der Datenpuffer für CAN und sein Mutex
struct Buffer CAN_FIFO = {{}, 0, 0};
xSemaphoreHandle xFIFOmutex;

//letztes Zaehlergebniss des Timer2  fuer eine Periode des Hall-Signals
volatile uint16_t HallPeriod;

/-----------------------------------------------------------/

//tritt auf, wenn Int0 ausgeloest wird
ISR(INT0_vect){
    if(TOV3 == 0){   //kein Overflow aufgetreten
        //Zwischenspeichern vom Timer3 Zaehlregister (=Zaehlergebnis=>Periodendauer der Radumdrehung)
        HallPeriod = TCNT3;
        //Reset Timer3 Zaehlregister
    }
    else{                            //Overflow aufgetreten
        HallPeriod = 0xFFFF;        //Ergebnis soll Maximalwert sein =>langsamste messbare Raddrehzahl
        TIFR3 &= ~(1 << TOV3);        //Overflow-Flag loeschen
    }
    TCNT3 = 0;                      //Zaehlergebnis zuruecksetzen
}

/-----------------------------------------------------------/
int main( void )
{
//Test für Debugging CANFIFO.data[0]=11; CANFIFO.data[1]=11; CANFIFO.data[2]=11; CANFIFO.data[3]=31; CANFIFO.data[4]=111; CANFIFO.data[5]=11; CANFIFO.data[10]=12; CANFIFO.data[14]=13; CANFIFO.data[15]=34; CANFIFO.data[20]=99; //Mutex für CANFIFO erstellen, damit nicht mehrere Tasks gleichzeitig auf CANFIFO zugreifen können xFIFOmutex = xSemaphoreCreateMutex();
<span style="color: #408080; font-style: italic">//Initialisierungen</span>
vIO_Init();
vInitExtInt0();
vInitTimer3();
<span style="color: #408080; font-style: italic">//Reihenfolge wichtig!</span>
vInitSPI_SS ();
spi_init((<span style="color: #B00040">uint8_t</span>)(SPI_MASTER<span style="color: #666666">|</span>SPI_MSB_FIRST<span style="color: #666666">|</span>SPI_DATA_MODE_0<span style="color: #666666">|</span>SPI_CLKIO_BY_16));
vInit3DBS();
<span style="color: #408080; font-style: italic">//Reihenfolge wichtig!</span>

<span style="color: #408080; font-style: italic">//Create Tasks</span>
<span style="color: #408080; font-style: italic">// xTaskCreate (task function name, task name (choose freely), stack size, pointer to task parameters, task priority, pass back handle by reference)</span>

<span style="color: #408080; font-style: italic">//xTaskCreate( vLEDFlashTask, ( signed char * ) &quot;LED&quot;, configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY, NULL );</span>
xTaskCreate ( vRefreshSystemTime, ( <span style="color: #B00040">signed</span> <span style="color: #B00040">char</span> <span style="color: #666666">*</span> ) <span style="color: #BA2121">&quot;SYSTIME&quot;</span>, configMINIMAL_STACK_SIZE, ( <span style="color: #B00040">void</span> <span style="color: #666666">*</span> ) <span style="color: #666666">&amp;</span>SysTime, mainTIME_TASK_PRIORITY, <span style="color: #008000">NULL</span>);
xTaskCreate ( vReadPortCTask, ( <span style="color: #B00040">signed</span> <span style="color: #B00040">char</span> <span style="color: #666666">*</span> ) <span style="color: #BA2121">&quot;READC&quot;</span>, configMINIMAL_STACK_SIZE, <span style="color: #008000">NULL</span>, mainREADC_TASK_PRIORITY, <span style="color: #008000">NULL</span>);
<span style="color: #408080; font-style: italic">//xTaskCreate ( vReadBattVolt, ( signed char * ) &quot;ADCBATT&quot;, configMINIMAL_STACK_SIZE, NULL, mainREAD_TEMP_ADC_PRIORITY, NULL);</span>
<span style="color: #408080; font-style: italic">//xTaskCreate ( vReadIntakeTemp, ( signed char * ) &quot;INTEMP&quot;, configMINIMAL_STACK_SIZE, NULL, mainREAD_TEMP_ADC_PRIORITY, NULL);</span>
<span style="color: #408080; font-style: italic">//xTaskCreate ( vReadHallPeriod, ( signed char * ) &quot;HALL&quot;, configMINIMAL_STACK_SIZE, NULL, mainHALL_TASK_PRIORITY, NULL);</span>
<span style="color: #408080; font-style: italic">//xTaskCreate ( vReadSPITemp, ( signed char * ) &quot;ET1&quot;, configMINIMAL_STACK_SIZE, ( void * ) SS0, mainREAD_SPI_TEMP_PRIORITY, NULL);</span>
<span style="color: #408080; font-style: italic">//xTaskCreate ( vReadSPITemp, ( signed char * ) &quot;ET2&quot;, configMINIMAL_STACK_SIZE, ( void * ) SS1, mainREAD_SPI_TEMP_PRIORITY, NULL);</span>
<span style="color: #408080; font-style: italic">//xTaskCreate ( vReadSPITemp, ( signed char * ) &quot;ET3&quot;, configMINIMAL_STACK_SIZE, ( void * ) SS2, mainREAD_SPI_TEMP_PRIORITY, NULL);</span>
<span style="color: #408080; font-style: italic">//xTaskCreate ( vReadSPITemp, ( signed char * ) &quot;ET4&quot;, configMINIMAL_STACK_SIZE, ( void * ) SS3, mainREAD_SPI_TEMP_PRIORITY, NULL);</span>
<span style="color: #408080; font-style: italic">//xTaskCreate ( vRead3DBS, ( signed char * ) &quot;3DBS&quot;, configMINIMAL_STACK_SIZE, NULL, mainREAD_SPI_3DBS_PRIORITY, NULL);</span>


<span style="color: #408080; font-style: italic">//Create Co-Routines</span>
<span style="color: #408080; font-style: italic">//xCoRoutineCreate (co-routine name, co-routine priority, index)</span>
<span style="color: #408080; font-style: italic">//xCoRoutineCreate( vFlashCoRoutine, 0, 0 );</span>

HallPeriod <span style="color: #666666">=</span> <span style="color: #666666">0xFFFF</span>;        <span style="color: #408080; font-style: italic">//Maximalwert =&gt;langsamste messbare Raddrehzahl</span>
sei();
vTaskStartScheduler();


<span style="color: #008000; font-weight: bold">while</span> (<span style="color: #666666">1</span>){};
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #666666">0</span>;
}//int main( void ) /-----------------------------------------------------------/ //Implementation of tasks //...

global variable corruption on at90can128

If this happens before you have started the scheduler then I doubt it is an RTOS problem, and is most likely a simple linker script problem. When you create a task FreeRTOS will call pvPortMalloc() to allocate some RAM. Where that RAM comes from is dependent on which memory allocator you have included in your project. http://www.freertos.org/a00111.html Are you using heap1.c, heap2.c or heap_4.c? If so then the RAM will come from a statically allocated array, and if writing to that array is also writing into your CAN buffer then there is a problem with the memory map/linker script. You can configure a malloc() failed hook function with these to trap running out of memory in the static array. If instead you are using heap_3.c then the memory will come from the heap as allocated by GCC when the standard GCC malloc() is called. In this case your build files must allocate a heap that is large enough. Often with GCC an overflowed heap is not detectable. Your code does not show what a struct Buffer type is. Are you sure it is itself actually allocating a buffer and not just a pointer to a buffer that you should be allocating yourself? Regards.

global variable corruption on at90can128

Hi Richard, thank you for the fast response. I’m using heap_2.c and in my settings heap size for tasks should be way enough for about ten tasks.
#define configMINIMALSTACKSIZE ( ( unsigned short ) 85 )
#define configTOTALHEAPSIZE      ( (size_t ) ( 3500 ) )  
this is struct Buffer defined in buffer.h
struct Buffer {
  uint16t data[BUFFERSIZE];
  uint8t read;
uint8
t write;
};
You’re right, I’m not sure if I’m introducing CANFIFO the right way (in this case I don’t really know what I’m doing, which is bad…). I’ll try to force the compiler to allocate memory for CANFIFO before allocating memory for other purposes. Best regards.