DVBCore  20.3.0
DVBCore Documentation
stbdbnvm.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 //---includes for this file----------------------------------------------------
26 // compiler library header files
27 
28 #include <string.h>
29 
30 // third party header files
31 
32 // Ocean Blue Software header files
33 
34 #include <techtype.h>
35 #include <dbgfuncs.h>
36 
37 #include "dba.h"
38 #include "dba_nvm.h"
39 #include "stbdbnvm.h"
40 #include "stbnvm.h"
41 #include "stbcsum.h"
42 
43 #include "stbheap.h"
44 
45 //---constant definitions for this file----------------------------------------
46 
47 #define BLOCK_PAYLOAD_SIZE 20
48 #define FIRST_BLOCK_MASK 0x80
49 #define LINKED_BLOCK_MASK 0x40
50 #define RECID_BLOCK_MASK 0x3f
51 
52 //---local typedef structs for this file---------------------------------------
53 
54 typedef struct
55 {
56  U8BIT payload[BLOCK_PAYLOAD_SIZE];
57  U16BIT next_blk;
58  U8BIT block_type;
59  U8BIT checksum;
61 
62 typedef struct
63 {
64  U16BIT blk_id;
65  NVM_BLOCK_REC blk_data;
66  BOOLEAN writing;
68 
69 typedef struct
70 {
71  U8BIT *blk_map;
72  U8BIT *ram_data;
73  U16BIT blk_off;
74  U16BIT num_blks;
75  BOOLEAN changed;
77 
78 typedef struct
79 {
80  U8BIT *data;
81  U16BIT size;
82  U16BIT blk_no;
83  BOOLEAN changed;
85 
86 //---local (static) variable declarations for this file------------------------
87 // (internal variables declared static to make them local)
88 
89 static NVM_DB_STATUS_REC db_status;
90 static NVM_CACHE_STATUS_REC cache_status;
91 
92 //---local function prototypes for this file-----------------------------------
93 // (internal functions declared static to make them local)
94 
95 static U16BIT GetBlockMap(U16BIT last_blk, BOOLEAN setclr);
96 static void SetBlockMap(U16BIT blk, BOOLEAN setclr);
97 
98 static BOOLEAN ReadBlock(U16BIT blk_no, NVM_BLOCK_REC *blk_ptr, BOOLEAN check);
99 static BOOLEAN WriteBlock(U16BIT blk_no, NVM_BLOCK_REC *blk_ptr, BOOLEAN check);
100 
101 static BOOLEAN CacheNVMRecord(U16BIT block_no);
102 static BOOLEAN SaveNVMCache(void);
103 
104 //---local function definitions------------------------------------------------
105 
118 static U16BIT GetBlockMap(U16BIT last_blk, BOOLEAN setclr)
119 {
120  U16BIT byte;
121  U8BIT bit;
122  U16BIT blk;
123  U16BIT next_blk = NVM_INVALID_BLOCK_ID;
124 
125  FUNCTION_START(GetBlockMap);
126 
127  if (last_blk == NVM_INVALID_BLOCK_ID)
128  {
129  // start from first block
130  blk = 0;
131  }
132  else
133  {
134  // or one after last block
135  blk = last_blk + 1;
136  }
137 
138  while (blk < db_status.num_blks)
139  {
140  byte = (U16BIT)(blk / 8);
141  bit = (U8BIT)(blk % 8);
142  if ((db_status.blk_map[byte] & (0x80 >> bit)) == 0x00)
143  {
144  if (setclr == FALSE)
145  {
146  next_blk = blk;
147  break;
148  }
149  }
150  else
151  {
152  if (setclr == TRUE)
153  {
154  next_blk = blk;
155  break;
156  }
157  }
158  blk++;
159  }
160 
161  FUNCTION_FINISH(GetBlockMap);
162 
163  return(next_blk);
164 }
165 
178 static void SetBlockMap(U16BIT blk, BOOLEAN setclr)
179 {
180  U16BIT byte;
181  U8BIT bit;
182 
183  FUNCTION_START(SetBlockMap);
184 
185  ASSERT(blk < db_status.num_blks);
186 
187  byte = (U16BIT)(blk / 8);
188  bit = (U8BIT)(blk % 8);
189 
190  if (setclr == TRUE)
191  {
192  db_status.blk_map[byte] |= (0x80 >> bit);
193  }
194  else
195  {
196  db_status.blk_map[byte] &= ~(0x80 >> bit);
197  }
198 
199  FUNCTION_FINISH(SetBlockMap);
200 }
201 
215 static BOOLEAN ReadBlock(U16BIT blk_no, NVM_BLOCK_REC *blk_ptr, BOOLEAN check)
216 {
217  U32BIT offset;
218  BOOLEAN ret_val = FALSE;
219 
220 // FUNCTION_START(ReadBlock);
221 
222  ASSERT(blk_no < db_status.num_blks);
223  ASSERT(blk_ptr != NULL);
224 
225  // get NVM address
226  offset = (U32BIT)db_status.blk_off +
227  ((U32BIT)blk_no * (U32BIT)sizeof(NVM_BLOCK_REC));
228  if (db_status.ram_data == NULL)
229  {
230  // read block
231  if (STB_NVMSTBRead(offset, (U32BIT)sizeof(NVM_BLOCK_REC), (U8BIT *)blk_ptr))
232  {
233  ret_val = TRUE;
234  }
235  }
236  else
237  {
238  // copy data
239  memcpy((void *)blk_ptr, (void *)(db_status.ram_data + offset), (size_t)sizeof(NVM_BLOCK_REC));
240  ret_val = TRUE;
241  }
242 
243  // calculate checksum and compare
244  if (check && ret_val && (blk_ptr->block_type != 0xff))
245  {
246  if (STB_CheckChecksum((U8BIT *)blk_ptr, (U32BIT)sizeof(NVM_BLOCK_REC)) == FALSE)
247  {
248  ret_val = FALSE;
249  }
250  }
251 
252 // FUNCTION_FINISH(ReadBlock);
253 
254  return(ret_val);
255 }
256 
270 static BOOLEAN WriteBlock(U16BIT blk_no, NVM_BLOCK_REC *blk_ptr, BOOLEAN check)
271 {
272  U32BIT offset;
273  BOOLEAN ret_val = FALSE;
274 
275 // FUNCTION_START(WriteBlock);
276 
277  ASSERT(blk_no < db_status.num_blks);
278  ASSERT(blk_ptr != NULL);
279 
280  // calculate checksum
281  if (check)
282  {
283  blk_ptr->checksum = STB_CalcChecksum((U8BIT *)blk_ptr, (U32BIT)sizeof(NVM_BLOCK_REC));
284  }
285 
286  // get NVM address
287  offset = (U32BIT)db_status.blk_off +
288  ((U32BIT)blk_no * (U32BIT)sizeof(NVM_BLOCK_REC));
289  if (db_status.ram_data == NULL)
290  {
291  // write block
292  if (STB_NVMSTBWrite(offset, (U32BIT)sizeof(NVM_BLOCK_REC), (U8BIT *)blk_ptr))
293  {
294  ret_val = TRUE;
295  }
296  }
297  else
298  {
299  // copy data
300  memcpy((void *)(db_status.ram_data + offset), (void *)blk_ptr, (size_t)sizeof(NVM_BLOCK_REC));
301  db_status.changed = TRUE;
302  ret_val = TRUE;
303  }
304 
305 // FUNCTION_FINISH(WriteBlock);
306 
307  return(ret_val);
308 }
309 
321 static BOOLEAN CacheNVMRecord(U16BIT block_no)
322 {
323  NVM_BLOCK_REC curr_blk;
324  BOOLEAN ret_val = TRUE;
325 
326  FUNCTION_START(CacheNVMRecord);
327 
328  ASSERT(block_no < db_status.num_blks);
329 
330  // if this record is not already cached
331  if ((cache_status.blk_no != block_no) || (cache_status.data == NULL))
332  {
333  // save cache in NVM and delete
334  SaveNVMCache();
335 
336  if (cache_status.data != NULL)
337  {
338  STB_FreeMemory((void *)cache_status.data);
339  }
340 
341  //update flags for new record
342  cache_status.data = NULL;
343  cache_status.size = 0;
344  cache_status.blk_no = block_no;
345  cache_status.changed = FALSE;
346 
347  // read payloads of all blocks of this record into cache
348  while (block_no != NVM_INVALID_BLOCK_ID)
349  {
350  // read contents of block
351  if (ReadBlock(block_no, &curr_blk, TRUE))
352  {
353  // get memory for new cache data area
354  cache_status.data = (U8BIT *)STB_ResizeMemory((void *)cache_status.data,
355  (U32BIT)(cache_status.size + BLOCK_PAYLOAD_SIZE));
356  if (cache_status.data != NULL)
357  {
358  // copy new payload
359  memcpy((void *)(cache_status.data + cache_status.size),
360  (void *)curr_blk.payload, (size_t)BLOCK_PAYLOAD_SIZE);
361  cache_status.size += BLOCK_PAYLOAD_SIZE;
362 
363  // get next block number
364  if ((curr_blk.block_type & LINKED_BLOCK_MASK) != 0)
365  // endian independent version of:
366  // block_no = curr_blk.next_blk;
367  block_no = STB_GetBE16Bit(&curr_blk.next_blk);
368  else
369  block_no = NVM_INVALID_BLOCK_ID;
370  }
371  else
372  {
373  // malloc failed so cache failed
374  ret_val = FALSE;
375  break;
376  }
377  }
378  else
379  {
380  // read failed so cache failed
381  ret_val = FALSE;
382  break;
383  }
384  }
385  }
386 
387  FUNCTION_FINISH(CacheNVMRecord);
388 
389  return(ret_val);
390 }
391 
403 static BOOLEAN SaveNVMCache(void)
404 {
405  U8BIT *src_ptr;
406  U16BIT block_no;
407  NVM_BLOCK_REC curr_blk;
408  BOOLEAN ret_val = TRUE;
409 
410  FUNCTION_START(SaveNVMCache);
411 
412  // if cache is valid and has been changed
413  if ((cache_status.changed == TRUE) && (cache_status.data != NULL))
414  {
415  src_ptr = cache_status.data;
416  cache_status.changed = FALSE;
417 
418  // write cache back into payloads of all blocks of this record
419  block_no = cache_status.blk_no;
420  while (block_no != NVM_INVALID_BLOCK_ID)
421  {
422  // read contents of block
423  if (ReadBlock(block_no, &curr_blk, TRUE))
424  {
425  // copy payload into block and back into NVM
426  memcpy((void *)curr_blk.payload, (void *)src_ptr, (size_t)BLOCK_PAYLOAD_SIZE);
427  if (WriteBlock(block_no, &curr_blk, TRUE))
428  {
429  // get next block number
430  src_ptr += BLOCK_PAYLOAD_SIZE;
431  if ((curr_blk.block_type & LINKED_BLOCK_MASK) != 0)
432  // endian independent version of:
433  // block_no = curr_blk.next_blk;
434  block_no = STB_GetBE16Bit(&curr_blk.next_blk);
435  else
436  block_no = NVM_INVALID_BLOCK_ID;
437  }
438  else
439  {
440  // write failed so save failed
441  ret_val = FALSE;
442  break;
443  }
444  }
445  else
446  {
447  // read failed so save failed
448  ret_val = FALSE;
449  break;
450  }
451  }
452  }
453 
454  FUNCTION_FINISH(SaveNVMCache);
455 
456  return(ret_val);
457 }
458 
459 //---global function definitions-----------------------------------------------
460 
472 void STB_InitNVMAccess(U16BIT offset)
473 {
474  U32BIT size;
475 
476  FUNCTION_START(STB_InitNVMAccess);
477 
478  // calculate size of NVM available for blocks
479  size = STB_NVMGetSTBSize();
480  size -= (U32BIT)offset;
481  size -= (U32BIT)sizeof(NVM_RECOVER_REC);
482 
483  // setup status vars
484  db_status.blk_map = NULL;
485  db_status.ram_data = NULL;
486  db_status.blk_off = offset;
487  db_status.num_blks = (U16BIT)(size / (U32BIT)sizeof(NVM_BLOCK_REC));
488  db_status.changed = FALSE;
489 
490  FUNCTION_FINISH(STB_InitNVMAccess);
491 }
492 
504 void STB_InitNVMMap(void)
505 {
506  U32BIT size;
507  U16BIT byte, i;
508  U8BIT bit;
509  NVM_BLOCK_REC curr_blk;
510 
511  FUNCTION_START(STB_InitNVMMap);
512 
513  // calculate size of RAM needed for map
514  size = (U32BIT)(db_status.num_blks / 8);
515  if ((db_status.num_blks % 8) > 0)
516  size++;
517 
518  // delete old block map
519  if (db_status.blk_map != NULL)
520  {
521  STB_FreeMemory((void *)db_status.blk_map);
522  }
523 
524  // create new block map
525  db_status.blk_map = (U8BIT *)STB_GetMemory(size);
526  if (db_status.blk_map != NULL)
527  {
528  memset((void *)db_status.blk_map, 0xff, (size_t)size);
529 
530  for (i = 0; i < db_status.num_blks; i++)
531  {
532  // read a block
533  if (ReadBlock(i, &curr_blk, FALSE))
534  {
535  // if block is spare
536  if (curr_blk.block_type == 0xff)
537  {
538  // clear this bit of the map
539  byte = (U16BIT)(i / 8);
540  bit = (U8BIT)(i % 8);
541  db_status.blk_map[byte] &= ~(0x80 >> bit);
542  }
543  }
544  }
545  }
546 
547  FUNCTION_FINISH(STB_InitNVMMap);
548 }
549 
565 {
566  BOOLEAN retval;
567  U16BIT i;
568  NVM_BLOCK_REC blk;
569 
570  FUNCTION_START(STB_CheckNVMDatabaseIntegrity);
571 
572  retval = TRUE;
573 
574  /* Read each block to check it's checksum */
575  for (i = 0; (i < db_status.num_blks) && retval; i++)
576  {
577  if (!ReadBlock(i, &blk, TRUE))
578  {
579  retval = FALSE;
580  }
581  }
582 
583  FUNCTION_FINISH(STB_CheckNVMDatabaseIntegrity);
584 
585  return(retval);
586 }
587 
599 void STB_SetNVMAccessRAM(U8BIT *ram_ptr)
600 {
601  FUNCTION_START(STB_SetNVMAccessRAM);
602 
603  db_status.ram_data = ram_ptr;
604 
605  FUNCTION_FINISH(STB_SetNVMAccessRAM);
606 }
607 
620 {
621  FUNCTION_START(STB_GetNVMAccessRAM);
622  FUNCTION_FINISH(STB_GetNVMAccessRAM);
623  return(db_status.ram_data);
624 }
625 
638 {
639  U16BIT ret_val;
640 
641  FUNCTION_START(STB_GetNVMBlockCount);
642 
643  ret_val = db_status.num_blks;
644 
645  FUNCTION_FINISH(STB_GetNVMBlockCount);
646 
647  return(ret_val);
648 }
649 
662 {
663  U16BIT block_no, ret_val;
664 
665  FUNCTION_START(STB_GetNVMBlocksUsed);
666 
667  ret_val = 0;
668  if (db_status.blk_map != NULL)
669  {
670  block_no = GetBlockMap(NVM_INVALID_BLOCK_ID, TRUE);
671  while (block_no != NVM_INVALID_BLOCK_ID)
672  {
673  ret_val++;
674  block_no = GetBlockMap(block_no, TRUE);
675  }
676  }
677  FUNCTION_FINISH(STB_GetNVMBlocksUsed);
678 
679  return(ret_val);
680 }
681 
687 {
688  FUNCTION_START(STB_GetNVMBlockSize);
689  FUNCTION_FINISH(STB_GetNVMBlockSize);
690  return(sizeof(NVM_BLOCK_REC));
691 }
692 
704 U16BIT STB_GetNVMBlocksNeeded(U16BIT size)
705 {
706  U16BIT ret_val;
707 
708  FUNCTION_START(STB_GetNVMBlocksNeeded);
709 
710  ret_val = (size / BLOCK_PAYLOAD_SIZE);
711  if ((size % BLOCK_PAYLOAD_SIZE) > 0)
712  ret_val++;
713 
714  FUNCTION_FINISH(STB_GetNVMBlocksNeeded);
715 
716  return(ret_val);
717 }
718 
731 U16BIT STB_CreateNVMRecord(U8BIT rec_id, U16BIT size)
732 {
733  U16BIT block_no, next_block, first_block, num_blks;
734  NVM_BLOCK_REC curr_blk;
735 
736  FUNCTION_START(STB_CreateNVMRecord);
737 
738  ASSERT(size > 0);
739  ASSERT(db_status.blk_map != NULL);
740 
741  // decide how many blocks we need for this size record
742  num_blks = STB_GetNVMBlocksNeeded(size);
743 
744  // search NVM for spare block(s) required
745  first_block = NVM_INVALID_BLOCK_ID;
746  block_no = GetBlockMap(NVM_INVALID_BLOCK_ID, FALSE);
747  while (block_no != NVM_INVALID_BLOCK_ID)
748  {
749  // setup contents of linked block
750  memset((void *)&curr_blk, 0, (size_t)sizeof(NVM_BLOCK_REC));
751  curr_blk.block_type = rec_id;
752 
753  // mark first block and remember block number
754  if (first_block == NVM_INVALID_BLOCK_ID)
755  {
756  curr_blk.block_type |= FIRST_BLOCK_MASK;
757  first_block = block_no;
758  }
759 
760  // mark all but last block and add link to next block
761  if (num_blks > 1)
762  {
763  curr_blk.block_type |= LINKED_BLOCK_MASK;
764  next_block = GetBlockMap(block_no, FALSE);
765  }
766  else
767  {
768  next_block = NVM_INVALID_BLOCK_ID;
769  }
770  // endian independent version of:
771  // curr_blk.next_blk = next_block;
772  STB_SetBE16Bit(&curr_blk.next_blk, next_block);
773 
774  // write contents of new NVM block
775  if (WriteBlock(block_no, &curr_blk, TRUE))
776  {
777  // mark block as used
778  SetBlockMap(block_no, TRUE);
779  num_blks--;
780  block_no = next_block;
781  }
782  else
783  {
784  // write failed so create failed
785  break;
786  }
787  }
788 
789  FUNCTION_FINISH(STB_CreateNVMRecord);
790 
791  return(first_block);
792 }
793 
805 void STB_DestroyNVMRecord(U16BIT block_no)
806 {
807  U16BIT next_block;
808  NVM_BLOCK_REC curr_blk;
809 
810  FUNCTION_START(STB_DestroyNVMRecord);
811 
812  ASSERT(block_no < db_status.num_blks);
813 
814  // for each block in the chain
815  while (block_no != NVM_INVALID_BLOCK_ID)
816  {
817  // read contents of block
818  if (ReadBlock(block_no, &curr_blk, TRUE))
819  {
820  // get next block number
821  if ((curr_blk.block_type & LINKED_BLOCK_MASK) != 0)
822  // endian independent version of:
823  // next_block = curr_blk.next_blk;
824  next_block = STB_GetBE16Bit(&curr_blk.next_blk);
825  else
826  next_block = NVM_INVALID_BLOCK_ID;
827 
828  // write old NVM block as unused
829  memset((void *)&curr_blk, 0xff, (size_t)sizeof(NVM_BLOCK_REC));
830  if (WriteBlock(block_no, &curr_blk, FALSE))
831  {
832  // mark block as empty
833  SetBlockMap(block_no, FALSE);
834  block_no = next_block;
835  }
836  else
837  {
838  // write failed so destroy failed
839  break;
840  }
841  }
842  else
843  {
844  // read failed so destroy failed
845  break;
846  }
847  }
848 
849  FUNCTION_FINISH(STB_DestroyNVMRecord);
850 }
851 
865 void STB_SetNextNVMBlock(U16BIT block_no, U16BIT next_block)
866 {
867  NVM_BLOCK_REC curr_blk;
868 
869  FUNCTION_START(STB_SetNextNVMBlock);
870 
871  ASSERT(block_no < db_status.num_blks);
872 
873  // for each block in the chain
874  while (block_no != NVM_INVALID_BLOCK_ID)
875  {
876  // read contents of block
877  if (ReadBlock(block_no, &curr_blk, TRUE))
878  {
879  if ((curr_blk.block_type & LINKED_BLOCK_MASK) != 0)
880  {
881  // get next block number
882  // endian independent version of:
883  // block_no = curr_blk.next_blk;
884  block_no = STB_GetBE16Bit(&curr_blk.next_blk);
885  }
886  else
887  {
888  // or point current record to next record
889  // endian independent version of:
890  // curr_blk.next_blk = next_block;
891  STB_SetBE16Bit(&curr_blk.next_blk, next_block);
892  WriteBlock(block_no, &curr_blk, TRUE);
893  block_no = NVM_INVALID_BLOCK_ID;
894  }
895  }
896  else
897  {
898  // read failed so repair failed
899  break;
900  }
901  }
902 
903  FUNCTION_FINISH(STB_SetNextNVMBlock);
904 }
905 
918 U16BIT STB_GetNextNVMBlock(U16BIT block_no)
919 {
920  NVM_BLOCK_REC curr_blk;
921  U16BIT ret_val = NVM_INVALID_BLOCK_ID;
922 
923  FUNCTION_START(STB_GetNextNVMBlock);
924 
925  ASSERT(block_no < db_status.num_blks);
926 
927  // for each block in the chain
928  while (block_no != NVM_INVALID_BLOCK_ID)
929  {
930  // read contents of block
931  if (ReadBlock(block_no, &curr_blk, TRUE))
932  {
933  // get next block number
934  // endian independent version of:
935  // block_no = curr_blk.next_blk;
936  block_no = STB_GetBE16Bit(&curr_blk.next_blk);
937 
938  if ((curr_blk.block_type & LINKED_BLOCK_MASK) == 0)
939  {
940  // or get next record from current record
941  ret_val = block_no;
942  block_no = NVM_INVALID_BLOCK_ID;
943  }
944  }
945  else
946  {
947  // read failed so repair failed
948  break;
949  }
950  }
951 
952  FUNCTION_FINISH(STB_GetNextNVMBlock);
953 
954  return(ret_val);
955 }
956 
969 U16BIT STB_FindNVMRecordFromId(U8BIT rec_id, U16BIT last_blk)
970 {
971  U16BIT block_no;
972  NVM_BLOCK_REC curr_blk;
973  U16BIT ret_val = NVM_INVALID_BLOCK_ID;
974 
975  FUNCTION_START(STB_FindNVMRecordFromId);
976 
977  ASSERT(rec_id < DBA_NUM_RECORDS);
978  ASSERT(db_status.blk_map != NULL);
979 
980  // search NVM for used blocks from last position
981  block_no = GetBlockMap(last_blk, TRUE);
982  while (block_no != NVM_INVALID_BLOCK_ID)
983  {
984  // read a block
985  if (ReadBlock(block_no, &curr_blk, TRUE))
986  {
987  // if first block in linked list
988  if ((curr_blk.block_type & FIRST_BLOCK_MASK) != 0)
989  {
990  // if block of given type
991  if ((curr_blk.block_type & RECID_BLOCK_MASK) == rec_id)
992  {
993  ret_val = block_no;
994  break;
995  }
996  }
997  }
998  block_no = GetBlockMap(block_no, TRUE);
999  }
1000 
1001  FUNCTION_FINISH(STB_FindNVMRecordFromId);
1002 
1003  return(ret_val);
1004 }
1005 
1006 void STB_NVMChanged(BOOLEAN state)
1007 {
1008  FUNCTION_START(STB_NVMChanged);
1009  db_status.changed = state;
1010  FUNCTION_FINISH(STB_NVMChanged);
1011 }
1012 
1017 void STB_NVMFlushCache(BOOLEAN clear)
1018 {
1019  FUNCTION_START(STB_NVMFlushCache);
1020 
1021  SaveNVMCache();
1022 
1023  if (clear)
1024  {
1025  if (cache_status.data != NULL)
1026  {
1027  STB_FreeMemory((void *)cache_status.data);
1028  cache_status.data = NULL;
1029  }
1030  cache_status.changed = FALSE;
1031  }
1032 
1033  FUNCTION_FINISH(STB_NVMFlushCache);
1034 }
1035 
1047 void STB_NVMSave(void)
1048 {
1049  FUNCTION_START(STB_NVMSave);
1050 
1051  /* Save current cache block */
1052  SaveNVMCache();
1053 
1054  /* Save the DB data to NVM if it's being cached in RAM and has been changed */
1055  if ((db_status.ram_data != NULL) && db_status.changed)
1056  {
1057  STB_NVMSTBWrite(0, STB_NVMGetSTBSize(), db_status.ram_data);
1058  db_status.changed = FALSE;
1059  }
1060 
1061  FUNCTION_FINISH(STB_NVMSave);
1062 }
1063 
1074 void STB_SetNVMRecordString(U16BIT block_no, U16BIT offset, U16BIT size, U8BIT *string)
1075 {
1076  U16BIT i;
1077  U8BIT *data_ptr;
1078 
1079  FUNCTION_START(STB_SetNVMRecordString);
1080 
1081  ASSERT(block_no < db_status.num_blks);
1082 
1083  // read NVM record into cache
1084  if (CacheNVMRecord(block_no))
1085  {
1086  // find start of field and offset in first byte
1087  data_ptr = cache_status.data;
1088  data_ptr += (offset / 8);
1089 
1090  if (size != 0)
1091  {
1092  // for string type, copy data from pointer
1093  for (i = 0; i < (size / 8); i++)
1094  {
1095  *data_ptr++ = string[i];
1096  }
1097  *(data_ptr - 1) = '\0'; // ensure string is null terminated
1098  }
1099  else
1100  {
1101  *data_ptr = '\0'; // ensure string is null terminated
1102  }
1103 
1104  cache_status.changed = TRUE;
1105  }
1106 
1107  FUNCTION_FINISH(STB_SetNVMRecordString);
1108 }
1109 
1120 void STB_SetNVMRecordNumber(U16BIT block_no, U16BIT offset, U16BIT size, U32BIT value)
1121 {
1122  U8BIT *data_ptr;
1123 
1124  FUNCTION_START(STB_SetNVMRecordNumber);
1125 
1126  ASSERT(block_no < db_status.num_blks);
1127  ASSERT(size > 0);
1128 
1129  // read NVM record into cache
1130  if (CacheNVMRecord(block_no))
1131  {
1132  // find end of field and offset in last byte
1133  data_ptr = cache_status.data;
1134  data_ptr += ((offset + size - 1) / 8);
1135  offset = (7 - ((offset + size - 1) % 8));
1136 
1137  // or for any other type, copy value LSB to field in reverse order
1138  // forces data into big endian format
1139  while (size > 0)
1140  {
1141  *data_ptr &= (U8BIT) ~(0x00000001 << offset);
1142  *data_ptr |= (U8BIT)((value & 0x00000001) << offset);
1143  value = (value >> 1);
1144  // at start of byte, get previous byte
1145  offset++;
1146  if (offset > 7)
1147  {
1148  offset = 0;
1149  data_ptr--;
1150  }
1151  size--;
1152  }
1153 
1154  cache_status.changed = TRUE;
1155  }
1156 
1157  FUNCTION_FINISH(STB_SetNVMRecordNumber);
1158 }
1159 
1171 U8BIT* STB_GetNVMRecordString(U16BIT block_no, U16BIT offset, U16BIT size)
1172 {
1173  U8BIT *data_ptr;
1174 
1175  FUNCTION_START(STB_GetNVMRecordString);
1176  USE_UNWANTED_PARAM(size);
1177 
1178  ASSERT(block_no < db_status.num_blks);
1179 
1180  // read NVM record into cache
1181  if (CacheNVMRecord(block_no))
1182  {
1183  // find start of field and offset in first byte
1184  data_ptr = cache_status.data;
1185  data_ptr += (offset / 8);
1186  }
1187  else
1188  {
1189  data_ptr = NULL;
1190  }
1191 
1192  FUNCTION_FINISH(STB_GetNVMRecordString);
1193 
1194  return(data_ptr);
1195 }
1196 
1208 U32BIT STB_GetNVMRecordNumber(U16BIT block_no, U16BIT offset, U16BIT size)
1209 {
1210  U8BIT *data_ptr;
1211  U32BIT value = 0;
1212 
1213  FUNCTION_START(STB_GetNVMRecordNumber);
1214 
1215  ASSERT(block_no < db_status.num_blks);
1216  ASSERT(size > 0);
1217 
1218  // read NVM record into cache
1219  if (CacheNVMRecord(block_no))
1220  {
1221  // find start of field and offset in first byte
1222  data_ptr = cache_status.data;
1223  data_ptr += (offset / 8);
1224  offset = (offset % 8);
1225 
1226  // or for any other type, copy each field bit to LSB of value
1227  // expects data in big endian format
1228  value = 0;
1229  while (size > 0)
1230  {
1231  value = (value << 1);
1232  value |= (U32BIT)((*data_ptr >> (7 - offset)) & 0x01);
1233  // at end of byte, get next byte
1234  offset++;
1235  if (offset > 7)
1236  {
1237  offset = 0;
1238  data_ptr++;
1239  }
1240  size--;
1241  }
1242  }
1243 
1244  FUNCTION_FINISH(STB_GetNVMRecordNumber);
1245 
1246  return(value);
1247 }
1248 
1262 void STB_WriteNVMData(U16BIT offset, U16BIT size, U8BIT *data_ptr)
1263 {
1264  PU8BIT addr;
1265 
1266  FUNCTION_START(STB_WriteNVMData);
1267 
1268  if (db_status.ram_data == NULL)
1269  {
1270  /* Write the data directly to NVM */
1271  STB_NVMSTBWrite((U32BIT)offset, (U32BIT)size, data_ptr);
1272  }
1273  else
1274  {
1275  /* Copy the data into the RAM cache */
1276  addr = db_status.ram_data + offset;
1277  memcpy((void *)addr, (void *)data_ptr, (size_t)size);
1278  db_status.changed = TRUE;
1279  }
1280 
1281  FUNCTION_FINISH(STB_WriteNVMData);
1282 }
1283 
1297 BOOLEAN STB_ReadNVMData(U16BIT offset, U16BIT size, U8BIT *data_ptr)
1298 {
1299  BOOLEAN ret_val = FALSE;
1300 
1301  FUNCTION_START(STB_ReadNVMData);
1302 
1303  if (db_status.ram_data == NULL)
1304  {
1305  /* Read the data directly to NVM */
1306  if (STB_NVMSTBRead((U32BIT)offset, (U32BIT)size, data_ptr))
1307  {
1308  ret_val = TRUE;
1309  }
1310  }
1311  else
1312  {
1313  /* Copy the data from the RAM cache */
1314  memcpy((void *)data_ptr, (void *)(db_status.ram_data + offset), (size_t)size);
1315  ret_val = TRUE;
1316  }
1317 
1318  FUNCTION_FINISH(STB_ReadNVMData);
1319 
1320  return(ret_val);
1321 }
1322 
1323 //*****************************************************************************
1324 // End of file
1325 //*****************************************************************************
1326 
U32BIT STB_GetNVMRecordNumber(U16BIT block_no, U16BIT offset, U16BIT size)
Reads the specified value of a field from a NVM record.
Definition: stbdbnvm.c:1208
U16BIT STB_GetNextNVMBlock(U16BIT block_no)
Returns the block number of the next NVM record pointed to by the NVM record starting at the specifie...
Definition: stbdbnvm.c:918
void * STB_GetMemory(U32BIT bytes)
Attempts to allocate memory from the heap.
Definition: stbheap.c:221
void STB_DestroyNVMRecord(U16BIT block_no)
Destroys NVM record by marking all NVM blocks used by the record as invalid.
Definition: stbdbnvm.c:805
NVM database access defines, structures and functions.
BOOLEAN STB_CheckNVMDatabaseIntegrity(void)
Reads each database block from NVM and checks its checksum. If the data has already been read into th...
Definition: stbdbnvm.c:564
BOOLEAN STB_NVMSTBRead(U32BIT offset, U32BIT bytes, U8BIT *dest_addr)
Reads bytes from the given position of the STB area of NVM.
Definition: stbnvm.c:506
U8BIT * STB_GetNVMRecordString(U16BIT block_no, U16BIT offset, U16BIT size)
Reads string of a field from a NVM record.
Definition: stbdbnvm.c:1171
void STB_SetNVMRecordString(U16BIT block_no, U16BIT offset, U16BIT size, U8BIT *string)
Writes the specified value into a field of a NVM record.
Definition: stbdbnvm.c:1074
void STB_NVMSave(void)
Saves the RAM cache data to NVM.
Definition: stbdbnvm.c:1047
void STB_SetBE16Bit(U16BIT *addr, U16BIT value)
Stores 16bit int in address, forcing value to be stored in Big endian format.
Definition: stbcsum.c:167
void STB_InitNVMAccess(U16BIT offset)
Initialises parameters needed for NVM block access.
Definition: stbdbnvm.c:472
Header file - Function prototypes for NVM control.
void * STB_ResizeMemory(void *ptr, U32BIT new_num_bytes)
Re-allocates a given memory area to the new size, ensuring data contained within the original memory ...
Definition: stbheap.c:550
void STB_SetNVMRecordNumber(U16BIT block_no, U16BIT offset, U16BIT size, U32BIT value)
Writes the specified value into a field of a NVM record.
Definition: stbdbnvm.c:1120
Header file - Function prototypes for NVM database.
U8BIT STB_CalcChecksum(U8BIT *data_ptr, U32BIT data_size)
Calculates the checksum to zero for the data block provided.
Definition: stbcsum.c:62
void STB_SetNextNVMBlock(U16BIT block_no, U16BIT next_block)
Repairs NVM linked list by pointing the NVM record starting at the specified block number to the reco...
Definition: stbdbnvm.c:865
U16BIT STB_GetNVMBlocksNeeded(U16BIT size)
Returns number of NVM database blocks needed for specified number of bytes.
Definition: stbdbnvm.c:704
U16BIT STB_FindNVMRecordFromId(U8BIT rec_id, U16BIT last_blk)
Finds next record of the type given in NVM.
Definition: stbdbnvm.c:969
void STB_FreeMemory(void *addr)
Releases previously allocated heap memory.
Definition: stbheap.c:336
U16BIT STB_GetBE16Bit(U16BIT *addr)
Returns 16bit int from address, assuming value is stored in Big endian format.
Definition: stbcsum.c:138
Debug functions header file.
Database access defines, structures and public functions.
U16BIT STB_CreateNVMRecord(U8BIT rec_id, U16BIT size)
Creates a record of the type given in NVM by overwriting invalid blocks.
Definition: stbdbnvm.c:731
void STB_WriteNVMData(U16BIT offset, U16BIT size, U8BIT *data_ptr)
Writes the given data to NVM.
Definition: stbdbnvm.c:1262
void STB_InitNVMMap(void)
Initialises parameters needed for NVM block access (calcs num blocks if required) ...
Definition: stbdbnvm.c:504
U16BIT STB_GetNVMBlocksUsed(void)
Returns total number of NVM database blocks in use.
Definition: stbdbnvm.c:661
BOOLEAN STB_ReadNVMData(U16BIT offset, U16BIT size, U8BIT *data_ptr)
Reads data from the NVM into the given buffer.
Definition: stbdbnvm.c:1297
System Wide Global Technical Data Type Definitions.
U16BIT STB_GetNVMBlockCount(void)
Returns total number of NVM database blocks.
Definition: stbdbnvm.c:637
BOOLEAN STB_CheckChecksum(U8BIT *data_ptr, U32BIT data_size)
Validates the checksum to zero for the block pointer provided.
Definition: stbcsum.c:96
Header file - Function prototypes for check sum calcs.
BOOLEAN STB_NVMSTBWrite(U32BIT offset, U32BIT bytes, U8BIT *src_addr)
Writes bytes into the given position of the STB area of NVM.
Definition: stbnvm.c:539
Header file - Function prototypes for heap memory.
void STB_SetNVMAccessRAM(U8BIT *ram_ptr)
Sets all DB NVM access to RAM block supplied instead of NVM (cancel if NULL).
Definition: stbdbnvm.c:599
U32BIT STB_NVMGetSTBSize(void)
Returns size of STB database storage are (in bytes).
Definition: stbnvm.c:478
void STB_NVMFlushCache(BOOLEAN clear)
Flush cached changes.
Definition: stbdbnvm.c:1017
U16BIT STB_GetNVMBlockSize(void)
Returns the size of an NVM database block, in bytes.
Definition: stbdbnvm.c:686
U8BIT * STB_GetNVMAccessRAM(void)
Returns the current RAM pointer used for DB NVM access.
Definition: stbdbnvm.c:619