chipKIT® Development Platform

Inspired by Arduino™

persistent variable ?

Created Wed, 13 Jun 2012 17:35:16 +0000 by philippel13


philippel13

Wed, 13 Jun 2012 17:35:16 +0000

hi,

is there a way to keep persistent a ram variable after a reset on a uno32 board ?

I've tried with "static" and "volatile" but it doesn't work, the value is always 0 after a reset.


nik999389

Wed, 13 Jun 2012 18:09:33 +0000

There is no program memory in the Pic as there is in the AVR, you might want to consider an external form of memory.

In the new build of the MPIDE that was just released they made they fixed SD card library, you could simply connect one of these up and save the data to a txt file. Either that or buy some flash memory yourself and save it onto there.

What is it exactly that your trying to do?


philippel13

Wed, 13 Jun 2012 18:36:26 +0000

I want to keep the state of an security system if the PIC32 is reset after a watchdog timer overflow. If i put my system ON and after the watchdog timer overflow my system become OFF, there is a problem with the security ...

In fact i'm trying to migrate my application from pic18lf2680 to the uno32 board. With the pic18, there is no problem for having a persistent variable after a reset. If you don't initialize a variable, it keep his old value before the reset. It is not the same with the pic32 with MPIDE, the value is put to 0 after each reset even if it is not initialized.

I can't use the flash memory because the value of the variable can change 2 or 4 times par day. I can add an eeprom but i've only one variable to save.

I've also tried to use "int VAR attribute((persistent))" as explained here : http://ww1.microchip.com/downloads/en/DeviceDoc/MPLABC32_v2_00_README.html But it doesn't works.


nik999389

Wed, 13 Jun 2012 19:06:25 +0000

Ahh I see, I can't think of any other method to achieve this. Most of the memory on the Pic32 is dynamic, which means you have to consistently update it for it to remain. I think your best bet would be to buy some more eeprom. It would be overkill, considering its one variable but you could buy some easy to use eeprom from sparkfun:

[url]http://www.sparkfun.com/products/525[/url]

What kinda variable are you trying to store? Is it just On or Off?


EmbeddedMan

Wed, 13 Jun 2012 21:53:42 +0000

hi, is there a way to keep persistent a ram variable after a reset on a uno32 board ? I've tried with "static" and "volatile" but it doesn't work, the value is always 0 after a reset.

Yup. You can specify that a variable not be cleared on boot. See, for example, [url]http://www.microchip.com/forums/fb.ashx?m=594242[/url]

*Brian


philippel13

Thu, 14 Jun 2012 08:02:26 +0000

i've tried as explained in your link but it doesn't works.

I've declared in MPIDE : int test attribute((address(0xA000FFF0),persistent));
But each time i make a reset (MCLR) test is put to 0.

Do i've to change something in the linker ? If yes how i have to do for modify it when using MPIDE ?


EmbeddedMan

Thu, 14 Jun 2012 13:42:04 +0000

If this doesn't work (and I don't know as I haven't tried it) then it is a bug in the compiler which should be fixed.

I'll see if I can get Jason K to look at it.

*Brian


jasonk

Thu, 14 Jun 2012 16:37:20 +0000

Hi,

Many MPLAB C32/XC32 features such as the address and persistent attributes won't work with the chipKIT compiler. The chipKIT compiler is much closer to the stock GCC 4.5.1 compiler and doesn't support some of these Microchip extensions.

However, we did add a .persistent output section to the default application linker scripts for the UNO32 and MAX32 boards. This .persistent output section takes input sections named .persist. This output section is outside of the _bss_begin and __bss_end symbols that the startup code uses to clear memory. The bad news is that there is no alignment after the section so using this section may cause problems if it contains an odd number of 8-bit chars. That's something we should look into...

At any rate,

unsigned int __attribute__((section(".persist"))) flag;

should work. I'd advise using it only with ints or floats.

I haven't checked it with chipKIT hardware, but it should work.


philippel13

Thu, 14 Jun 2012 19:15:12 +0000

i've just tried and it doesn't works ... And the reaction of the compiler is very strange.

