ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
ruuvi_task_flash.c
Go to the documentation of this file.
1
23#if RT_FLASH_ENABLED
24#include "ruuvi_driver_error.h"
25#include "ruuvi_driver_sensor.h"
27#include "ruuvi_interface_log.h"
30#include "ruuvi_task_flash.h"
31
32#include <stddef.h>
33#include <stdio.h>
34#include <string.h>
35#include <inttypes.h>
36
37#ifndef TASK_FLASH_LOG_LEVEL
38#define TASK_FLASH_LOG_LEVEL RI_LOG_LEVEL_INFO
39#endif
40
41#ifndef RT_FLASH_ERROR_FILE
42# define RT_FLASH_ERROR_FILE 0xBFFE
43#endif
44
45#ifndef RT_FLASH_ERROR_RECORD
46# define RT_FLASH_ERROR_RECORD 0xBFFE
47#endif
48
49#define LOG(msg) ri_log(TASK_FLASH_LOG_LEVEL, msg)
50#define LOGD(msg) ri_log(RI_LOG_DEBUG, msg)
51#define LOGW(msg) ri_log(RI_LOG_WARNING, msg)
52#define LOGHEX(msg, len) ri_log_hex(TASK_FLASH_LOG_LEVEL, msg, len)
53
54typedef struct
55{
56 rd_status_t error;
57 char filename[32];
58 int line;
59} rt_flash_error_cause_t;
60
61#if 0
62static void on_error (const rd_status_t err,
63 const bool fatal,
64 const char * file,
65 const int line)
66{
67 if (!fatal)
68 {
69 return;
70 }
71
72 error_cause_t error = {.error = err, .line = line };
73 rd_status_t err_code;
74 uint32_t timeout = 0;
75 strncpy (error.filename, file, sizeof (error.filename));
76 // Store reason of fatal error
77 err_code = rt_flash_store (APPLICATION_FLASH_ERROR_FILE,
78 APPLICATION_FLASH_ERROR_RECORD,
79 &error, sizeof (error));
80
81 // Wait for flash store op to complete
82 while (RD_SUCCESS == err_code &&
83 timeout < 1000 &&
85 {
86 timeout++;
87 // Use microsecond wait to busyloop instead of millisecond wait to low-power sleep
88 // as low-power sleep may hang on interrupt context.
89 ri_delay_us (1000);
90 }
91
92 // Try to enter bootloader, if that fails reset.
95}
96#endif
97
98#ifndef CEEDLING
99static
100#endif
101void print_error_cause (void)
102{
103 rt_flash_error_cause_t error;
104 rd_status_t err_code;
105 err_code = rt_flash_load (RT_FLASH_ERROR_FILE,
106 RT_FLASH_ERROR_RECORD,
107 &error, sizeof (error));
108
109 if (RD_SUCCESS == err_code)
110 {
111 char error_str[128];
112 size_t index = 0;
113 index += snprintf (error_str, sizeof (error_str), "Previous fatal error: %s:%d: ",
114 error.filename, error.line);
115 index += ri_error_to_string (error.error, error_str + index,
116 sizeof (error_str) - index);
117 snprintf (error_str + index, sizeof (error_str) - index, "\r\n");
118 LOG (error_str);
119 }
120}
121
123{
124 rd_status_t err_code = RD_SUCCESS;
125 err_code |= ri_flash_init();
126
127 // Error on flash? purge, reboot
128 if (RD_SUCCESS != err_code)
129 {
132 // Stop test execution here.
133# ifdef CEEDLING
134 return err_code;
135# endif
136 }
137
138 // Print previous fatal error
139 print_error_cause();
140 return err_code;
141}
142
143rd_status_t rt_flash_store (const uint16_t page_id, const uint16_t record_id,
144 const void * const message, const size_t message_length)
145{
146 rd_status_t status = RD_SUCCESS;
147 status = ri_flash_record_set (page_id, record_id, message_length, message);
148
149 if (RD_ERROR_NO_MEM == status)
150 {
152
153 while (rt_flash_busy())
154 {
155 ri_yield();
156 }
157
158 status = ri_flash_record_set (page_id, record_id, message_length, message);
159 }
160
161 return status;
162}
163
164rd_status_t rt_flash_load (const uint16_t page_id, const uint16_t record_id,
165 void * const message, const size_t message_length)
166{
167 return ri_flash_record_get (page_id, record_id, message_length, message);
168}
169
170rd_status_t rt_flash_free (const uint16_t file_id, const uint16_t record_id)
171{
172 return ri_flash_record_delete (file_id, record_id);
173}
174
176{
177 return ri_flash_gc_run();
178}
179
180bool rt_flash_busy (void)
181{
182 return ri_flash_is_busy();
183}
184
185
186
187#else
188
189#include "ruuvi_driver_error.h"
190#include <stdlib.h>
192{
193 // Setup error reset
194 return RD_SUCCESS;
195}
196
197rd_status_t rt_flash_store (const uint16_t file_id, const uint16_t record_id,
198 const void * const message, const size_t message_length)
199{
200 return RD_SUCCESS;
201}
202
203rd_status_t rt_flash_load (const uint16_t page_id, const uint16_t record_id,
204 void * const message, const size_t message_length)
205{
206 return RD_ERROR_NOT_FOUND;
207}
208
209bool rt_flash_busy (void)
210{
211 return false;
212}
213#endif
uint32_t rd_status_t
bitfield for representing errors
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_NO_MEM
No Memory for operation.
#define RD_ERROR_NOT_FOUND
Not found.
rd_status_t ri_flash_gc_run(void)
Run garbage collection.
bool ri_flash_is_busy()
Check if flash is busy.
void ri_flash_purge(void)
Purge flash.
rd_status_t ri_flash_record_set(const uint32_t page_id, const uint32_t record_id, const size_t data_size, const void *const data)
Set data to record in page.
rd_status_t ri_flash_init(void)
rd_status_t ri_flash_record_delete(const uint32_t file_id, const uint32_t record_id)
Mark a record for deletion.
rd_status_t ri_flash_record_get(const uint32_t page_id, const uint32_t record_id, const size_t data_size, void *const data)
Get data from record in page.
size_t ri_error_to_string(rd_status_t error, char *error_string, size_t space_remaining)
Write text description of error message into given string pointer and null-terminate it....
bool rt_flash_busy(void)
Check if flash is running an operation.
rd_status_t rt_flash_gc_run(void)
Trigger garbage collection.
rd_status_t rt_flash_init(void)
Initialize flash storage.
rd_status_t rt_flash_free(const uint16_t file_id, const uint16_t record_id)
Free data from flash.
rd_status_t rt_flash_load(const uint16_t page_id, const uint16_t record_id, void *const message, const size_t message_length)
Load data from flash.
rd_status_t rt_flash_store(const uint16_t file_id, const uint16_t record_id, const void *const message, const size_t message_length)
Store data to flash.
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Ruuvi sensor interface Lifecycle: Beta
Interface functions to persistent flash storage.
void ri_power_enter_bootloader(void)
Enter bootloader.
void ri_power_reset(void)
Reset IC.
rd_status_t ri_yield(void)
Function which will release execution.
rd_status_t ri_delay_us(uint32_t time)
Delay a given number of microseconds.