Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

global variable corruption on at90can128

Posted by sebamz on November 12, 2013

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

<!-- HTML generated using hilite.me -->

/*
    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 mainLEDTASKPRIORITY ( tskIDLEPRIORITY ) #define mainTIMETASKPRIORITY ( tskIDLEPRIORITY + 2) #define mainREADCTASKPRIORITY ( tskIDLEPRIORITY + 1 ) #define mainHALLTASKPRIORITY ( tskIDLEPRIORITY + 1 ) #define mainREADTEMPADCPRIORITY ( tskIDLEPRIORITY ) #define mainREADSPITEMPPRIORITY ( tskIDLEPRIORITY ) #define mainREADSPI3DBSPRIORITY ( tskIDLEPRIORITY ) //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 mainCOMTESTBAUD_RATE ( ( unsigned long ) 38400 )

/* Scheduler TickPeriod in ms*/ #define mainTICKRATEMS ( 1000/configTICKRATEHZ )

/* LED used by the serial port tasks. This is toggled on each character Tx, and mainCOMTESTLED + 1 is toggles on each character Rx. */ #define mainCOMTESTLED ( 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

Posted by richardbarry on November 12, 2013

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

Posted by sebamz on November 12, 2013

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.

<!-- HTML generated using hilite.me -->

#define configMINIMALSTACKSIZE	( ( unsigned short ) 85 )
#define configTOTALHEAPSIZE		( (size_t ) ( 3500 ) )	

this is struct Buffer defined in buffer.h

<!-- HTML generated using hilite.me -->

struct Buffer {
  uint16t data[BUFFERSIZE];
  uint8t read; 				
  uint8t 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.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists