Line data Source code
1 : // Copyright 2024 Accenture.
2 :
3 : #include "eeprom/EepromDriver.h"
4 :
5 : #include "bsp/Bsp.h"
6 :
7 : #include <sys/stat.h>
8 :
9 : #include <cstring>
10 : #include <fcntl.h>
11 : #include <unistd.h>
12 :
13 : namespace eeprom
14 : {
15 :
16 8 : EepromDriver::EepromDriver() : eepromFd(-1)
17 : {
18 8 : bool fileExisted = false;
19 :
20 : // Try opening existing file first
21 8 : eepromFd = open(eepromFilePath.c_str(), O_RDWR);
22 :
23 8 : if (eepromFd != -1)
24 : {
25 7 : fileExisted = true;
26 : }
27 : else
28 : {
29 : // If opening fails, try creating it
30 1 : eepromFd = open(eepromFilePath.c_str(), O_RDWR | O_CREAT, 0666);
31 :
32 1 : if (eepromFd != -1)
33 : {
34 1 : chmod(eepromFilePath.c_str(), 0666);
35 : }
36 : }
37 :
38 : // Initialize only for newly created files
39 8 : if (eepromFd != -1 && !fileExisted)
40 : {
41 : // Resize EEPROM file
42 1 : if (ftruncate(eepromFd, EEPROM_SIZE) == 0)
43 : {
44 : // Fill with 0xFF
45 : uint8_t buffer[EEPROM_SIZE];
46 1 : memset(buffer, 0xFF, EEPROM_SIZE);
47 :
48 : // After truncate, file offset is guaranteed to be 0
49 1 : ssize_t const written = ::write(eepromFd, buffer, EEPROM_SIZE);
50 :
51 1 : if (written == static_cast<ssize_t>(EEPROM_SIZE))
52 : {
53 1 : fsync(eepromFd);
54 : }
55 : }
56 : }
57 8 : }
58 :
59 6 : bsp::BspReturnCode EepromDriver::init()
60 : {
61 6 : if (eepromFd == -1)
62 : {
63 0 : return ::bsp::BSP_ERROR;
64 : }
65 :
66 : // Verify file size is correct
67 : struct stat fileStat;
68 6 : if (fstat(eepromFd, &fileStat) != 0)
69 : {
70 0 : return ::bsp::BSP_ERROR;
71 : }
72 :
73 : // If file size doesn't match expected EEPROM size, resize it
74 6 : if (fileStat.st_size != EEPROM_SIZE)
75 : {
76 0 : if (ftruncate(eepromFd, EEPROM_SIZE) != 0)
77 : {
78 0 : return ::bsp::BSP_ERROR;
79 : }
80 :
81 0 : if (fsync(eepromFd) != 0)
82 : {
83 0 : return ::bsp::BSP_ERROR;
84 : }
85 : }
86 :
87 6 : return ::bsp::BSP_OK;
88 : }
89 :
90 : bsp::BspReturnCode
91 5 : EepromDriver::write(uint32_t const address, uint8_t const* const buffer, uint32_t const length)
92 : {
93 5 : bool success
94 5 : = ((-1 != eepromFd) && (address < EEPROM_SIZE) && (length <= (EEPROM_SIZE - address)));
95 :
96 5 : success = (success && (lseek(eepromFd, address, SEEK_SET) != -1));
97 5 : success = (success && (::write(eepromFd, buffer, length) == static_cast<ssize_t>(length)));
98 5 : success = (success && (fsync(eepromFd) == 0));
99 :
100 5 : if (!success)
101 : {
102 2 : printf("Failed to write to EEPROM file\r\n");
103 2 : return ::bsp::BSP_ERROR;
104 : }
105 3 : return ::bsp::BSP_OK;
106 : }
107 :
108 : bsp::BspReturnCode
109 5 : EepromDriver::read(uint32_t const address, uint8_t* const buffer, uint32_t const length)
110 : {
111 5 : bool success
112 5 : = ((-1 != eepromFd) && (address < EEPROM_SIZE) && (length <= (EEPROM_SIZE - address)));
113 :
114 5 : success = (success && (lseek(eepromFd, address, SEEK_SET) != -1));
115 5 : success = (success && (::read(eepromFd, buffer, length) == static_cast<ssize_t>(length)));
116 :
117 5 : if (!success)
118 : {
119 2 : printf("Failed to read from EEPROM file\r\n");
120 2 : return ::bsp::BSP_ERROR;
121 : }
122 3 : return ::bsp::BSP_OK;
123 : }
124 :
125 16 : EepromDriver::~EepromDriver()
126 : {
127 8 : if (-1 != eepromFd)
128 : {
129 8 : fsync(eepromFd);
130 8 : close(eepromFd);
131 8 : eepromFd = -1;
132 : }
133 8 : }
134 :
135 : } // namespace eeprom
|