Many microcontrollers, e.g. PIC18F, have flash program memory: "The Flash program memory is readable and writable during normal operation". Does this mean I can store some user configurations in the program memory?
Yes, you can. I have done this many times.
However, there are some drawbacks relative to using separate EEPROM:
- The number of lifetime writes to program flash memory is significantly less than data EEPROM.
- The processor will go out to lunch during the erase and write times.
- Program flash is erased in blocks. You can't just update a single byte. I usually use a block caching scheme to deal with this.
Many PIC18's have EEPROM memory, up to 1K in size. Unfortunately the PIC18F46J50 you reference does not. If EEPROM is available, it is a much better choice if it is large enough for your data, as the EEPROM has a minimum of 1,000,000 erase/write cycles, and the flash is only 10,000.
The PIC18, like most other microcontrollers, uses what is called a Harvard architecture, meaning there are physically separate addressable area for programs and data (i.e. you can have a program address 4 and a data address 4, and they are not the same). Therefore you cannot read or write flash memory using the normal methods in either C or assembly language.
Instead, on the PIC18 family, you set up a starting address in a 22-bit register called TBLPTR. To read bytes from the flash, you use a TBLRD instruction. There is an option to automatically increment or decrement the address after a read you don't have to do that manually.
To write to flash memory, you have to erase one or more 64-byte blocks of flash memory first that will be written over. After setting up the starting address again in TBLPTR, and values in some other registers to initialize the erase operation, interrupts are disabled and then you must write 0x55 immediately followed by 0xAA to a register; this unlocks the erase command and is needed to prevent errant code from accidentally wiping out memory. Finally the command to actually do the erase is executed, followed by re-enabling interrupts.
Writing to flash memory is similar to erasing, except the block size is smaller. The write is actually executed using a TBLWT instruction, which also allows auto increment/decrement like the TBLRD instruction.
In addition to saving off configuration data, writing to flash memory allows one to update their firmware in the field using what is called "firmware over the air". You need to have a fixed block of firmware, usually at the start of program memory, that can receive the update from a Bluetooth module, Wi-Fi, cellular module, or even a wired connection, and update the flash above a certain point in the program (e.g. a "fence") with new code. After the update is completed, a reset is initiated, and the new code is put into use.
Many other microcontrollers besides the PIC family have the ability to update their flash memory; most use some combination of configuration registers, an address pointer, and special instructions to carry out the task.