Storing information in flash (flstore flclear)
August 07, 2017 03:47PM
Hi All,

Im using the new flash save command to save thermostat schedules into flash, this works fine until i try to re-use a slot for a schedule, i.e. i use the first 6 positions in the constant array and its fine, i try to save over them and its not fine, heres my code...

// #include "C:ByPicV2liblib_dt_1.bas"

constant sch.schedule { 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff  }

constant sch.empty { 0xffffffff }

constant sch.DAY   0
constant sch.HFROM 1
constant sch.MFROM 2
constant sch.HTO   3
constant sch.MTO   4
constant sch.TEMP  5

dim sch.ActiveId

function sch.Save(id,*sch())
    dim i, x, idx
    idx = id * 6
    x = 0
     for i = idx to idx + 5
         flstore(?sch.schedule(i),sch(x))
         x = x + 1
     next
endf

function sch.Delete(id)
    dim Sch(6)
    Sch(0) = 0
    Sch(1) = 0
    Sch(2) = 0
    Sch(3) = 0
    Sch(4) = 0
    Sch(5) = 0
    sch.Save(id,*Sch())
endf

function sch.NextFree()
dim s, id
     for s = 0 to 49
        id = s * 6
        if sch.schedule(id) < 0 || sch.schedule(id) > 7 then
            return id
            break
        endif
     next
     return -1
endf

function sch.Add(day, fhour, fminute, thour, tminute, temp)
    dim s, id, sch(6)
    for s = 0 to 49
        id = s * 6
        if (sch.schedule(id) < 1 || sch.schedule(id) > 7) then
            sch(0) = day
            sch(1) = fhour
            sch(2) = fminute
            sch(3) = thour
            sch(4) = tminute
            sch(5) = temp
            sch.Save(s, *sch())
            print id
            break
        endif
    next
endf

function sch.IsActive(*date_time(),*sch())
    dim s, day, fhour, fminute, thour, tminute, id
    dim fromDate(8), toDate(8), fromUTC, toUTC, nowUTC, nowWeb$, temp
    for s = 0 to 49
        id = s * 6
        day = sch.schedule(id)
        fhour = sch.schedule(id + 1)
        fminute = sch.schedule(id + 2)
        thour = sch.schedule(id + 3)
        tminute = sch.schedule(id + 4)
        temp = sch.schedule(id + 5)
        if day = date_time(time.DOW) then
            nowWeb$ = dt.web$(*date_time())
            dt.time(nowWeb$,*fromDate())

            fromDate(time.HOURS) = fhour
            fromDate(time.MINS) = fminute
            fromUTC = dt.UTC(*fromDate())

            dt.time(nowWeb$,*toDate())
            toDate(time.HOURS) = thour
            toDate(time.MINS) = tminute
            toUTC = dt.UTC(*toDate())

            nowUTC = dt.UTC(*date_time())

            if fromUTC <= nowUTC then
                if toUTC > nowUTC then
                    sch(sch.DAY) = day
                    sch(sch.HFROM) = fhour
                    sch(sch.MFROM) = fminute
                    sch(sch.HTO) = thour
                    sch(sch.MTO) = tminute
                    sch(sch.TEMP) = temp
                    sch.ActiveId = id
                    return 1
                endif
            endif
        endif
    next
    sch.ActiveId = -1
    return 0
endf

function sch.GetJSON()
  dim s, sch$, day, fhour, fminute, thour, tminute
  dim mode$, temp, id, sLen
  dim out$
  dim out2$
  dim rec$
  print "["
    for s = 0 to 49
        id = s * 6
        day = sch.schedule(id + sch.DAY)
        fhour = sch.schedule(id + sch.HFROM)
        fminute = sch.schedule(id + sch.MFROM)
        thour = sch.schedule(id + sch.HTO)
        tminute = sch.schedule(id + sch.MTO)
        temp = sch.schedule(id + sch.TEMP)
        if day > 0 then
            if s > 0 then
                rec$ = ",{"
            else
                rec$ = "{"
            endif
            rec$ = rec$ + ""Id":" + s + ","
            rec$ = rec$ + ""Day":" + day + ","
            rec$ = rec$ + ""TimeFrom":"" + format$("%02d",fhour)
            rec$ = rec$ + ":" + format$("%02d",fminute) + "","
            rec$ = rec$ + ""TimeTo":"" + format$("%02d",thour)
            rec$ = rec$ + ":" +  format$("%02d",tminute) + "","
            rec$ = rec$ + ""Temperature":" + temp
            rec$ = rec$ + "}"
            print rec$
        endif
    next
    print "]rnrn"
