Quality RTOS & Embedded Software

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




Loading

i2c on arm9 causing data abort

Posted by bones23 on December 28, 2007
I am trying to get an i2c driver running in freeRTOS on an str912. All it does right now is send a message continuously from the arm9 to a test device I have hooked up to the i2c bus. The i2c thread will run several hundred times just fine but will then throw a Prefetch abort. After stepping through the program I found that this happens in the call to vTaskDelay() made after the call to I2C_WriteData() has finished. Any ideas on what could be causing this?

//i2c thread
void prvRunI2C(void){
u8 i2cmsg[] = "test";

for(;;){
I2C_WriteData(0x6e, i2cmsg, 4);
vTaskDelay( mainLCD_DELAY );
}
}

//I2C_WriteData()
void I2C_WriteData(u8 address, u8 *msg, u8 count)
{
portENTER_CRITICAL();
I2C0_Buffer_Tx= msg;
i2c_buffer_size=count;
i2c_slave_address = address;

Direction = I2C_MODE_TRANSMITTER;
Tx_Idx=0;

{
char hex1[3];
char hex2[3];
char hex3[3];
hex1[2] = hex2[2] = hex3[2] = 0;

byte2hex(I2C0_Buffer_Tx[0], hex1);
byte2hex(I2C0_Buffer_Tx[1], hex2);
byte2hex(I2C0_Buffer_Tx[2], hex3);
}

I2C_GenerateStart(I2C0, ENABLE);
/* Test on EV5 and clear it */
while( ! I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_MODE_SELECT) ) // EV5
{;
}
/* Send I2C1 Address for write */
I2C_Send7bitAddress (I2C0, i2c_slave_address, I2C_MODE_TRANSMITTER);
/* Test on EV6 and clear it */
while( ! I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_MODE_SELECTED) ); // EV6
/* Clear EV6 by set again the PE bit */
I2C_Cmd (I2C0, ENABLE);
/* Send Data to write on I2C1 slave */
while (Tx_Idx < i2c_buffer_size)// && !stop)
{
/*snprintf(out_buf, 80, "sending byte: %d\r\n", Tx_Idx);
send_data(DEBUG_UART, out_buf, strlen(out_buf) );
*/

/* Send Master data */

I2C_SendData(I2C0, I2C0_Buffer_Tx[Tx_Idx++]);
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(I2C0, I2C_EVENT_MASTER_BYTE_TRANSMITTED))// && !stop) //EV8
{
u16 wLastEvent = I2C_GetLastEvent(I2C0);

switch (wLastEvent)
{
/* 16 means that the BUSY flag is set, but not the M/SL flag.
Since we mean to act only as a master, the M/SL flag should be
set anytime we are in the middle of transmission*/
/*case 16:
stop = 1;
snprintf(out_buf, 80, "I2C Error, wLastEvent==16\r\n");
send_data(DEBUG_UART, out_buf, strlen(out_buf));
if (wLastEvent == I2C_ARBITRATION_LOST)
{
snprintf(out_buf, 80, "I2C Arbitration Lost\r\n");
send_data(DEBUG_UART, out_buf, strlen(out_buf));
stop=1; //Leave the while loop
}
if (wLastEvent == I2C_BUS_ERROR_DETECTED)
{
snprintf(out_buf, 80, "I2C Bus Error\r\n");
send_data(DEBUG_UART, out_buf, strlen(out_buf));
stop=1; //Leave the while loop
}
break;
case 0:
snprintf(out_buf, 80, "I2C status of 0, stopping\r\n");
send_data(DEBUG_UART, out_buf, strlen(out_buf));
stop = 1;
break;*/
CASE_ERROR(I2C_EVENT_SLAVE_ADDRESS_MATCHED)
CASE_ERROR(I2C_EVENT_SLAVE_BYTE_RECEIVED)
CASE_ERROR(I2C_EVENT_SLAVE_BYTE_TRANSMITTED)
CASE_ERROR(I2C_EVENT_MASTER_MODE_SELECT)
CASE_ERROR(I2C_EVENT_MASTER_MODE_SELECTED)
CASE_ERROR(I2C_EVENT_MASTER_BYTE_RECEIVED)
//CASE_ERROR(I2C_EVENT_MASTER_BYTE_TRANSMITTED)
case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
break;
CASE_ERROR(I2C_EVENT_MASTER_MODE_ADDRESS10)
CASE_ERROR(I2C_EVENT_SLAVE_STOP_DETECTED)
CASE_ERROR(I2C_EVENT_SLAVE_ACK_FAILURE)
case 18: /*This is the correct busy state, busy flag, plus m/sl flag*/
break;
default:
UART_printf(DEBUG_UART, "unknown event: %d on byte: %d\r\n", wLastEvent, Tx_Idx);
break;
}
}
}

/* Generate STOP condition to close communication */
I2C_GenerateSTOP (I2C0, ENABLE);
/* Disable I2C0 */
//I2C_Cmd(I2C0, DISABLE);
portEXIT_CRITICAL();
}

RE: i2c on arm9 causing data abort

Posted by Richard on December 30, 2007
Have you checked that you are not running out of stack? I notice you are using snprintf() which can take up a lot of stack space.

First of all try simply increasing the stack allocated to the task.

Next you could try actually inspecting the stack. When the abort happens, inspect the pxCurrentTCB variable to see which task was running. From the structure you will be able to get the location of the stack the task was using. The stack was filled with 0xa5 when the task was created, so if all the 0xa5's have been overwritten then you know you are out of stack.

There are some cut down versions of the printf() family of functions included in the FreeRTOS.org download.

Regards.

RE: i2c on arm9 causing data abort

Posted by bones23 on January 15, 2008
Your right, I did not give this one enough stack space.


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




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

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

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