Loading...
Searching...
No Matches
mem.c
1/***********************************************************************************
2 * @file launch.c *
3 * @author Matt Ricci *
4 * @addtogroup Shell *
5 * *
6 * @{ *
7 ***********************************************************************************/
8
9#include "devicelist.h"
10
11#include "string.h"
12#include "stdio.h"
13
14#include "dataframe.h"
15#include "flash.h"
16#include "parser.h"
17#include "shell.h"
18
19static void Mem_exec(UART_t *uart, char *);
20static void Mem_help(UART_t *uart);
21
22DEFINE_PROGRAM_HANDLE("mem", Mem_exec, Mem_help)
23
24static void Mem_help(UART_t *uart) {
25 uart->println(uart, "NAME:");
26 uart->println(uart, "\tmem\n");
27 uart->println(uart, "USAGE:");
28 uart->println(uart, "\tmem erase");
29 uart->println(uart, "\tmem read [all | apogee]\n");
30 uart->println(uart, "DESCRIPTION:");
31 uart->println(uart, "\terase");
32 uart->println(uart, "\t Erase all data written to memory.\n");
33 uart->println(uart, "\tread [all]");
34 uart->println(uart, "\t Read binary data from memory.\n");
35 uart->println(uart, "OPTIONS:");
36 uart->println(uart, "\t-h, --help");
37 uart->println(uart, "\t Print this help and exit");
38}
39
40/* =============================================================================== */
51static void Mem_exec(UART_t *uart, char *flags) {
52 Flash_t *flash = DeviceList_getDeviceHandle(DEVICE_FLASH).device;
53
54 ArgParser parser = ArgParser_init();
55 int argReadIdx = parser.addArg(
56 &parser, "read", 0, ARG_TYPE_STRING, false
57 );
58 int argEraseIdx = parser.addArg(
59 &parser, "erase", 'r', ARG_TYPE_BOOL, false
60 );
61
62 // clang-format off
63 int mutexResetRepeatIdx = parser.addMutexGroup(
64 &parser, (int[]){
65 argReadIdx,
66 argEraseIdx,
67 }, 2
68 );
69 // clang-format on
70
71 char *tokens[MAX_ARGS];
72 int numTokens = 0;
73
74 // Tokenize the input string
75 char *token = strtok(flags, " ");
76 while (token != NULL && numTokens < MAX_ARGS) {
77 tokens[numTokens++] = token;
78 token = strtok(NULL, " ");
79 }
80
81 // Parse input tokens
82 parser.parseArgs(&parser, numTokens, tokens);
83
84 // Early exit with error message
85 if (parser.error.status == PARSER_STATUS_ERROR) {
86 uart->println(uart, parser.error.msg);
87 return;
88 }
89
90 if (parser.args[argReadIdx].provided) {
91 // Read all pages and print raw binary
92 if (!strcmp(parser.args[argReadIdx].value, "all")) {
93 taskENTER_CRITICAL();
94 volatile uint8_t pageData[256];
95 for (long i = 0; i < flash->pageCount; i++) {
96 flash->readPage(flash, i * 0x100, pageData);
97 for (int j = 0; j < flash->pageSize; j++)
98 uart->send(uart, pageData[j]);
99 }
100 taskEXIT_CRITICAL();
101 }
102 // Search memory for apogee event and print results
103 else if (!strcmp(parser.args[argReadIdx].value, "apogee")) {
104
105 char str[50];
106
107 uint8_t flashData[259]; // 3-byte overlap + 256-byte page
108 uint8_t header[] = {HEADER_EVENT_APOGEE, 0xB0, 0x0B};
109
110 uint8_t *packet = NULL;
111
112 // Read in first page
113 flash->readPage(flash, 0, &flashData[3]);
114 memset(flashData, 0, 3); // Clear first 3 bytes for boundary condition
115
116 // Iterate each page
117 for (long i = 0; i < flash->pageCount; i++) {
118 snprintf(str, 50, "\rChecking page %ld of %ld", i, flash->pageCount);
119 uart->print(uart, str);
120 if (i > 0) {
121 // After the first page, copy the last 3 bytes from previous
122 // into the first 3 bytes of the next
123 memcpy(&flashData[0], &flashData[256], 3);
124 // Read the next page beginning after bytes from previous
125 flash->readPage(flash, i * flash->pageSize, &flashData[3]);
126 }
127 // Iterate every byte in page
128 for (int j = 0; j < 256; j++) {
129 // Write string if event dataframe is found and exit
130 if (!memcmp((packet = &flashData[j]), header, 3)) {
131 float flightTime = *(uint16_t *)&flashData[j + 3] / 1000.0f;
132 snprintf(str, 50, "\r\nApogee at %fs.", flightTime);
133 goto EXIT;
134 }
135 }
136 }
137
138 // Write error to string if no event dataframe is found
139 snprintf(str, 50, "\r\nNo apogee event was found in memory.");
140
141 EXIT:
142 // Print the result
143 uart->println(uart, str);
144 }
145
146 // Request cannot be fulfilled
147 else {
148 uart->println(uart, "Error: Requested value for read not recognised.");
149 }
150 }
151
152 else if (parser.args[argEraseIdx].provided) {
153 uart->print(uart, "Clearing flash... ");
154 flash->erase(flash);
155 uart->println(uart, "Done.");
156 }
157}
158
Defines the API for Flash memory storage.
int pageSize
Number of bytes per page.
Definition flash.h:22
long pageCount
Total number of pages.
Definition flash.h:23
void(* readPage)(struct Flash *, uint32_t, volatile uint8_t *)
Read page method.
Definition flash.h:25
void(* erase)(struct Flash *)
Chip erase method.
Definition flash.h:24
DeviceHandle_t DeviceList_getDeviceHandle(DeviceKey)
Retrieve device handle from list by key.
Definition devicelist.c:36
Struct definition for UART interface.
Definition uart.h:132