Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

Writing CC2530 flash during run-time

Other Parts Discussed in Thread: CC2530

Hello,

My application needs a custom function which can update the cc2530F256's firmware during runtime, but I'm having a problem getting the function to work.

My program code resides in pages 0-8 of the flash memory. My firmware updating function is placed in a separate segment of memory on page 9 (created by adding the line "-P(CODE)updateFirmwareCodespace=0x4800-0x5000" to the linker command file) - so it can erase and re-program the program code without erasing itself.

When my program receives new program code, it's stored in flash pages 118-126. When the firmware updating function is called, it's supposed to erase pages 0-8, transfer the new code from pages 118-126 to pages 0-8, then restart with the new program. Specifically, I map the upper flash bank into XDATA, then use DMA to read the new code from XDATA and write it to the lower flash pages. Here's the C code:

void updateFirmware(void) @ "updateFirmwareCodespace"
{
   // disable interrupts
   IEN0 = 0;

   // map the FLASH bank containing new code into XDATA
   MEMCTR = (MEMCTR & 0xF8) | 7;

   // clear existing firmware
   for(uint8 pg = 0; pg<9; pg++)
   {
      FADDRH = pg<<1; FCTL |= 0x01;
      while(FCTL&0x80);
   }

   // set up DMA transfer of new firmware to 0x0000-0x47FF - this code borrowed from TI's hal_flash.c
   HAL_DMA_SET_ADDR_DESC0( &dmaCh0 );
   HAL_DMA_SET_ADDR_DESC1234( dmaCh1234 );
   halDMADesc_t *ch = &dmaCh0;
   HAL_DMA_SET_DEST(ch, &FWDATA);
   HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_USE_LEN);
   HAL_DMA_SET_LEN(ch, 16);
   HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE);
   HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE);
   HAL_DMA_SET_TRIG_SRC(ch, HAL_DMA_TRIG_FLASH);
   HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_1);
   HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_0);
   // The DMA is to be polled and shall not issue an IRQ upon completion.
   HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_DISABLE);
   HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS);
   HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH);
   HAL_DMA_CLEAR_IRQ(HAL_NV_DMA_CH);
   HAL_DMA_ARM_CH(HAL_NV_DMA_CH);
  
   // transfer new firmware 16 bytes at a time
   for(uint16 i = 0; i<1152; i+=16)
   {
      // set source of DMA transfer
      HAL_DMA_SET_SOURCE(ch, (0xB000 + i));

      // set destination of DMA transfer
      FADDRL = (uint8)i;
      FADDRH = (uint8)(i >> 8);
 
      // Trigger the DMA writes
      FCTL |= 0x02;

      // Wait until writing is done.
      while (FCTL & 0x80);
   }

   // restart the new program
   asm("LJMP 0x0000");

}

After running the program, I read the cc2530's flash and see that pages 0-8 have been cleared to 0xFF, the updater function code still resides in page 9, and the new code is in pages 118-126. That is, the function clears pages 0-8 but does not re-write them successfully. Can you give any insight into what I might be doing wrong?

Thanks very much!