When i add the line "unsigned int attribute((section(".persist"))) test; " in my sketch, it is there impossible to upload the code in the board ! You can then see the message "uploading to I/O board" normaly until the end but the red leds on board doesn't flash normally and finally the code is not upload.

And when i remove the line, all become again right, i can then upload my code.


jasonk

Thu, 14 Jun 2012 22:44:16 +0000

Can you post an example sketch? Also, which board are you using? I'll give it a try when I get a chance.


philippel13

Fri, 15 Jun 2012 07:08:38 +0000

my code has a lot of .cpp files so it is too long for post it in the forum.

My board is the uno32.

I've tried with a simple example :

int test attribute((persistent,address(0xA0000000)));

void setup() {
Serial.begin(57600);
Serial.println("go"); }

void loop() { test++; Serial.println(test); delay(1000); }

I've then no problem for uploading the code but the persistent doesn't work. On each rest the "test" variable is cleared.

I've also tried the onboard RTCC and it seem no persistent too. I've to do more tests to be sure.


EmbeddedMan

Fri, 15 Jun 2012 16:55:04 +0000

I think what you want is :

unsigned int attribute((section(".persist"))) test;

void setup() { Serial.begin(9600); Serial.println("go"); }

void loop() { test++; Serial.println(test); delay(1000); }

And I can confirm that the above sketch does not in fact work - the variable test is always initialized to zero on every reset.

I can't remember how to get MPLAB to generate a MAP file, so I can't see where it is putting 'test' . . .

*Brian


philippel13

Fri, 15 Jun 2012 17:58:23 +0000

in fact i've tried with :

int test attribute((persistent));
int test attribute((address(0xA000FFF0),persistent));
int test attribute((address(0xA0000000))); int test attribute((persistent,address(0xA0000000))); unsigned int attribute((section(".persist"))) test;

None of these definition work.

As i tell in my previous message, i've also the problem with the RTCC clock. I'm using the following library : http://hacking.majenko.co.uk/chipkit-uno32-real-time-clock-library And each time i do a reset (MCLR) the time is set to date:10/10/17 and time :10:07:30.

My code is : // Initialize the RTCC module RTCC.begin();

/*
// Set the alarm to trigger every second RTCC.alarmMask(AL_10_SECOND); RTCC.chimeEnable(); RTCC.alarmEnable(); // Attach our routine to send the time through the serial port RTCC.attachInterrupt(&outputTime); */

// Set the time to something sensible **** in comment for test persistent /* RTCC.hours(9); RTCC.minutes(59); RTCC.seconds(0); RTCC.year(11); RTCC.month(05); RTCC.day(9); */

RTCC.printdate(); --> 10/10/17 RTCC.printheure(); --> 10:07:30

Initially i would like to migrate my application from pic18 to pic32/MPIDE just for the fun of the pic32 and the c++ but after a few tests i think it was not a good idea ... With the pic32/MPIDE, 3.3v, no eeprom inside, no persistent variable, no persistent RTC, very long start up after a reset, impossible to change the pic, need to buy another programmer if i want to use with mplab, ....

thanks for your help.

philippe


EmbeddedMan

Fri, 15 Jun 2012 18:14:16 +0000

philippe,

The chipKIT does have working EEPROM emulation - works exactly like the Arduino's EEPROM, same calls.

The persistent variable problem is a bug and we will get it figured out and fixed, probably in short order. I think you're the first person who's asked about it.

The RTC issue is one I've been meaning to look into - it should be working as you expect it (as long as you have the 32KHz crystal added to your board), we just need to figure out where the software problem is inside MPIDE. Does Arduino have functioning RTC?

The delay on boot is in the bootloader, and can be easily changed if you are willing to re-program your bootloader.

You are correct - you can not easily replace the PIC32. However, most Arduinos are also soldered down, no difference there.

As far as programming/debugging under MPLAB, you can use a PICKit3 and they sell for less than $30 on e-bay. Equivalent programmer/debugger for AVR is about the same - no difference there.

I just wanted to get all of the above out there so you have more data in your Arduino/chipKIT comparison.

*Brian


philippel13

Fri, 15 Jun 2012 18:41:27 +0000

brian,

in fact i don't compare arduino and chipkit but pic18 and pic32.

I've created a few years ago an application with 6* pic18f2680 on a can bus with C18 compiler and it works perfectly.

I'm playing with pic32, arduino, chipkit, c++ just for learning but i don't really need of it. In my case, the pic18 as enough power. However, even if there are a few bug, the chipkit/MPIDE is very impressive.


jasonk

Fri, 15 Jun 2012 23:30:30 +0000

And I can confirm that the above sketch does not in fact work - the variable test is always initialized to zero on every reset.

My initial guess was that maybe the variable is getting allocated to the same address as a variable used by the bootloader and was getting cleared by the bootloader's startup code. It looks like the memory clearing part of the bootloader's startup code has been removed, but it could still get corrupted by the bootloader's memory usage. We may need to put more thought into where we allocate the persistent data.


philippel13

Sat, 16 Jun 2012 14:09:49 +0000

for the rtcc, i've made a couple of tests and i confirm i've the same problem with no persistent time on reset. Perhaps i've made an error somewhere but i don't see where.

I've followed the doc : http://ww1.microchip.com/downloads/en/DeviceDoc/61125E.pdf

I also confirm i've add the crystal 32k on the board and without reset the RTCC works fine.

And i've tried the code found here given by Paul_L : http://www.chipkit.org/forum/viewtopic.php?f=17&t=413&hilit=rtcc

At each reset the time value = 10073000 !!!

Here are my 2 sketchs :

Sketch 1 :

