This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294KCPDT: Does erasing a block of flash memory affects the timers running in background?

Part Number: TM4C1294KCPDT

Hi,

I'm working on TM4C1294KCPDT.  I'm trying to erase a block of memory using FlashErase function provided in driverlib/flash.c

This erase is to happen whenever I get some data from the user. I need to erase the block and then program it with new data.

I have a timer running in the background at 1ms and when the code enters the FlashErase function my timer routine is not being called for some duration.

Can anyone help me with this?

Thanks

  • Hello Deepak,

    Typically the FlashErase process should execute from SRAM, so if the Timer isn't set to run out of SRAM then the program would not be able to execute it. Also you have to ensure that the Timer is not affected by the Flash erase and re-programming as well. For your device, 16 kB blocks are erased at a time, so care must be taken to avoid destroying any code that may be executing.

    To better confirm the execution from SRAM is the core of your issue, I would need to see code for both how the timer is configured as well as the Flash Erase process you are executing. Also getting the .cmd or .map file to understand the memory mapping would be helpful as well.
  • void timer4_init(void) {
        //
        // Enable the peripherals used by this example.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER4);
    
        //
        // Configure the 32-bit periodic timer.
        //
        TimerConfigure(TIMER4_BASE, TIMER_CFG_PERIODIC);
        TimerLoadSet(TIMER4_BASE, TIMER_A, ui32SysClock/1000);   //Clock at 120 MHz
    
        IntPrioritySet(INT_TIMER4A, 0x00);
    
        //
        // Setup the interrupts for the timer timeouts.
        //
        IntEnable(INT_TIMER4A);
        TimerIntEnable(TIMER4_BASE, TIMER_TIMA_TIMEOUT);
    
        //
        // Enable the timers.
        //
        TimerEnable(TIMER4_BASE, TIMER_A);
    }
    
    
    #define FLASH_EVENT_START	0x6C000	//Address of the first block of flash to be used for storing events.475136 0x6C000									// 524288-16384(boot)-16384(params)-16384(events)=475136
    #define FLASH_EVENT_END		0x70000	//Address of the last block of flash to be used for storing events.
    #define FLASH_BLOCK_SIZE	0x4000	//Flash erases in 16k block increments. //4000 DR
    #define FLASH_BLOCKS_TO_ERASE  1	// Number of blocks to erase.
    
    long Event_Schedule_Save(DIGITAL_EVENT_SCHEDULE* einfo) { // Save Event Info
    
    	long error = 1;
    	tFlashProtection state;
    	int i;
    	FLASH_EVENT_START=
    
    	ASSERT((FLASH_EVENT_START % 4) == 0);    // Starting address must be a multiple of 4. 
    	ASSERT((sizeof(einfo) % 4) == 0);		// Number of bytes to be programmed must be a multiple of 4.
    
    	state = FlashProtectGet(FLASH_EVENT_START);  // Get protection setting for block of memory to be used.
    	if (state == FlashReadWrite) { // States are r/w, ro, xo, must r/w.
    	    error = FlashErase(FLASH_EVENT_START);	// Erase flash in 16k block increments.
    	} else
    		error = -1;							// Error if state is not r/w.
    
    	if (!error)
    		error = FlashProgram((uint32_t*) einfo, FLASH_EVENT_START, sizeof(DIGITAL_EVENT_SCHEDULE));
    
    	return (error);  // -1 indicates programming error, 0 is success.
    }
    
    typedef struct {
    	union {
    		struct {
    			EVENT_SCHEDULE_HEADER 	HEADER;
    			DIGITAL_EVENT 		EVENTS[EVENT_COUNT];
    		};
    		unsigned char Byte[DIGITAL_EVENT_SCHEDULE_SIZE + EVENT_SCHEDULE_HEADER_SIZE];
    	};
    } DIGITAL_EVENT_SCHEDULE;
    Hi Ralph,

    I have attached a text file which contains my code for timer initialization and the flash erase and re-write. It also includes the structure I'm trying to write.

    I noticed that when it erases the block for the first time, the timer is not affected but every time after that my time is getting affected.

    Also, can you tell me where can i find the .cmd and .map in my project to share it with you.

    Regards,

    Deepak Rai

  • Hello Deepak,

    In Code Composer Studio, the .cmd file will be in your main project directory and the .map file will be in the Debug folder.
  • project_css_map.txt

    /******************************************************************************
     *
     * qs_weather_ccs.cmd - CCS linker configuration file for qs_weather.
     *
     * Copyright (c) 2013-2014 Texas Instruments Incorporated.  All rights reserved.
     * Software License Agreement
     *
     * Texas Instruments (TI) is supplying this software for use solely and
     * exclusively on TI's microcontroller products. The software is owned by
     * TI and/or its suppliers, and is protected under applicable copyright
     * laws. You may not combine this software with "viral" open-source
     * software in order to form a larger program.
     *
     * THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
     * NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
     * NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
     * CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
     * DAMAGES, FOR ANY REASON WHATSOEVER.
     *
     * This is part of revision 2.1.0.12573 of the DK-TM4C129X Firmware Package.
     *
     *****************************************************************************/
    
    --retain=g_pfnVectors
    
    /* The following command line options are set as part of the CCS project.    */
    /* If you are building using the command line, or for some reason want to    */
    /* define them here, you can uncomment and modify these lines as needed.     */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone.              */
    /*                                                                           */
    /* --heap_size=0                                                             */
    /* --stack_size=256                                                          */
    /* --library=rtsv7M3_T_le_eabi.lib                                           */
    
    /* The starting address of the application.  Normally the interrupt vectors  */
    /* must be located at the beginning of the application.                      */
    #define APP_BASE 0x00000000
    #define RAM_BASE 0x20000000
    
    /* System memory map */
    
    MEMORY
    {
        /* Application stored in and executes from internal flash */
        FLASH (RX) : origin = APP_BASE, length = 0x00100000
        /* Application uses internal RAM for data */
        SRAM (RWX) : origin = 0x20000000, length = 0x00040000
    }
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > APP_BASE
        .text   :   > FLASH
        .const  :   > FLASH
        .cinit  :   > FLASH
        .pinit  :   > FLASH
        .init_array : > FLASH
    
        .vtable :   > RAM_BASE
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM
    }
    
    __STACK_TOP = __stack + 1024;
    

    Hi Ralph,

    I have attached the files. Did you get anything on the issue through the code?

    I have the timer 4 running in the background and I'm using timer1 to write and erase the flash. Both are running at 1ms. Timer 4 has the highest priority and  I'm disabling the timer1 and then getting into the function to erase and write and after completion of the function I'm enabling the timer1 again.So I want the timer4 running at all the time irrespective of anything else.

    Regards,

    Deepak

  • A read from any location in the flash bank that has a block being erased will stall the CPU until the erase is complete. The stall even prevents interrupts from being serviced.
  • Hi Bob,
    As you can see through my previous posts, the timer4 interrupt routine is not being called for sometime when the memory is being erased. I want the timer4 to keep running at all the time. Is there any possible solution to this?

    timer4 interrupt routine is not reading from the memory being erased.

    Regards,
    Deepak

  • From what you posted, you are erasing the block at 0x6C000. The main flash of the TM4C1294 consists of four banks, split into a lower and an upper area with two banks interleaved in both. That gives you effectively two regions to work with, 0x0-0x3FFFF and 0x40000-0x7FFFF. Looking at the .map file you provided, I see you are using locations 0x0-0x4012F. Accessing the first 0x130 locations in the upper region while the block erase is on-going will stall the CPU. However, those locations are being used for the .cinit section which should only be read during startup. Therefore, I don't see why you would be stalling.

    Can you change the optimization level and reduce the code size? It would be interesting to see if the problem goes away if your program fits in the lower 256KB of flash. Are you running any periodic checksum or CRC on the flash memory?
  • My current code is using locations 0x0-0x4012F. Should I try to fit this in 0x0-0x3FFFF ?

    About the checksum, before this FlashErase function, I'm using FlashPBSave function to save parameter block. I believe this function calculates the checksum but that is only for the parameter block to be saved. And I don't think it's periodic because only when I get the data from the user I save both of then one by one. So firstly the parameter block is saved then the other data block.

    Regards,
    Deepak
  • Yes, try setting your optimization level to 4 and the speed/size to 0 just to see if we can get your code to fit into 0x-0x3FFFF.

    I am still trying to think of a better way to identify the real issue.

  • 3438.project_css_map.txt

    Hi Bob,

    I made the chnage you asked for. However, ( Opt 4 and speed 0 ) were giving me too many errors so I did ( Opt 2 speed 0 )which also decreased the size bellow 0x3FFFF. The current memory used is 0x0-0x2b938.  But still there's the issue with the timer. And I still don't understand why it doesn't happen on the first erase.

    I have attached the .map file for your verification.

  • Pardon - not using this '129 MCU family - I'm unable to add 'much' of  'specific to this MCU' use.     (yet I do applaud the, 'Shrinking of file size' - and subsequent observation/test.)

    Firm/I - attempt to tease out  (hidden) MCU Mechanisms  via

    • the CREATION of extremely small - new code files
    • these new files cleverly designed - and  (both)  'carefully & strategically placed' - w/in Flash memory   (per vendor Bob's guidelines - visited here - earlier

    The goal here - I believe - is 'Very much NOT to 'Bend the MCU' into 'hoped for' accommodation/compliance' - w/an already developed - large & complex program!      This existing program - already failing - (likely) due to its large size & multiplicity of functions - is highly likely to create 'MASKING ERRORS' (or conditions) which will 'confound & delay' the discovery of the 'dominant fault causing mechanism(s)!' 

    Instead - the always uber effective 'KISS' - would seek,  'Replication of  that exact (timer defeating) issue' -  but  via the BARE MINIMUM of code &  (necessary) accessory/peripheral operations.    I am proposing that  one (clearly) benefits by, 'First DRAINING the SWAMP' - and only then - slowly - methodically - rebuilding!    (creating a 'water-park' - instead!)

    Vendor's 'Bob' has provided the 'very necessary' Design Constraints - it is our job then - to best  'harness, properly direct & deploy'  his sound guidance.

    Such (far smaller) project renders the (likely) Failure Mechanism(s) - so much more exposed - thus FAR easier to identify!       (the 'SS' portion of 'KISS'  [strategic & systematic]  proves greatly difficult to implement - w/in any 'over-reaching'  code frame-work.    (i.e. almost any existing code - which cannot be expected - to 'properly  prepare for - thus anticipate'  - such unwanted issues!)      

    Again a 'bare-bones' (minimal) implementation - designed for eased,  'logically Sequenced/Probed Test/Verify' -  measured & confirmed at each/every step w/in the process - has 'LONG BEEN PROVEN'  to 'Work BEST!'      (this so as the greatly reduced number - and size - of the different code elements - escapes  most all of the 'masking errors' - simply  'INVITED IN' - by the 'too large existing programs' - always 'minus' such (advised & informed)  'error probing/detecting' Focus!)

    Once the source of the failure has been determined - the original/existing code (only then) can be properly examined - then sequentially added (and then always - 'piece by piece tested.')     Via such 'more disciplined approach'  the 'harmful bits/pieces' (much more quickly/easily SURFACE)  -  surely aiding their identification, understanding - then  removal.

  • Hi Deepak,

    Just wondering is your code first calling FlashPBInit() prior to writing the users parameter block?
  • Yes. I'm calling FlashPBInit() at the start of my code. It's called only once in the beginning. 

    Does that affects the timer? 

  • Hello Deepack. I would suggest to just take a look at the following forum's link. e2e.ti.com/.../226139
    If I'm guessing well, the answer of Sue Cozart may also apply to your case. In any case, what cb1_mobile suggests seems to me to be the most efficient way to track down the core source of the problem. In other words, devide and conquer. I always follow that rule during debugging. Also, if I recall well, when Cortex-M4 performs any read/write/erase from/to flash, no interrupts are serviced during that time but the WDG only. I'll maybe have some time tomorrow to check on the issue in more detail.
    Good luck,
    John
  • Hi Deepak,

    After Johns post read it dawns SYSTICK timer exist at NVIC level, seemingly timer INT would not be stopped. Otherwise RTOS bios/others require SYSTICK always tick tock. So it would seem CPU could no longer process C+ flash erase instructions if it suddenly stopped reloading count down register during flash writes. On a different note SYSTICK INT source is auto cleared by NVIC, another clue it may not become a victim of flash block writes.