endf

function sch.List()
  dim s, sch$, d, fhour, fminute, thour, tminute, sch(6)
  dim mode$, temp, id, rec$, dayname$
    print "rn**********Schedule Listing***********"
    for s = 0 to 49
        id = s * 6
        sch.Load(s,*sch())
        d = sch(sch.DAY)
        fhour = sch(sch.HFROM)
        fminute = sch(sch.MFROM)
        thour = sch(sch.HTO)
        tminute = sch(sch.MTO)
        temp = sch(sch.TEMP)
        if d > 0 then
            dayname$ = dt.day_name$(d)
            rec$ = "rn#["
            rec$ = rec$ + format$("%02d",s)
            rec$ = rec$ + "] "
            rec$ = rec$ + dayname$
            rec$ = rec$ + " - "
            rec$ = rec$ + format$("%02d",fhour)
            rec$ = rec$ + ":"
            rec$ = rec$ + format$("%02d",fminute)
            rec$ = rec$ + " until "
            rec$ = rec$ + format$("%02d",thour)
            rec$ = rec$ + ":"
            rec$ = rec$ + format$("%02d",tminute)
            rec$ = rec$ + " @ "
            rec$ = rec$ + format$("%02d",temp)
            rec$ = rec$ + "'C#"
            print rec$
        endif
    next
    print "rn*****************END*****************rnrn"
endf

and heres what happens (after flclear(0)) and reflash of my code...

sch.Add(1,13,0,14,0,25)
0 ok sch.List

**********Schedule Listing***********
#[00] Mon - 13:00 until 14:00 @ 25'C# << added OK
*****************END*****************

ok sch.Add(1,13,0,14,0,25)
6 ok sch.List

**********Schedule Listing***********
#[00] Mon - 13:00 until 14:00 @ 25'C#
#[01] Mon - 13:00 until 14:00 @ 25'C# << added OK
*****************END*****************

ok sch.Delete(0)
ok sch.List

**********Schedule Listing***********
#[01] Mon - 13:00 until 14:00 @ 25'C# << [00] Deleted OK
*****************END*****************

ok sch.Add(1,13,0,14,0,25)
0 ok sch.List

**********Schedule Listing***********
#[01] Mon - 13:00 until 14:00 @ 25'C# <<NOT added ????
*****************END*****************

ok

any ideas why i cant reuse the old flash space?



Edited 1 time(s). Last edit at 08/07/2017 07:11PM by djmills.uk@gmail.com.
Re: Storing information in flash (flstore flclear)
August 08, 2017 09:17AM
hello,
The PIC32 does not have any 'native' non-volatile storage and so this is implemented as the best it can do. This does have a couple of implications:

It is possible to write to any part of the flash as a single word (4 bytes), however it is not possible to erase a single byte, erase only works on a block of 1k at a time ALSO the 1k MUST start on a 4 k boundary.
When defining a constant constant sch.schedule {.... this may start anywhere so the technique is to find the boundary and work from there, this will 'waste' some constant storage unless the constant just happens to be on a boundary (unlikely).

The general way to handle this storage is to first find the boundary:

function flashstore.start()
dim j
	for j = 0 to 512
		if (?sch.schedule(j) % 0x400) = 0 then
			break
		endif
	next
	return j
endf

the value returned (say estart) is the boundary and so this value should be used as the start of useable storage
flstore(?sch.schedule(estart+offset),value) // to store a 4 byte word anywhere within block
flerase(?sch.schedule(estart)) // erases whole block

Second
The flash is not meant to be written to, many times, a schedule is a good use as this will not be changed much but changing as part of a program loop say once every few mS will where out the flash cell

A code example is here [www.byvac.com]
Re: Storing information in flash (flstore flclear)
August 08, 2017 11:32AM
Thanks jim, im thinking perhaps using the flash as storage isnt the ideal for me, i did try to use my rtc to store the schedules but im unsure of the memory limit, its the same one you use and im using your rtc library and rtc.getreg(x) do you know how many getreg slots are available?

EDIT: Never min i discovered that the maximum slot is 63

i think i will get an i2c storage module such as this: http://amzn.eu/a7oILGO

Thanks for your help



Edited 1 time(s). Last edit at 08/08/2017 12:32PM by djmills.uk@gmail.com.
Sorry, you do not have permission to post/reply in this forum.