Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


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 ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

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

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

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner