Tool/software: TI C/C++ Compiler
Hi,
I have a structure (KVSpair) which I want to program into Location 0x0 of EEPROM and read back into a similar structure. What I see is only the first element in the structure is populated after Read and the next one leads to segmentation fault ISR looping.
This is a test program to find index of key and its obtain its value where both key and value are strings.
Please help.
I am attaching the test code for you convenience (Whole Program) and I am annotating part of the program which is relevant.
#define NUMKEYS 3
/**************************************************************************************
*
* Variables
*
* ************************************************************************************
*/
// Start address is 0x0 to 0x17FC and where the sizeof(...) words would be written.
#define E2PROM_TEST_ADDRESS 0x0
*************************************************************************************************************
* main.c
* Driver program to calculate size of EEPROM and number of Blocks
* To write into every location from start to 6KB ie 0x0 to 0x17FC
* To read back that data
* Print to UART
**************************************************************************************************/
int main(void) {
uint32_t e2size,e2block;
uint32_t ui32SysClock;
uint32_t ui32EEPROMInit, ui32EEPROMStatus;
// Structure for holding Config parameter Strings
typedef struct {
char *key;
char *value;
}KVSpair, *dict_t ;
// initialize name value pairs
KVSpair KVarray[NUMKEYS] = {
{"UniquePartID\0","GEOM-MFAM-SENSOR\0"},
{"SerialNumber\0","ABCD-1294X-TM4c-xxxx\0"},
{"MachineSerialNumber\0","xxxx-xx-xxxx\0"}
};
KVSpair e2prom_kv_read_value= {"\0","\0"}; /* Read key value struct */
//******************************SET CPU CLOCK AT 120 MHZ***********************************************************************************************//
// Run from the PLL at 120 MHz.
//
ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
/* EEPROM SETTINGS */
SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0); // EEPROM activate
//
// Wait for the EEPROM module to be ready.
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0))
{
}
// Wait for the EEPROM Initialization to complete
ui32EEPROMInit = EEPROMInit();
//
// Check if the EEPROM Initialization returned an error
// and inform the application
//
if(ui32EEPROMInit != EEPROM_INIT_OK)
{
while(1)
{
}
}
/* UART SETTINGS */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioConfig(0, 115200, ui32SysClock);
/***************Main Action ****************/
UARTprintf("EEPROM Test Program \r\n");
e2size = EEPROMSizeGet(); // Get EEPROM Size
UARTprintf("EEPROM Size %d bytes\n", e2size);
e2block = EEPROMBlockCountGet(); // Get EEPROM Block Count
UARTprintf("EEPROM Block Count: %d\n", e2block);
***************************************************************************************************
* Config Parameters into EEPROM ********************************************************************
****************************************************************************************************** */
int i = 0;
const char *Key = "UniquePartID\0";
dict_t dict;
dict = KVarray; // pointer to point to our assigned data structure top
// print all keys
// find key
char *tmpStr;
for (i=0;i<NUMKEYS;i++){
// tmpStr = strdup(dict->key); // copy the key at index i to tmp str -- This does not work in Tiva
tmpStr = dict->key;
if (!strcmp(tmpStr, Key)){
// Write Confif Parameter String into EEPROM and read back
UARTprintf("Write Try > Address %u: Struct : {%s,%s}\n", E2PROM_TEST_ADDRESS, dict->key,dict->value);
// Wait for Write operation to complete
ui32EEPROMStatus = EEPROMProgram((uint32_t *)dict, E2PROM_TEST_ADDRESS, sizeof(dict)); //Write struct to start from 0x0000
while (ui32EEPROMStatus == EEPROM_RC_WORKING){
} // wait for current program to complete
//Do not attempt to read if a write is in progress
ui32EEPROMStatus = EEPROMStatusGet(); // This returns status of EEDONE register
if (!ui32EEPROMStatus) // the EEDONE register is all zeroes if EEPROM is idle
EEPROMRead((uint32_t *)&e2prom_kv_read_value, E2PROM_TEST_ADDRESS, sizeof(e2prom_kv_read_value)); //Read from struct at EEPROM start from 0x0000
// EEPROMRead((uint32_t *)&e2prom_kv_read_value.value, E2PROM_TEST_ADDRESS+1, sizeof(e2prom_kv_read_value.value)); //Read from struct at EEPROM start from 0x0000
UARTprintf("Read Try > Address %u: Struct : {%s,%s}\n", E2PROM_TEST_ADDRESS, e2prom_kv_read_value.key,e2prom_kv_read_value.value);
if (i<NUMKEYS-1) dict++;
return i;
}
}//end for
/****************************************************************************************************** * *********Basic Program for reading and writing to EEPROM************************************* */ #include <stdint.h> #include <stdbool.h> #include <string.h> #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "inc/hw_ints.h" #include "driverlib/gpio.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/interrupt.h" #include "driverlib/eeprom.h" #include "utils/uartstdio.h" #include "drivers/pinout.h" //#define TEST_WHOLE_MEMORY /* Macro to enable whole memory read write block by block */ /* Enable this if you want to ecute the for loop that reads and writes from whole EEPROM memory*/ // number of key value pairs defined statically #define NUMKEYS 3 /************************************************************************************** * * Variables * * ************************************************************************************ */ // Start address is 0x0 to 0x17FC and where the sizeof(...) words would be written. #define E2PROM_TEST_ADDRESS 0x0 /************************************************************************************************************* * main.c * Driver program to calculate size of EEPROM and number of Blocks * To write into every location from start to 6KB ie 0x0 to 0x17FC * To read back that data * Print to UART **************************************************************************************************/ int main(void) { uint32_t e2size,e2block; uint32_t ui32SysClock; uint32_t ui32EEPROMInit, ui32EEPROMStatus; #ifdef TEST_WHOLE_MEMORY // Data Variables and address uint32_t pui32Data[2]; uint32_t pui32Read[2]; #endif // Structure for holding Character Strings struct E2PROM { uint8_t value1; uint8_t value2; uint16_t value3; uint8_t value4[12]; }; // Character Strings test struct E2PROM e2prom_write_value = {5,7,9826, "Hello World"}; /* Write struct */ struct E2PROM e2prom_read_value = {0,0,0,""}; /* Read struct */ // Structure for holding Config parameter Strings typedef struct { char *key; char *value; }KVSpair, *dict_t ; // initialize name value pairs KVSpair KVarray[NUMKEYS] = { {"UniquePartID\0","GEOM-MFAM-SENSOR\0"}, {"SerialNumber\0","ABCD-1294X-TM4c-xxxx\0"}, {"MachineSerialNumber\0","xxxx-xx-xxxx\0"} }; KVSpair e2prom_kv_read_value= {"\0","\0"}; /* Read key value struct */ //******************************SET CPU CLOCK AT 120 MHZ***********************************************************************************************// // Run from the PLL at 120 MHz. // ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); //******************************ENABLE SYSTEM CLOCK FOR ON BOARD LED***********************************************************************************************// // Enable the GPIO port that is used for the on-board LED. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); // Check if the peripheral access is enabled. while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION)) { } // // Turn off the LED. // GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x0); // Enable the GPIO pin for the LED (PN0). Set the direction as output, and // enable the GPIO pin for digital function. GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0); SysCtlDelay(20000); // Turn on board LED GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0); //******************************INITIALIZE UART***********************************************************************************************// /* EEPROM SETTINGS */ SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0); // EEPROM activate // // Wait for the EEPROM module to be ready. // while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0)) { } // Wait for the EEPROM Initialization to complete ui32EEPROMInit = EEPROMInit(); // // Check if the EEPROM Initialization returned an error // and inform the application // if(ui32EEPROMInit != EEPROM_INIT_OK) { while(1) { } } /* UART SETTINGS */ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioConfig(0, 115200, ui32SysClock); /***************Main Action ****************/ UARTprintf("EEPROM Test Program \r\n"); e2size = EEPROMSizeGet(); // Get EEPROM Size UARTprintf("EEPROM Size %d bytes\n", e2size); e2block = EEPROMBlockCountGet(); // Get EEPROM Block Count UARTprintf("EEPROM Block Count: %d\n", e2block); //*** Test Section***********************************************/ // Write character string into EEPROM and read back UARTprintf("Write Try > Address %u: Struct : {%u,%u,%u,%s}\n", E2PROM_TEST_ADDRESS, e2prom_write_value.value1, e2prom_write_value.value2, e2prom_write_value.value3, e2prom_write_value.value4); // Wait for Write operation to complete ui32EEPROMStatus = EEPROMProgram((uint32_t *)&e2prom_write_value, E2PROM_TEST_ADDRESS, sizeof(e2prom_write_value)); //Write struct to start from 0x0000 while (ui32EEPROMStatus == EEPROM_RC_WORKING){ } // wait for current program to complete //Do not attempt to read if a write is in progress ui32EEPROMStatus = EEPROMStatusGet(); // This returns status of EEDONE register if (!ui32EEPROMStatus) // the EEDONE register is all zeroes if EEPROM is idle EEPROMRead((uint32_t *)&e2prom_read_value, E2PROM_TEST_ADDRESS, sizeof(e2prom_read_value)); //Read from struct at EEPROM start from 0x0000 UARTprintf("Read Try > Address %u: Struct : {%u,%u,%u,%s}\n", E2PROM_TEST_ADDRESS, e2prom_read_value.value1, e2prom_read_value.value2, e2prom_read_value.value3, e2prom_read_value.value4); /*************************************************************************************************** * Config Parameters into EEPROM ******************************************************************** ****************************************************************************************************** */ int i = 0; const char *Key = "UniquePartID\0"; dict_t dict; dict = KVarray; // pointer to point to our assigned data structure top // print all keys // find key char *tmpStr; for (i=0;i<NUMKEYS;i++){ // tmpStr = strdup(dict->key); // copy the key at index i to tmp str -- This does not work in Tiva tmpStr = dict->key; if (!strcmp(tmpStr, Key)){ // Write Confif Parameter String into EEPROM and read back UARTprintf("Write Try > Address %u: Struct : {%s,%s}\n", E2PROM_TEST_ADDRESS, dict->key,dict->value); // Wait for Write operation to complete ui32EEPROMStatus = EEPROMProgram((uint32_t *)dict, E2PROM_TEST_ADDRESS, sizeof(dict)); //Write struct to start from 0x0000 while (ui32EEPROMStatus == EEPROM_RC_WORKING){ } // wait for current program to complete //Do not attempt to read if a write is in progress ui32EEPROMStatus = EEPROMStatusGet(); // This returns status of EEDONE register if (!ui32EEPROMStatus) // the EEDONE register is all zeroes if EEPROM is idle EEPROMRead((uint32_t *)&e2prom_kv_read_value, E2PROM_TEST_ADDRESS, sizeof(e2prom_kv_read_value)); //Read from struct at EEPROM start from 0x0000 // EEPROMRead((uint32_t *)&e2prom_kv_read_value.value, E2PROM_TEST_ADDRESS+1, sizeof(e2prom_kv_read_value.value)); //Read from struct at EEPROM start from 0x0000 UARTprintf("Read Try > Address %u: Struct : {%s,%s}\n", E2PROM_TEST_ADDRESS, e2prom_kv_read_value.key,e2prom_kv_read_value.value); if (i<NUMKEYS-1) dict++; return i; } }//end for /**************************************************************************************************** * Test 6K of EEPROM memory with read word and write words block by block*********************************** ********************************************************************************************************/ #ifdef TEST // Program some data into the EEPROM at address 0x0000. // Calculate size of EEPROM and number of Blocks in that size pui32Data[0] = 0xFFFFFFFF; pui32Data[1] = 0x00000000; // wait for programming to be over ui32EEPROMStatus = EEPROMProgram(pui32Data, 0x400, sizeof(pui32Data)); while (ui32EEPROMStatus == EEPROM_RC_WORKING){ } UARTprintf("Data Written to EEPROM: %d\n", pui32Data); // // Read it back. //Do not attempt to read if a write is in progress if (ui32EEPROMStatus != EEPROM_RC_WRBUSY) EEPROMRead(pui32Read, 0x400, sizeof(pui32Read)); UARTprintf("Data read from EEPROM: %d\n", pui32Read); #endif #ifdef TEST_WHOLE_MEMORY int i =0,j=0; /******************************************************************************************************** // For whole EEPROM: Number of iterations = EEPROMSIZE/NUMBER OF EEPROMBLOCKS :j<(e2size/e2block) // Calculation is as follows: // inner loop always traverses each block // Outer loop is responsible for correct offset into each block from start address // First block: j=0l; so inner loop goes from 0 to 95 location // Second iteration of inner loop :j is 1(outer loop) and so we traverse locations 96 onwards to 192.. **********************************************************************************************************/ for (j=0;j<(e2size/e2block);j++) { for (i=0;i<e2block;i++) { // One Block // wait for write to complete ui32EEPROMStatus = EEPROMProgram(pui32Data,(E2PROM_TEST_ADDRESS+i+j*e2block) , sizeof(pui32Data)); while (ui32EEPROMStatus == EEPROM_RC_WORKING){ } // wait for current program to complete //Do not attempt to read if a write is in progress ui32EEPROMStatus = EEPROMStatusGet(); // This returns status of EEDONE register if (!ui32EEPROMStatus) // the EEDONE register is all zeroes if EEPROM is idle EEPROMRead(pui32Read, (E2PROM_TEST_ADDRESS+i+j*e2block), sizeof(pui32Read)); UARTprintf(" Block %d : Location:,%d", j,i); UARTprintf("Data read from EEPROM: %d\n", pui32Read); // UARTFlushTx(1); // wait for data to be flushed } // end inner loop for UARTprintf("Done Block EEPROM: %d\n", j); } // end out loop for UARTprintf("Done Whole EEPROM:\n"); #endif while (1) { } return 0; }