SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Reprogramm flash from programm

Tue Jul 06, 2021 2:19 pm

Hi,

I'm pretty sure it is possible, but I'm wondering whats the best way to achieve it.
I would like to update the pico over a serial protocol - so the programm has to reprogramm itself.

what about this one:

Flash size is not a problem, I could receive the new binary and store it somewhere in the flash. (So I don't have to care about all the protocol functions beeing in RAM)
Call a method __not_in_flash, within that f() disable second core, isr and then copy the new binary to XIP_BASE and restart

Would that be possible? Do i miss something?

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 876
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Reprogramm flash from programm

Tue Jul 06, 2021 5:26 pm

that should be fine.

dthacher
Posts: 85
Joined: Sun Jun 06, 2021 12:07 am

Re: Reprogramm flash from programm

Fri Jul 09, 2021 2:06 am

Normally you create some kind of bootloader which reserves a section of flash for the update. This has longer boot. Update images need adjustment with scripts usually, to enable being called by bootloader. Bootloader is always called first and rarely gets updated. Updating bootloader is bit of a dance depending on design.

You could reserve a known section of flash for update logic. This could be used as ram function or not. Only runs for update. Cannot be overwritten or updated without a dance. All update images must be aware of its existence and how to call it. If they do not know how to do this you will not be able update.

You could include a ram function with every update image which can be used to update. Only runs as needed. However if you fail to include it you will not be able to update.

In summary, it is possible. I think the ram function may be the easier way to go.


Some bootloaders support multiple images. They mark an image as runnable. In this case one of the images could update an inactive image. You should be able to update the image select from inside the runnable image. Reboot would be required to make the swap, but that is kind turn regardless generally speaking.

Note this is not a very secure approach. This is also a little more complicated. I have also seen/heard of servers boot selecting embedded devices using something like this. Ironically they were concerned with security...

SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Re: Reprogramm flash from programm

Sun Jul 25, 2021 2:10 pm

so now i tried a proof-of-concept, but somehow I got stuck..

I read a UF2 File over Serial (USB) and store the data in the flash with an offset (m_flashoffset) of + 0x0010 0000.
Thats works fine.

After that I also compared the contect of flash at 0x0000 0000 (original programm uf2 loaded with stock bootloader) with the flash's contect at 0x0010 0000 (same UF2 but loaded with my programm over serial and stored there.
There are no differences detected.

So i tried to update the flash with this function:

Code: Select all

  void __not_in_flash_func(UpdateFlash)()
  {
    noInterrupts();
    rp2040.idleOtherCore();
    watchdog_enable(10000, false);	// 10s should be enough, call it here instead of watchdog_reboot afterwards because watchdog functions are in flash

    // copy data sector by sector
    uint32_t new_binary_start_ram = m_firstTargetAdr + m_flashoffset; // in RAM address space, so XIP_BASE ist not substracted
    uint32_t new_binary_length = m_nextTargetAdr - m_firstTargetAdr;
    uint32_t prog_flash_start = m_firstTargetAdr - XIP_BASE; // addresses in UF2 are in RAM address space, substrat XIP_BASE to get FLASH address
    uint32_t prog_flash_start_ram = m_firstTargetAdr; // addresses in UF2 are in RAM address space

    uint32_t num_sectors = (new_binary_length / FLASH_SECTOR_SIZE) + 1;

    for(int i = 0;i<num_sectors;i++)
    {
      uint8_t *sector_new_start = (uint8_t*)(new_binary_start_ram + (i*FLASH_SECTOR_SIZE));
      uint8_t *sector_old_start = (uint8_t*)(prog_flash_start_ram + (i*FLASH_SECTOR_SIZE));

      uint32_t prog_flash_sectorstart = prog_flash_start + (i*FLASH_SECTOR_SIZE);

      if(memcmp(sector_new_start,sector_old_start,FLASH_SECTOR_SIZE))
      {
        //true if mem does not match, so copy

        flash_range_erase (prog_flash_sectorstart, FLASH_SECTOR_SIZE);
        flash_range_program(prog_flash_sectorstart, sector_new_start, FLASH_SECTOR_SIZE);
      }      
    }

    while(1)
      ;
    // restart with watchdog

    return;
  }
after the restart through WD the device does not boot the new programm but goes to UF2 Bootloader.

I also tried to print out the adresses for the flash functions but this is only possible at a dry run, but it seems ok to me:

Code: Select all

flash_range_erase 0x0 0x1000
flash_range_program 0x0 0x10100000 0x1000

flash_range_erase 0x1000 0x1000
flash_range_program 0x1000 0x10101000 0x1000

flash_range_erase 0x2000 0x1000
flash_range_program 0x2000 0x10102000 0x1000

flash_range_erase 0x3000 0x1000
flash_range_program 0x3000 0x10103000 0x1000

flash_range_erase 0x4000 0x1000
flash_range_program 0x4000 0x10104000 0x1000

flash_range_erase 0x5000 0x1000
flash_range_program 0x5000 0x10105000 0x1000

flash_range_erase 0x6000 0x1000
flash_range_program 0x6000 0x10106000 0x1000

flash_range_erase 0x7000 0x1000
flash_range_program 0x7000 0x10107000 0x1000

flash_range_erase 0x8000 0x1000
flash_range_program 0x8000 0x10108000 0x1000

flash_range_erase 0x9000 0x1000
flash_range_program 0x9000 0x10109000 0x1000

flash_range_erase 0xA000 0x1000
flash_range_program 0xA000 0x1010A000 0x1000

flash_range_erase 0xB000 0x1000
flash_range_program 0xB000 0x1010B000 0x1000

flash_range_erase 0xC000 0x1000
flash_range_program 0xC000 0x1010C000 0x1000

flash_range_erase 0xD000 0x1000
flash_range_program 0xD000 0x1010D000 0x1000

flash_range_erase 0xE000 0x1000
flash_range_program 0xE000 0x1010E000 0x1000

flash_range_erase 0xF000 0x1000
flash_range_program 0xF000 0x1010F000 0x1000

flash_range_erase 0x10000 0x1000
flash_range_program 0x10000 0x10110000 0x1000
Any ideas what could be go wrong here?

I already ordered some more pi picos to use as debugger.

SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Re: Reprogramm flash from programm

Mon Jul 26, 2021 8:57 am

I think I may have found the problem - yet no idea for a solution.

While I checked the both flash_range_erase and flash_range_programm for beeing in RAM (yes they are) I missed that they call some function at the beginning NOT in RAM...

it seems that I have to write my own flash programming routines.. damn.

Or do you have any idea how I can make the flash functions (and all functions called in them) to be executed from ram?

Code: Select all

void __no_inline_not_in_flash_func(flash_range_erase)(uint32_t flash_offs, size_t count) {
#ifdef PICO_FLASH_SIZE_BYTES
    hard_assert(flash_offs + count <= PICO_FLASH_SIZE_BYTES);
#endif
    invalid_params_if(FLASH, flash_offs & (FLASH_SECTOR_SIZE - 1));
    invalid_params_if(FLASH, count & (FLASH_SECTOR_SIZE - 1));
    void (*connect_internal_flash)(void) = (void(*)(void))rom_func_lookup(rom_table_code('I', 'F'));
    void (*flash_exit_xip)(void) = (void(*)(void))rom_func_lookup(rom_table_code('E', 'X'));
    void (*flash_range_erase)(uint32_t, size_t, uint32_t, uint8_t) =
        (void(*)(uint32_t, size_t, uint32_t, uint8_t))rom_func_lookup(rom_table_code('R', 'E'));
    void (*flash_flush_cache)(void) = (void(*)(void))rom_func_lookup(rom_table_code('F', 'C'));
    assert(connect_internal_flash && flash_exit_xip && flash_range_erase && flash_flush_cache);
    flash_init_boot2_copyout();

    // No flash accesses after this point
    __compiler_memory_barrier();

    connect_internal_flash();
    flash_exit_xip();
    flash_range_erase(flash_offs, count, FLASH_BLOCK_SIZE, FLASH_BLOCK_ERASE_CMD);
    flash_flush_cache(); // Note this is needed to remove CSn IO force as well as cache flushing
    flash_enable_xip_via_boot2();
}

SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Re: Reprogramm flash from programm

Mon Jul 26, 2021 11:29 am

My idea to solve this problem was to get rid of that sector-by-sector flashing and do it in one call - the important part of the function is in ram.

But - erase and program are seperate function.
So i combined these two to:

Code: Select all

void __no_inline_not_in_flash_func(flash_range_erase_and_program)(uint32_t flash_offs, const uint8_t *data, size_t count) {
#ifdef PICO_FLASH_SIZE_BYTES
    hard_assert(flash_offs + count <= PICO_FLASH_SIZE_BYTES);
#endif
    invalid_params_if(FLASH, flash_offs & (FLASH_PAGE_SIZE - 1));
    invalid_params_if(FLASH, count & (FLASH_PAGE_SIZE - 1));
    void (*connect_internal_flash)(void) = (void(*)(void))rom_func_lookup(rom_table_code('I', 'F'));
    void (*flash_exit_xip)(void) = (void(*)(void))rom_func_lookup(rom_table_code('E', 'X'));
    void (*flash_range_program)(uint32_t, const uint8_t*, size_t) =
        (void(*)(uint32_t, const uint8_t*, size_t))rom_func_lookup(rom_table_code('R', 'P'));
	void (*flash_range_erase)(uint32_t, size_t, uint32_t, uint8_t) =
        (void(*)(uint32_t, size_t, uint32_t, uint8_t))rom_func_lookup(rom_table_code('R', 'E'));
    void (*flash_flush_cache)(void) = (void(*)(void))rom_func_lookup(rom_table_code('F', 'C'));
    assert(connect_internal_flash && flash_exit_xip && flash_range_erase && flash_range_program && flash_flush_cache);
    flash_init_boot2_copyout();

    __compiler_memory_barrier();

    connect_internal_flash();
    flash_exit_xip();
	flash_range_erase(flash_offs, count, FLASH_BLOCK_SIZE, FLASH_BLOCK_ERASE_CMD);
    flash_range_program(flash_offs, data, count);
    flash_flush_cache(); // Note this is needed to remove CSn IO force as well as cache flushing
    flash_enable_xip_via_boot2();
}

and call it this way:

Code: Select all

  void __not_in_flash_func(UpdateFlash)()
  {

    noInterrupts();
    rp2040.idleOtherCore();
    watchdog_enable(10000, false);

    // copy data sector by sector
    uint32_t new_binary_start_ram = m_firstTargetAdr + m_flashoffset - XIP_BASE + XIP_BYPASS_CACHE_ADDR_BASE; // in RAM address space, so XIP_BASE ist not substracted
    uint32_t new_binary_length = m_nextTargetAdr - m_firstTargetAdr;
    uint32_t prog_flash_start = m_firstTargetAdr - XIP_BASE; // addresses in UF2 are in RAM address space, substrat XIP_BASE to get FLASH address
    uint32_t prog_flash_start_ram = m_firstTargetAdr - XIP_BASE + XIP_BYPASS_CACHE_ADDR_BASE; // addresses in UF2 are in RAM address space

    uint32_t num_sectors = (new_binary_length / FLASH_SECTOR_SIZE) + 1;

    uint8_t *new_binary_start_ram_p = (uint8_t*)new_binary_start_ram;

    //flash_range_erase (prog_flash_start, num_sectors*FLASH_SECTOR_SIZE);
    //flash_range_program(prog_flash_start, new_binary_start_ram_p, num_sectors*FLASH_SECTOR_SIZE);
    flash_range_erase_and_program(prog_flash_start, new_binary_start_ram_p, num_sectors*FLASH_SECTOR_SIZE);
    
    while(1);

but it is STILL not working. After the Update and restart (also power off-on) - pi pico stays in the Bootloader.

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 876
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Reprogramm flash from programm

Mon Jul 26, 2021 2:22 pm

they do not call anything not in RAM (or ROM), you do not need to write your own routines

SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Re: Reprogramm flash from programm

Mon Jul 26, 2021 7:34 pm

kilograham wrote:
Mon Jul 26, 2021 2:22 pm
they do not call anything not in RAM (or ROM), you do not need to write your own routines
thank you for your answer.

The line directed me to that idea.

Code: Select all

    // No flash accesses after this point
    __compiler_memory_barrier();
Now I see that that was wrong. I think I didn't got the fact that these function are in the BootROM at this moment.


But do you have any idea what could be the problem? This is driving me crazy !

Thats my current UpdateFlash function:

Code: Select all

void __not_in_flash_func(UpdateFlash)()
  {
    Serial.println("UpdateFlash:");


    // copy data sector by sector
    uint32_t new_binary_start_ram = m_firstTargetAdr + m_flashoffset; // in RAM address space, so XIP_BASE ist not substracted
    uint32_t new_binary_length = m_nextTargetAdr - m_firstTargetAdr;
    uint32_t prog_flash_start = m_firstTargetAdr - XIP_BASE; // addresses in UF2 are in RAM address space, substrat XIP_BASE to get FLASH address
    uint32_t prog_flash_start_ram = m_firstTargetAdr; // addresses in UF2 are in RAM address space

    uint32_t num_sectors = (new_binary_length / FLASH_SECTOR_SIZE) + 1;

    uint8_t *new_binary_start_ram_p = (uint8_t*)new_binary_start_ram;
    uint8_t *prog_flash_start_ram_p = (uint8_t*)prog_flash_start_ram;

    bool new_binary_changed_sector = memcmp(new_binary_start_ram_p, prog_flash_start_ram_p, num_sectors*FLASH_SECTOR_SIZE);

    Serial.print("prog_flash_start: 0x");
    Serial.println(prog_flash_start, HEX);
    Serial.print("num_sectors*FLASH_SECTOR_SIZE: 0x");
    Serial.println(num_sectors*FLASH_SECTOR_SIZE, HEX);
    Serial.print("new_binary_start_ram_p: 0x");
    Serial.println((uint32_t)new_binary_start_ram_p, HEX);
    Serial.print("prog_flash_start_ram_p: 0x");
    Serial.println((uint32_t)prog_flash_start_ram_p, HEX);
    Serial.print("new_binary_changed_sector: 0x");
    Serial.println(new_binary_changed_sector);

    delay(500);
    

    noInterrupts();
    rp2040.idleOtherCore();
    //watchdog_enable(10000, false);

    flash_range_erase (prog_flash_start, num_sectors*FLASH_SECTOR_SIZE);
    flash_range_program(prog_flash_start, new_binary_start_ram_p, num_sectors*FLASH_SECTOR_SIZE);


    rp2040.resumeOtherCore();
    interrupts();

    delay(500);

    Serial.println("Update Finished.");
    return;
    }
And that is the output:
UpdateFlash:
prog_flash_start: 0x0
num_sectors*FLASH_SECTOR_SIZE: 0x11000
new_binary_start_ram_p: 0x10100000
prog_flash_start_ram_p: 0x10000000
new_binary_changed_sector: 0x0

what you can see here:
I start erasing and programming at 0x00
The pointer I use for flash programming was used in the previous memcmp and it detected no difference !
But - after calling flash_range_erase and flash_range_program, it gets lost. It should go on, the flash contect SHOULD not have changed.
After a powercycle - UF2 Bootloader...

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 876
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Reprogramm flash from programm

Mon Jul 26, 2021 7:48 pm

you can't read from flash during flash_range_program (which you are doing because you are passing a flash pointer as the source)

you will need to copy from flash->RAM and RAM->Flash in a loop.

SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Re: Reprogramm flash from programm

Tue Jul 27, 2021 9:41 am

Thank you very much. What a stupid mistake.

I was really excited to see it working, finally but... unfortunately I did not get it working :cry:

thats my function. Now I write sector-by-sector, and the data is buffered in sram.

Code: Select all

void __not_in_flash_func(UpdateFlash)()
  {
    Serial.println("UpdateFlash:");


    uint32_t new_binary_start_ram = m_firstTargetAdr + m_flashoffset; // in RAM address space, so XIP_BASE ist not substracted
    uint32_t new_binary_length = m_nextTargetAdr - m_firstTargetAdr;
    uint32_t prog_flash_start = m_firstTargetAdr - XIP_BASE; // addresses in UF2 are in RAM address space, substrat XIP_BASE to get FLASH address
    uint32_t prog_flash_start_ram = m_firstTargetAdr; // addresses in UF2 are in RAM address space

    uint32_t num_sectors = (new_binary_length / FLASH_SECTOR_SIZE) + 1;

    
    #if !DRYRUN
    noInterrupts();
    rp2040.idleOtherCore();
    #endif
    watchdog_enable(10000, false);


    uint8_t copybuffer[FLASH_SECTOR_SIZE];

    for(int i = 0;i<num_sectors;i++)
    {
      uint8_t *sector_new_start = (uint8_t*)(new_binary_start_ram + (i*FLASH_SECTOR_SIZE));
      uint8_t *sector_old_start = (uint8_t*)(prog_flash_start_ram + (i*FLASH_SECTOR_SIZE));

      uint32_t prog_flash_sectorstart = prog_flash_start + (i*FLASH_SECTOR_SIZE);

      #if DRYRUN
      Serial.print("Sector No: 0x");
      Serial.println(i,HEX);
      Serial.print("Source Adr: 0x");
      Serial.println((uint32_t)sector_new_start,HEX);
      Serial.print("Target Adr: 0x");
      Serial.println((uint32_t)sector_old_start,HEX);
      #endif

      for(int k=0;k<FLASH_SECTOR_SIZE;k++)
          copybuffer[k] = *(sector_new_start+k);

      #if DRYRUN
      if(memcmp(copybuffer,sector_old_start,FLASH_SECTOR_SIZE))
        Serial.println("no match");
      else
        Serial.println("match");
      #endif

      {
        //true if mem does not match, so copy

        #if DRYRUN
        Serial.print("flash_range_erase 0x");
        Serial.print(prog_flash_sectorstart,HEX);
        Serial.print(" 0x");
        Serial.println(FLASH_SECTOR_SIZE,HEX);
        #else
        flash_range_erase (prog_flash_sectorstart, FLASH_SECTOR_SIZE);
        #endif


        #if DRYRUN
        Serial.print("flash_range_program 0x");
        Serial.print(prog_flash_sectorstart,HEX);
        Serial.print(" 0x");
        Serial.print((uint32_t)copybuffer,HEX);
        Serial.print(" 0x");
        Serial.println(FLASH_SECTOR_SIZE,HEX);
        Serial.println("");
        #else
        flash_range_program(prog_flash_sectorstart, copybuffer, FLASH_SECTOR_SIZE);
        #endif
      }
    }

    while(1);    // restart with watchdog
    return;
  }

It does not work. After reboot, the new binary does not do anything visible from outside. But - it does not anymore stay in the Bootloader.

That is the output of the dryrun trying to flash the identical binary over the current one.
The copybuffer is even compared to the content of the target position in flash, and it reports no difference. But - after flashing that copybuffer, it stops working. So something must still go wrong here...

Driving me nuts..

Code: Select all

UpdateFlash:
Sector No: 0x0
Source Adr: 0x10100000
Target Adr: 0x10000000
match
flash_range_erase 0x0 0x1000
flash_range_program 0x0 0x20040FC8 0x1000

Sector No: 0x1
Source Adr: 0x10101000
Target Adr: 0x10001000
match
flash_range_erase 0x1000 0x1000
flash_range_program 0x1000 0x20040FC8 0x1000

Sector No: 0x2
Source Adr: 0x10102000
Target Adr: 0x10002000
match
flash_range_erase 0x2000 0x1000
flash_range_program 0x2000 0x20040FC8 0x1000

Sector No: 0x3
Source Adr: 0x10103000
Target Adr: 0x10003000
match
flash_range_erase 0x3000 0x1000
flash_range_program 0x3000 0x20040FC8 0x1000

Sector No: 0x4
Source Adr: 0x10104000
Target Adr: 0x10004000
match
flash_range_erase 0x4000 0x1000
flash_range_program 0x4000 0x20040FC8 0x1000

Sector No: 0x5
Source Adr: 0x10105000
Target Adr: 0x10005000
match
flash_range_erase 0x5000 0x1000
flash_range_program 0x5000 0x20040FC8 0x1000

Sector No: 0x6
Source Adr: 0x10106000
Target Adr: 0x10006000
match
flash_range_erase 0x6000 0x1000
flash_range_program 0x6000 0x20040FC8 0x1000

Sector No: 0x7
Source Adr: 0x10107000
Target Adr: 0x10007000
match
flash_range_erase 0x7000 0x1000
flash_range_program 0x7000 0x20040FC8 0x1000

Sector No: 0x8
Source Adr: 0x10108000
Target Adr: 0x10008000
match
flash_range_erase 0x8000 0x1000
flash_range_program 0x8000 0x20040FC8 0x1000

Sector No: 0x9
Source Adr: 0x10109000
Target Adr: 0x10009000
match
flash_range_erase 0x9000 0x1000
flash_range_program 0x9000 0x20040FC8 0x1000

Sector No: 0xA
Source Adr: 0x1010A000
Target Adr: 0x1000A000
match
flash_range_erase 0xA000 0x1000
flash_range_program 0xA000 0x20040FC8 0x1000

Sector No: 0xB
Source Adr: 0x1010B000
Target Adr: 0x1000B000
match
flash_range_erase 0xB000 0x1000
flash_range_program 0xB000 0x20040FC8 0x1000

Sector No: 0xC
Source Adr: 0x1010C000
Target Adr: 0x1000C000
match
flash_range_erase 0xC000 0x1000
flash_range_program 0xC000 0x20040FC8 0x1000

Sector No: 0xD
Source Adr: 0x1010D000
Target Adr: 0x1000D000
match
flash_range_erase 0xD000 0x1000
flash_range_program 0xD000 0x20040FC8 0x1000

Sector No: 0xE
Source Adr: 0x1010E000
Target Adr: 0x1000E000
match
flash_range_erase 0xE000 0x1000
flash_range_program 0xE000 0x20040FC8 0x1000

Sector No: 0xF
Source Adr: 0x1010F000
Target Adr: 0x1000F000
match
flash_range_erase 0xF000 0x1000
flash_range_program 0xF000 0x20040FC8 0x1000

Sector No: 0x10
Source Adr: 0x10110000
Target Adr: 0x10010000
match
flash_range_erase 0x10000 0x1000
flash_range_program 0x10000 0x20040FC8 0x1000




I also tried to copy not to Flash-Offset 0x0 but to an unsued space at 0x80000.
When I do that, the device comes up again and the result of a compare of the flash content at 0x0 and 0x80000 is that they are identical.

=> something must be go wrong when writing into the flash part of the current programm - even when the content is unchanged.

SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Re: Reprogramm flash from programm

Tue Jul 27, 2021 10:33 am

So I finally got it working !

But I need to do both things:

- Use my combine flash_range_erase_and_programm routine
- Do it with one singlecall of this function, no sector-by-sector

one call means, I need the whole binary in SRAM. That can be a probem.


Do you have any idea what is causing that behaviour?
It is not intended to be that way, right?

SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Re: Reprogramm flash from programm

Tue Jul 27, 2021 11:47 am

could maybe this one be the reason for the trouble ?

Code: Select all

static void __no_inline_not_in_flash_func(flash_init_boot2_copyout)(void) {
    if (boot2_copyout_valid)
        return;
    for (int i = 0; i < BOOT2_SIZE_WORDS; ++i)
        [b]boot2_copyout[i] = ((uint32_t *)XIP_BASE)[i];[/b]
    __compiler_memory_barrier();
    boot2_copyout_valid = true;
}
Reading from

Code: Select all

XIP_BASE[i]
?

But - then it should be no problem if the new binary is identical to the old binary
AND there is a valid flag, so it should only be called once before any flash operation.

SirSydom
Posts: 28
Joined: Mon Jan 18, 2021 7:38 am

Re: Reprogramm flash from programm

Tue Jul 27, 2021 2:58 pm

kilograham wrote:
Mon Jul 26, 2021 2:22 pm
they do not call anything not in RAM (or ROM), you do not need to write your own routines
are you sure?

what about rom_func_lookup ? (and others)
This function is called inside flash_range_erase and flash_range_program and it resides in flash.
So I'm quite sure that causes the problem.

I'm a little confused, because I found that issue here what exaktly matches my problems:
https://github.com/raspberrypi/pico-sdk/issues/410
there you say "copy that code" and to me you say "you do not need to write your own routines"

I don't wan't to blame you, I'm happy that anyone is discussing with me. But I'm interested in solving the problem.

Return to “General”