Eric

  • You can't write the flash while running a program in flash (anywhere).

    You have to run the trigger for the DMA from RAM. Since it is only a few bytes to trigger the DMA, it is a simple task to put those few bytes in RAM (I push them on the stack) and then switch modes to put RAM in CODE space, LCALL the trigger snippet, wait for the write complete, RET back to FLASH code, and switch back to RAM as XDATA.

    The data sheet goes over this in some detail.

  • Where can i find those bytes and how do you push them on stack? And do i use LCALL in the function? Been trying this for a few weeks now and cant get it to work greatly appreiciate any help! Thanks! 

  • Actually, I decided against that approach - manipulating the stack is a right pain with the 8051 (emulating 16 bits, etc, etc).

    In the end, I used the DMA method and copied the small segment of 'trigger' code into 'system' ram (protected from the app ram on boot) where it stays permenently.

    The DMA trigger code is only a few bytes and the switch to RAM and back is very short and sweet.

    I will check, but I think I can post the code if you are interested.

  • Here is our code for flash fetch/write/copy. NOTE, I have exported it from the actual C file - we don't use the TI HAL (we have our own OS) and use a 'bios' on the CC25XX series radios that includes flash i/o so, in our system, these functions are exported to a function table.

    I don't think there any particular header dependencies that should cause problems.

    Other than excluding the headers and cutting out some unused code, this is as we use it (the tests in initFlash() won't work without our library).

    We dedicate DMA 0 to flash i/o - this saves a lot of flash i/o setup but may not be valid if you use DMA 0 for something else. We also use a 256 byte low RAM block as 'system' memory (apps 'can't' access) and we have a reserved location for the two code fragments (erase and write). You will need to place these somewhere convenient. I didn't bother changing the reserved sizes, but I seem to recall 32 bytes is very generous.

    [Yes, we separate the OS from the apps which are compiled, linked and loaded separately to the OS - often times, we use SDCC for the apps, oh and did I mention, we have over the air loading too ;-)]


    #define FLASHDRV_DMA_CH 0
    #define ERASE           0x01

    // DMA descriptor
    typedef struct
        {
        unsigned char srcAddrH;
        unsigned char srcAddrL;
        unsigned char dstAddrH;
        unsigned char dstAddrL;
        unsigned char xferLenV;
        unsigned char xferLenL;
        unsigned char ctrlA;
        unsigned char ctrlB;
        } flashdrvDmaDesc_t;

    static flashdrvDmaDesc_t flashdrvDmaDesc; // DMA descriptor table

    /////////////////////////////////////////////////////////////////
    static void __flashDmaTrigger(void) //@ "flashRamCode"
        {
        FCTL |= 0x02;         // Trigger the DMA writes.
        while (FCTL & 0x80);  // Wait until writing is done.
        }

    static void __flashErasePage(unsigned char page) //@ "flashRamCode"
        {
        // erase the page
        FADDRH = page << 1;
        FCTL |= ERASE;
        // CPU stalls until done

        // done
        }
    ////////////////////////////////////////////////////////////////

    static void erase(unsigned char page)
        {
        // disable interrupts
        __asm("PUSH 0xA8");/* IE */
        __asm("CLR  0xAF");/* IE.7 */
       
        // switch RAM into CODE
        unsigned char memctr = MEMCTR;
        MEMCTR |= 0x08;    // map RAM into CODE

        // call the erase snippet
        ((void (*)()) 0x8120)(page);

        // switch RAM to XDATA
        MEMCTR = memctr;    // map RAM into XDATA

        // done
        __asm("POP 0xA8");/* IE */
        }

    void fetch(word addr, byte *buf, word count)
        {
        // note this is a 4 byte aligned read from 18bit loc >> 2
        // count is # of UInt32

        // figure the page and the offset
        unsigned char pg = (((UInt32)addr) << 2) / kFlashPageSize;
        unsigned short offset = (((UInt32)addr) << 2) - pg * kFlashPageSize;

        // Calculate the offset into the containing flash bank as it gets mapped into XDATA.
        unsigned char *ptr = (unsigned char *)(offset + 0x8000) + ((pg % 16) * kFlashPageSize);
        unsigned char memctr = MEMCTR;  // Save to restore.
       
        pg /= 16;  // Calculate the flash bank from the flash page.
       
        // disable interrupts
        __asm("PUSH 0xA8");/* IE */
        __asm("CLR  0xAF");/* IE.7 */

        // map the containing flash bank into XDATA.
        MEMCTR = (MEMCTR & 0xF8) | pg;
       
        while (count--)
            {
            *buf++ = *ptr++;
            *buf++ = *ptr++;
            *buf++ = *ptr++;
            *buf++ = *ptr++;
            }
       
        // restore map
        MEMCTR = memctr;

        // done
        __asm("POP 0xA8");/* IE */
        }

    void write(unsigned short addr, unsigned char *buf, unsigned short cnt)
        {
        flashdrvDmaDesc.srcAddrH = (unsigned char) ((unsigned short)buf >> 8);
        flashdrvDmaDesc.srcAddrL = (unsigned char) (unsigned short) buf;
        flashdrvDmaDesc.xferLenV =
                (0x00 << 5) |               // use length
                (unsigned char)(unsigned short)(cnt >> 6);  // length (12:8). Note that cnt is flash word
        flashdrvDmaDesc.xferLenL = (unsigned char)(unsigned short)(cnt * 4);
       
        DMAIRQ &= ~( 1 << FLASHDRV_DMA_CH ); // clear IRQ
        DMAARM = (0x01 << FLASHDRV_DMA_CH ); // arm DMA
       
        FADDRL = (unsigned char) addr;
        FADDRH = (unsigned char)(addr >> 8);

        // disable interrupts
        __asm("PUSH 0xA8");/* IE */
        __asm("CLR  0xAF");/* IE.7 */
       
        // switch RAM into CODE
        unsigned char memctr = MEMCTR;
        MEMCTR |= 0x08;    // map RAM into CODE

        // call the trigger snippet
        ((void (*)()) 0x8100)();

        // switch RAM to XDATA
        MEMCTR = memctr;    // map RAM into XDATA

        // done
        __asm("POP 0xA8");/* IE */
        }


    void copy(unsigned short dst, unsigned short src, unsigned short count)
        {
        UInt32 buf[8];        // []*4 bytes on stack!

        for (; !(count < 8); count -= 8)
            {
            fetch(src, (byte *) buf, 8);
            write(dst, (byte *) buf, 8);
            src += 8;
            dst += 8;
            }

        if (count)
            {
            fetch(src, (byte *) buf, count);
            write(dst, (byte *) buf, count);
            }
        }


    void initFlash()
        {
        // put flash code into RAM
        unsigned char memctr = MEMCTR;
        MEMCTR = 0;    // map page 1 to XDATA
        memcpy((void *) 0x100, (void *) (0x8000 + (word) &__flashDmaTrigger), 32);
        memcpy((void *) 0x120, (void *) (0x8000 + (word) &__flashErasePage), 32);

        MEMCTR = memctr;

    #if FLASHDRV_DMA_CH == 0
        DMA0CFGH = (unsigned char) ((unsigned short) &flashdrvDmaDesc >> 8);
        DMA0CFGL = (unsigned char)  (unsigned short) &flashdrvDmaDesc;
        flashdrvDmaDesc.dstAddrH = (unsigned char) ((unsigned short)&FWDATA >> 8);
        flashdrvDmaDesc.dstAddrL = (unsigned char) (unsigned short) &FWDATA;
        flashdrvDmaDesc.ctrlA =
                (0x00 << 7) | // word size is byte
                (0x00 << 5) | // single byte/word trigger mode
                18;           // trigger source is flash
        flashdrvDmaDesc.ctrlB =
                (0x01 << 6) | // 1 byte/word increment on source address
                (0x00 << 4) | // zero byte/word increment on destination address
                (0x00 << 3) | // The DMA is to be polled and shall not issue an IRQ upon completion.
                (0x00 << 2) | // use all 8 bits for transfer count
                0x02; // DMA priority high
    #else
        # error "flashdrv DMA channel other than 0 is not supported"
    #endif

    #if 0
    // test FLASH
    #define TEST_ADDR 0x14014
        debug("Testing erase/write/fetch to 0x%06lx\n", (UInt32) TEST_ADDR);
        debug("bank %u\n", FlashBank(TEST_ADDR));
        debug("page %u\n", FlashPage(TEST_ADDR));
        debug("offset %u\n", FlashPageOffset(TEST_ADDR));
        erase(FlashPage(TEST_ADDR));
        dump(0xc010, 16, 1);

        byte buf[32];
        memcpy(buf, "Hello World\n", 13);
        write(FlashAddr(TEST_ADDR), buf, 4);

        memset(buf, 0, sizeof(buf));
        fetch(FlashAddr(TEST_ADDR), buf, 4);
       
        copy(FlashAddr(TEST_ADDR + 32), FlashAddr(TEST_ADDR), 4);

        debug("%s\n", buf);
    #endif
        }


  • Thanks for the replies, i have finally succeeded in reprogramming it during runtime! :)

  • hi, I have the same question as you, which writes  contains in the last page in running time. so how did you solve this problem?  JUST can make it in DEBUG mode, however failure in normal power supply mode. PLEASE help me, it's so urgent. THANK YOU VERY MUCH!

  • "Sir,can you please explain how the fetch function is taking the address and also
    flashdrvDmaDesc.ctrlA |=18; // trigger source is flash"

    Someone asked this question (I got an email), but I don't see it in the thread. Answering the questions last first;

    1)

    flashdrvDmaDesc.ctrlA is described in the datasheet - I have long since forgotten what all the bits mean, you will need to review the datasheet.

    2)

    Flash can only be read/written on 4 byte boundaries.

    This means flash is treated like and array of 4 byte integers and you can use a 2 byte word to index the whole flash.

    Thus, to map an 18 bit 'flash byte' address to a 2 byte 'flash integer' address, you simply shift the address right 2 bits. This is the address passed in to fetch().

    Inside fetch() the address is then decomposed into a flash page and an offset to the 'integer' required (figure the page and the offset).

    Since the required flash page must also be mapped into XDATA, you also need the mapped XDATA address from which to actually read the data (Calculate the offset ... as it gets mapped into XDATA).

    Once the mappings are done, the system swaps the right page in to XDATA and does then does the read.

    fetch() can only do 4 byte aligned reads - for reading specific bytes, you will need to add an additional layer to pull the byte you actually want.

    Generally, byte reads/writes are a bad idea (time/complexity and limitations on flash byte writes). I organize everything I read/write to be 4 byte aligned via a simple flash record management system that only deals in 4byte aligned records.

  • Thanks for the reply sir,i have one more doubt its written in the datasheet that FADDRH:FADDRL flash high and low start address
    (This is the 16 MSBs of the 18-bit byte address). I am unable to understand this.Can you simplify .?

    Also sir my new firmware that i stored in the flash  is written onto address(starting) 0X28000(Bank 2),but when i passed this address i am getting wrong page no and offset value.

    according to this address when shifting it left by 2 (<<2) i get A0000 which when divided by 2048(page size).page no comes out to be 320 which i not possible.

    What possibly i am doing wrong in my calculation?

  • Hello

    I am getting a problem while updating firmware in cc2530. From flash memory i have successfully updated the image into the upper XBANK moving the data to the lower XBANK through RAM is the problem?

  • Hello Sir,
    I am facing some problems regarding memory mapping and looking for the solutions
    my question is about the snippet in your code how can we figure out the address 0x8100 in

    call the erase snippet
    ((void (*)()) 0x8120)(page) //how??
    I have stored the new data/firmware onto flash from pages 16 that is from bank 1 and y original code is running in bank 0.how do i switch bank 1 to bank0 through RAM ?
    i am unable to figure out how flash-->DMA-->XDATA are getting connected?
    can you tell me what i am doing wrong.
  • Ravindra Kant said:

    Thanks for the reply sir,i have one more doubt its written in the datasheet that FADDRH:FADDRL flash high and low start address
    (This is the 16 MSBs of the 18-bit byte address). I am unable to understand this.Can you simplify .?

    Also sir my new firmware that i stored in the flash  is written onto address(starting) 0X28000(Bank 2),but when i passed this address i am getting wrong page no and offset value.

    according to this address when shifting it left by 2 (<<2) i get A0000 which when divided by 2048(page size).page no comes out to be 320 which i not possible.

    What possibly i am doing wrong in my calculation?

    Not sure if I can explain it any more clearly. At the risk of making things worse;

    You have up to 256kb of flash. Divide this by 4 is 64k 4 byte words. Thus you have 64k dwords (4 byte words) of flash.

    You can address an array of 64k dwords using a 2 byte unsigned integer (0 ->0xffff).

    You create the >dword< address of the >byte< address 0x28000 by >right< shifting 2 bits to 0xA000 (right shifting 2 bits is the same as divide by 4).

    0xA000 is the index into >dword< aligned flash memory where the byte at byte address 0x28000 is located.

    byte flash[0x28000] == dword flash[0xa000]

    What you are trying to do seems to be beyond your level of understanding of the way digital systems work. If this is something you still can't grasp, I suggest you don't post further until you understand the way memory address aliasing works.

  • Ravindra Kant said:


    call the erase snippet
    ((void (*)()) 0x8120)(page) //how??
    I have stored the new data/firmware onto flash from pages 16 that is from bank 1 and y original code is running in bank 0.how do i switch bank 1 to bank0 through RAM ?
    i am unable to figure out how flash-->DMA-->XDATA are getting connected?
    can you tell me what i am doing wrong.

    The 25xx users guide clearly describes how to page flash into memory. It also describes the system memory map, which can certainly be confusing at first, especially if you are not familiar with the 8051.

    Fundamentally, the 8051 can address a number of address spaces. Historically some of these were 'on' chip and some were 'off' chip.

    There are two memory spaces you are really interested in - CODE space and XDATA space.

    Both address spaces are limited to 64kb in size, CODE space can only be read by the 8051 whilst reading instructions and XDATA can only be read/writen as part of an xdata i/o instruction.

    Now, the 25XX has both FLASH and SRAM and using two memory control registers you can map pages of flash OR sram into either CODE memory space or XDATA memory space (see SWRU191C p29).

    I maintain two function snippets in SRAM at addresses 0x0100 and 0x0120. These function snippets are assembly code to 1) start a flash erase and 2) start a dma flash read/write. They are very short, very simple and (as I recall) detailed in the user guide.

    To use these functions, SRAM must be mapped into CODE space and that can only happen in the upper half of the code space (Fig 2-3 p29). So, when mapped into code space, these addresses become CODE addresses 0x8100 and 0x8120. How sram gets mapped in is detailed both in the user guide and in my code above. Since they are function entry points, they can be used in place of function names (yes, I could have used a typedef, but I didn't).

    This then satisfies the requirement that flash can only be modified from code running in SRAM.

  • If anyone is interested - we maintain an SDK supporting the 25XX, including flash management, OTA, proprietary mode RF and much more.
    You can ping me via klinkenbecker at yahoo.com
  • sir can you please tell me how can we declare a function in xdata using IAR workbench
  • sir can you please tell me how can we declare a function in xdata using IAR workbench in c
  • Ravindra Kant said:
    sir can you please tell me how can we declare a function in xdata using IAR workbench

    The IAR docs cover this in detail.

    Not wanting to be evasive, but this question belongs elsewhere and will only serve to confuse the topic of this thread.

  • Hello Mr Klinkenbecker,

    I understood that i have to place the functions in ram specially erase and write to perform the deletion of current firmware.According to the program the erase function is placed at location 0x0120 ,but now when i call erase function and tried to erase the page from page no 0 it shows IDATA stack overflow is shown. A

    when i call the break operation it shows location 0X8120 --AJMP and the compiler is at halt here its not getting forward.

    do i have to make amendments in the linker file too with -Q option (referred to IAR manual).

  • It is impossible to know what you did to get to that situation without more information.

    However, if you are running code in page 0 that then calls a ram function to erase page 0, then the ram function has nothing to return to - you just erased it.

    Your screen capture above shows something at 0x0520. If that is your erase function in ram, then mapping that into the code space will result in an address of 0x8520 to call, not 0x8120.

    You do not have to mess with the linker options to make it work.

    I suggest you make a very simple program (that you load normally into low flash) to do the following;

    - set up a function in ram that >just< returns (it doesn't matter where, just don't 'hit' anything inside your program ram usage)
    - map ram into code space (verify you can see the RAM and the function in code space using debugger)
    - make sure that you can single step into your ram function and step addresses match the appropriate flash/ram transitions
    - unmap ram from code space
    - verify that ram is indeed unmapped (using debugger)

    If you can do this, you have one of the basic building blocks working.

    Fundamentally, because of the design of the CC8051 memory mapping architecture, you should generally resist erasing page0 as part of an OTA system update. It is possible to do, you just have a more complicated task to make it work, but more importantly, if you erase page 0 and then get a power outage (low battery, user pulls battery, etc), your device is now bricked and cannot be used without external re-programming.
  • I should clarify - you don't >need< to use the linker, but you can use the linker to place your RAM functions in the RAM segment.

    I didn't do that because they are so few bytes and they don't ever change that I just coded them as data and maintain them in a protected 'well known location' in low ram. If you want the linker to keep track, then, by all means use it.

    We load multiple run-time applications images over the top of one another and we protect low memory for 'system usage' via our own application link file. That doesn't use RAM functions, but it does prevent loaded applications using low memory (ram >and< flash)
  • Sir,

    I have successfully erased first 4 pages page(0-4) but it throws an error IDATA overflow when i press ok four times on the error it erases the pages.

    so my question why possibly i m getting IDATA error and why pages are not getting erased after page 4.

    this all i checked when i am running my application with cc debugger but when application is run as standalone nothing happened.

  • Ravindra Kant said:

    Still my problem is that I get the error IDATA stack overflow but the particular page that is HalFlashErase(0) has been erased.

    You are erasing the page you are running your program from. When __erase() returns it returns to an erased page.

    If you insist on erasing page 0 you have to approach the problem very differently.

    Ravindra Kant said:

    the problem is once i have placed the function into RAM than do i have to call them manually or those function will get called automatically?

    Manually, there is no concept of 'automatically'. The only 'automation' in the CC25XX are interrupts or DMA - interrupts should (probably) be disabled and DMA doesn't call functions.

    You should also check your memory map to ensure that 0x0100 is not used by the linker. Use the IAR map options to get the memory map.

    Make sure you copy the erase function to a location that is not used by the linker.

  • Sir,
    why is dump function in the code you mentioned ,what is its purpose??
  • Hello Sir Klinkenbecker
    Can you tell how to define Additional Interrupt Vector table inside any bank apart from Bank 0 and then jump Interrupt vector from root bank to the newly defined vector table????

    Thankss!!!
  • dump() is one of our Embedded System support functions that 'dumps' the content of memory as hex/char display.
    For example, from an ARM running our same embedded system (that I happen to be working on);

    200008e4/0000: 45 57 02 14 08 00 00 00 03 00 35 40 00 00 2f 00 EW........5@../.
    200008f4/0010: 7d 00 08 00 7d 00 08 00 7d 00 08 00 00 00 00 00 }...}...}.......

    dump() uses the bios debug output handler, which is generally connected to the uart port but, in the example here, was connected to an Ethernet port using a simple i/o protocol.
  • If you want to relocate the 'system' interrupt handler address (as you can on an M3 for example), you can't.

    If you want to redirect the interrupt vectors 'elsewhere', that is quite trivial, just place JMP instructions in the table.

    I would guess you are looking for ways to safely erase page 0 >there are none<, or possibly looking for ways to run an application from a page other than page0 - that is possible by redirecting the vectors using JMP.

    If you want to robustly do OTA updates, you have to partition your code into page0 code and the rest. You then organize your partitioning so that page0 such that;

    1) code is not big - small code == fewer bugs
    2) can safely handle a reset at anytime during an OTA event
    3) test the heck out of your page0 code!!

    In practice, for OTA on these devices and unless you really know what you are doing, you should only have a loader in page0. The application would then reside in page1 and above with interrupts redirected to it using JMP.

    Addendum:

    I actually mean bank0 and bank1 - not page0 and page1. If you are using the 'bank switched' compiler model, you will also need to manage the jump tables in bank0 which will need to be updated as part of OTA. Loader would be in bank0 low memory and the application would start on the next page boundary above the loader (so you can safely erase it without clobbering the loader).

  • hello sir,
    thanks !!
    Can i check at which address my interrupt vector table is located in the root bank?

    -Z(CODE)INTVEC=0
    -Z(CODE)CSTART=_NEAR_CODE_START-(_CODEBANK_START-1)

    The above two lines i have taken from the linker file but are confusing as to say I assunmed that INTVEC is at the starting of interrupt vector table INTVEC = 0 means at Bank 0 and now i defined one more INTVEC at an address =0X18000
    Is it correct?

    how to make the firmware decide that now jump to the newly defined vector table like you explained very clearly
    "interrupts redirected to it using JMP."
  • Ravindra Kant said:

    -Z(CODE)INTVEC=0
    -Z(CODE)CSTART=_NEAR_CODE_START-(_CODEBANK_START-1)

    The above two lines i have taken from the linker file but are confusing as to say I assunmed that INTVEC is at the starting of interrupt vector table INTVEC = 0 means at Bank 0 and now i defined one more INTVEC at an address =0X18000

    Yes, that is correct. However, you also need to change the CODE start addresses and rebuild the startup code to match. I can't exactly remember the details, but it is pretty obvious - you will get a linker error telling you which file needs changing. Note also that, for probably very lame reasons, IAR cannot load a program that starts in any bank other than bank0. Even just one byte into bank0 and everything works, but any other bank and it doesn't.

    Ravindra Kant said:

    "interrupts redirected to it using JMP."

    Here you need assembly code - short of doing it for you, which I'm not going to do, you will need to understand 8051 assembly code, how the 8051 starts up and how it jumps to it's interrupt vectors.

    If you don't know these things, you will have a lot of trouble making it work and you will need to spend some time figuring it out. If you don't have the startup code for some reason, it will be much, much harder (but not impossible).

  • Hello Sir klinkenbecker!

    I have declared functions in RAM 

    #pragma location = "FLASHtoRAM"  

    static void __flashDmaTrigger(void)@"FLASHtoRAM"
    {

    FCTL |= 0x02; // Trigger the DMA writes.
    while (FCTL & 0x80); // Wait until writing is done.
    }

    static void __flashErasePage(unsigned char page)@"FLASHtoRAM"
    {
    if(ETHDEBUG){printf("Erase:");}

    FADDRH = page << 1;
    FCTL |= ERASE;
    }

    unsigned char memctr=MEMCTR;
    MEMCTR=0;
    memcpy((void *)0x200,(void *)(8000 +(uint8)&__flashErasePage),32);
    memcpy((void *)0x240,(void *)(8000 +(uint8)&__flashDmaTrigger),32);
    MEMCTR=memctr;

    I  have also defined this segment at location -P(CODE)FlashtoRAM=0x6000-0x6500

    then i called this function inside the HalFlashErase and HalFlashWrite

     

    but when i called the function inside the main that is HalFlashErase(1) 

    and then HalFlaseWrite(1).

    I dont found any changes yeah i dont get that IDATA stack overflow error

    and i found out after debugging that something has been written at the location 0x6000 Image makes it clear


    and also at location in the xdata at location 0x200 and 0x240


    can you guide me sir..???