void setup() { Serial.begin(9600); Serial.print("RTCCON= "); Serial.print(RTCCON, HEX); Serial.print(" / "); Serial.print("OSCCON= "); Serial.print(OSCCON, HEX); //Unlock OSCCON; SYSKEY = 0x0; SYSKEY = 0xAA996655; SYSKEY = 0x556699AA; OSCCONSET = 2; SYSKEY = 0x0; Serial.println(); Serial.print("RTCCON= "); Serial.print(RTCCON, HEX); Serial.print(" / "); Serial.print("OSCCON= "); Serial.print(OSCCON, HEX); Serial.println(); // RTCTIME = 0; }

void loop() {

Serial.println(RTCTIME, HEX); delay(1500); }

           ------------------------------------------------------

Sketch 2 :

void setup() { Serial.begin(57600); }

void loop() {

Serial.println(RTCTIME, HEX); delay(1500); }

           ------------------------------------------------------

Is there a bug somewhere or i've made an error ?

philippe


philippel13

Fri, 22 Jun 2012 06:33:59 +0000

i've done an 2 tests more with the example found here : http://www.johnloomis.org/microchip/docs/32-bit-Peripheral-Library-Guide.pdf

And i've always the same problem : the RTC works fine but the time is cleared after each reset or a watchdog. In fact the time is always put to 07:30 after a reset.

It is a really big problem for an rtc much more than for the no persistent variables.

I've searched for a few days and i don't understand what is wrong. Have you an idea ?

Perhaps a problem with my uno32. Is someone could test the code ?

My code with reset pushed : #include "plib.h"

//#define wdt 1

rtccTime tm1;// time structure rtccDate dt1;// date structure

void setup () { Serial.begin(57600);
rtccRes res=RtccInit(); while(RtccGetClkStat()!=RTCC_CLK_ON); Serial.println(' '); Serial.print("Go -> "); #ifdef wdt EnableWDT(); Serial.print("Watchdog Test - "); #else Serial.print("Reset Test - "); #endif }

void loop ()

Here is the output of the test by pushing reset button : Go -> Reset Test - 7:30 | 7:31 | 7:32 | 7:33 | 7:34 | 7:35 | 7:36 |
Go -> Reset Test - 7:30 | 7:31 | 7:32 | 7:33 |
Go -> Reset Test - 7:30 | 7:31 | 7:32 | 7:33 | 7:34 | 7:35 | 7:36 |

And now the same test with the watchdog (#define wdt 1 at the top of code) Go -> Watchdog Test - 7:30 |
Go -> Watchdog Test - 7:30 |
Go -> Watchdog Test - 7:30 |


philippel13

Sat, 23 Jun 2012 16:23:53 +0000

hi,

nobody from chipkit could help me ?

I've tried for a lot of days to have persistent variables and persistent RTC after a reset or watchdog but it definitively don't work for me.

Do someone could try for confirm or not the problem on an other uno32 than mine ?

The problem doesn't come from the init code because if i insert it in the main loop, the rtcc continue to work normally.

I think the problem come from the reset code himself in MPIDE or from the uno32. I can't make a test with C32 because i don't have a pic32 programmer. I've only an ICD2 but it doesn't work with pic32 devices.

With an RTC loosing the time at the first reset or watchdog and the same for variables, this board become just a gadget without possibility to use it for a real application ....

If i want to do the same application than with a pic18 i've to add to the uno32 an external RAM, an external EEprom and an external RTC !

philippe


EmbeddedMan

Sat, 23 Jun 2012 18:09:54 +0000

philippe - I'm sorry I can't get to trying to fix the RTC issue right now. It's on my list of things to work on at some point. Hopefully one of the other devs can take a look at it sooner than I will be able to.

*Brian


mikes

Sun, 24 Jun 2012 02:35:57 +0000

Have you tried the EEPROM library yet, it uses the flash memory on the chip and does not require an external EEPROM to function. Example of restoring a variable after a shutdown.

#include <EEPROM.h>
byte state;
int address = 0;
void setup()
{
  pinMode(43,OUTPUT);
  pinMode(3,INPUT);
  pinMode(4,INPUT);
  state = EEPROM.read(address);
}
void loop()
{
  if (!digitalRead(3) && state == 0) //use a wire to ground to pull the pin low
  {
    state = 1;
    EEPROM.write(address,state);
  }
  if (!digitalRead(4) && state == 1)
  {
    state = 0;
    EEPROM.write(address,state);
  }
  if (!(state == 0) && !(state == 1))
  {
    state = 0;
  }
  digitalWrite(43,state);
}

philippel13

Sun, 24 Jun 2012 04:10:04 +0000

hi brian,

in fact in a first time the most important thing for me is to be sure there is really a bug somewhere in MPIDE for me stop searching in documentation and in my code for nothing .... If someone could just tried the code and confirm or not will be fun. After if there is a declared bug, i can understand you need time to resolve it.

For the eeprom, the emulation with flash memory can't be a solution for variable changing a few time a day (number max of erase/write cycles). As all 32 bits have no eeprom, the simplest is to add I2C eeprom. And in most case, i just need to keep power on board with battery and value in RAM (persistent data).

philippe


EmbeddedMan

Sun, 24 Jun 2012 05:15:16 +0000

I will try to find some time to test out your code and see what I can see. But I don't know anything about the RTCC yet, so I'm not going to quickly be able to find out if its your code or MPIDE or what.

Also, the emulated EEPROM is a great place to store something that only changes a couple times per day. Even a couple times per minute. We use the Microchip DEE library [url]http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en538000[/url] which is quite good and extends the life of the Flash many thousands of times, so no need to worry about it wearing out unless you're doing many updates per second.

*Brian


philippel13

Sun, 24 Jun 2012 14:07:46 +0000

thanks for the link about eeprom emulator. Very interesting and efficient.


philippel13

Sat, 07 Jul 2012 15:10:09 +0000

hi,

i've bought a pickit3 and i'd like to test my code without the bootloader for verify if the problem of persistent data and rtcc come from this bootloader.

How can i proceed for compile the sketch with mpide and send the .hex file to the board without the bootloader ?


jasonk

Sat, 07 Jul 2012 23:51:41 +0000

There's a thread here that may help you run your sketch with PICkit 3 in MPLAB IDE v8.xx. http://www.chipkit.org/forum/viewtopic.php?f=19&t=473

EDIT: Actually, if I remember correctly, I believe that the instructions in that thread also use the bootloader to program and the PICkit 3 just to debug an already programmed image.

Something else to try might be to add a few uninitialized variables before your persistent variable.

I believe that KeithV is working on a new and improved version of the bootloader that should reserve some memory for persistent variables. I'm not sure if it is ready to try yet though. When it is ready, you'll be able to use the PICkit 3 to program the bootloader.


philippel13

Sun, 08 Jul 2012 17:07:59 +0000

"Something else to try might be to add a few uninitialized variables before your persistent variable."

I've just tried and it doesn't works.


skyjumper

Sun, 15 Jul 2012 00:39:36 +0000

Also, the emulated EEPROM is a great place to store something that only changes a couple times per day. Even a couple times per minute. We use the Microchip DEE library [url]http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en538000[/url] which is quite good and extends the life of the Flash many thousands of times, so no need to worry about it wearing out unless you're doing many updates per second.

This is interesting, how does this work? Does the PIC have the ability to write only a few bytes of flash, or does this reserve an entire page? It must be possible to update just a page of program flash?


EmbeddedMan

Mon, 16 Jul 2012 04:24:26 +0000

The best thing is to read the docs that come with DEE - they're very good. (There's a nicely written app note about it.)

But all PICs can only erase a block at a time, but can write smaller chunks - like for PIC32 : words (4 bytes) or lines (32 bytes, I think) at a time.

*Brian


mervyn.777

Mon, 16 Jul 2012 15:08:06 +0000

I'm quite new to the chipkit development. I'm using the ChipKIT uno32 in MPIDE.

I would like to persist an array of float data. I'll be writing to the flash not very frequently.

Please could someone provide a sample code to persist data. I'm trying the emulated eeprom but with no luck :(

I also tried many other methods suggested in this thread but everything turned out to be futile.

I also tried looking into http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en538000 but couldnt quite follow the instruction. It will be much appreciated if someone could guide my through this.


EmbeddedMan

Tue, 17 Jul 2012 01:48:19 +0000

What's wrong with the EEPROM functions that are built into the MPIDE core library? I think they work just fine.

*Brian


mervyn.777

Tue, 17 Jul 2012 13:50:01 +0000

What's wrong with the EEPROM functions that are built into the MPIDE core library? I think they work just fine. *Brian

This is my sample sketch:

#include <EEPROM.h>
byte state;
int address = 0;
void setup()
{
  Serial.begin(115200);
  state = 8;
  EEPROM.write(address,state);
  Serial.println(EEPROM.read(address));
}
void loop()
{

}

And here's the error i always get: [color=#FF0000]avrdude: verification error, first mismatch at byte 0x0180 0x00 != 0xff avrdude: verification error; content mismatch[/color]

I also tried using this sketch:

#include <EEPROM.h>
#define USER_APP_ADDR 0x9D010000

void setup()
{
  Serial.begin(115200);
  for (int i = 0; i< 512; i++){
    EEPROM.write(i + USER_APP_ADDR,i);
  }
  delay(10000);
  for (int i = 0; i< 512; i++){
    Serial.print(EEPROM.read(i + USER_APP_ADDR));
  }
}
void loop()
{
}

But I still get the same error. One thing I observed was when I flash for the 1st time I don't get any error but the output is blank. But from the second time on wards flashing becomes impossible!

I dont know where I'm going wrong. I'm using chipKit UNO32.

Thanks for your help!


skyjumper

Tue, 17 Jul 2012 17:40:35 +0000

A verification error from AVRDUDE indicates that your sketch was not uploaded correctly. It has nothing to do with the sketch itself. Compile any simple example, try to upload it and I'll bet you have the same error.

This more likely has to do with a baud rate mis-match between the IDE and the boot loader, or perhaps a problem with the boot loader itself. Have you changed anything on your board?


mervyn.777

Tue, 17 Jul 2012 19:25:56 +0000

A verification error from AVRDUDE indicates that your sketch was not uploaded correctly. It has nothing to do with the sketch itself. Compile any simple example, try to upload it and I'll bet you have the same error. This more likely has to do with a baud rate mis-match between the IDE and the boot loader, or perhaps a problem with the boot loader itself. Have you changed anything on your board?

I start getting this error ONLY when I upload the EEPROM sketch but I'm able to upload any other sketch and they work just fine.

What you said was partially right. After I get this error when I tried to upload any other sketch (that used to work before), they too throw the same error. In order to solve this problem I usually remove the USB connecting to the board and reconnect and the problem gets solved.

I'm pretty sure the problem lies with EEPROM library and/or sketch but don't know exactly where it is. I'm positive the baudrate is fine but not too sure about the bootloader.


skyjumper

Wed, 18 Jul 2012 12:42:47 +0000

What you said was partially right. After I get this error when I tried to upload any other sketch (that used to work before), they too throw the same error. In order to solve this problem I usually remove the USB connecting to the board and reconnect and the problem gets solved. I'm pretty sure the problem lies with EEPROM library and/or sketch but don't know exactly where it is. I'm positive the baudrate is fine but not too sure about the bootloader.

AVRDUDE uploads the "sketch," which is a HEX file, then reads it back, checking what is read back against the original. If they don't match, you get a verification error.

The only way I can think that this could be caused by the sketch is if the compiled sketch is too big to fit into the flash. Is the compiled sketch particularly large for any reason? I'm not familiar with the boot loader on these boards, but some bug in the boot loader could cause this as well.

If this issue could be caused by the actual code itself, as in the source code, I would love to hear how that is possible.


mervyn.777

Wed, 18 Jul 2012 15:44:24 +0000

AVRDUDE uploads the "sketch," which is a HEX file, then reads it back, checking what is read back against the original. If they don't match, you get a verification error. The only way I can think that this could be caused by the sketch is if the compiled sketch is too big to fit into the flash. Is the compiled sketch particularly large for any reason? I'm not familiar with the boot loader on these boards, but some bug in the boot loader could cause this as well.
If this issue could be caused by the actual code itself, as in the source code, I would love to hear how that is possible.

This is the size of my sketch: Binary sketch size: 7448 bytes (of a 126976 byte maximum)

Even I'm speculating the problem to lie in the bootloader image.

I have the latest bootloader hex file but I dont know how to flash this on to the board. How can I update my UNO32 bootloader to latest HEX using MPIDE via uart??

Do I need anything else apart from this?


KeithV

Wed, 18 Jul 2012 16:50:44 +0000

What you are doing is not how you use EEProm. You said:

#define USER_APP_ADDR 0x9D010000 EEPROM.write(i + USER_APP_ADDR,i);

The start of EEProm is at address 0, do not add anything to it, the EEProm library knows where EEProm goes, and today it is always the last 4K of flash. You are writing to some undetermined address.

In short, the problem is you probably wrote some place in program-flash and it stuck; however, for some unknown reason when you uploaded a new sketch the bootloader did not erase all of program-flash (less EEProm). Then when avrdude uploaded the sketch it verifies flash and if it did not program that area of flash avrdude expects 0xFFFFFFFF to come back (unprogramed flash). If you wrote to that area and it somehow stuck, this would fail the verification; which is what you are seeing. Clearly programing another sketch should clear the problem but for some reason did not. I would download the bootloader from the Digilent site and reprogram the bootloader via MPLAB, that will clear all of flash and you should be okay.

As for .persistent data, that section of RAM is ALWAYs being whacked by the bootloader. There will probably be junk in that section of RAM. I have been working on a new bootloader and also all of the linker scripts and there will be a whole new way that bootloaders load programs. One of the new features is that you will have at least 512 bytes of persistent data. Just throw it in the .persistent section like you have been and it should work. What I have done is I have re-written the bootloader to skip the 1st 1.5K of RAM, so the bootloader will not whack that RAM, but there are other things in that space too, so you can only bet on 512 bytes of persistent data. In order to take advantage of this, you will need to program the new bootloader on your board.

The next official release of MPIDE will NOT have the new linker scripts in them and while the new bootloader will still skip the 1.5K of space, I cannot ensure that the sketches .presistent data will be placed in that protected space. For you to know this will all work you will need to wait for the first test build of MPIDE after the next official release to get the new linker scripts that place persistent data into the protected RAM space.