Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
strategy.c
00001 /* 00002 * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "flash-journal-strategy-sequential/flash_journal_private.h" 00019 #include "flash-journal-strategy-sequential/flash_journal_strategy_sequential.h" 00020 #include "support_funcs.h" 00021 #include <string.h> 00022 #include <stdio.h> 00023 00024 SequentialFlashJournal_t *activeJournal; 00025 00026 /* forward declarations */ 00027 void mtdHandler(int32_t status, ARM_STORAGE_OPERATION operation); 00028 00029 static inline int32_t mtdGetTotalCapacity(ARM_DRIVER_STORAGE *mtd, uint64_t *capacityP) 00030 { 00031 /* fetch MTD's INFO */ 00032 ARM_STORAGE_INFO mtdInfo; 00033 int32_t rc = mtd->GetInfo(&mtdInfo); 00034 if (rc != ARM_DRIVER_OK) { 00035 return JOURNAL_STATUS_STORAGE_API_ERROR; 00036 } 00037 *capacityP = mtdInfo.total_storage; 00038 00039 return JOURNAL_STATUS_OK; 00040 } 00041 00042 static inline int32_t flashJournalStrategySequential_read_sanityChecks(SequentialFlashJournal_t *journal, const void *blob, size_t sizeofBlob) 00043 { 00044 if ((journal == NULL) || (blob == NULL) || (sizeofBlob == 0)) { 00045 return JOURNAL_STATUS_PARAMETER; 00046 } 00047 if ((journal->state == SEQUENTIAL_JOURNAL_STATE_NOT_INITIALIZED) || (journal->state == SEQUENTIAL_JOURNAL_STATE_INIT_SCANNING_LOG_HEADERS)) { 00048 return JOURNAL_STATUS_NOT_INITIALIZED; 00049 } 00050 if (journal->state != SEQUENTIAL_JOURNAL_STATE_INITIALIZED) { 00051 return JOURNAL_STATUS_ERROR; /* journal is in an un-expected state. */ 00052 } 00053 // printf("read sanity checks: totalDataRead = %lu, sizeofJournaledBlob = %lu\n", (uint32_t)journal->read.totalDataRead, (uint32_t)journal->info.sizeofJournaledBlob); 00054 if ((journal->info.sizeofJournaledBlob == 0) || (journal->read.totalDataRead == journal->info.sizeofJournaledBlob)) { 00055 journal->read.totalDataRead = 0; 00056 return JOURNAL_STATUS_EMPTY; 00057 } 00058 00059 return JOURNAL_STATUS_OK; 00060 } 00061 00062 static inline int32_t flashJournalStrategySequential_log_sanityChecks(SequentialFlashJournal_t *journal, const void *blob, size_t sizeofBlob) 00063 { 00064 if ((journal == NULL) || (blob == NULL) || (sizeofBlob == 0)) { 00065 return JOURNAL_STATUS_PARAMETER; 00066 } 00067 if ((journal->state == SEQUENTIAL_JOURNAL_STATE_NOT_INITIALIZED) || (journal->state == SEQUENTIAL_JOURNAL_STATE_INIT_SCANNING_LOG_HEADERS)) { 00068 return JOURNAL_STATUS_NOT_INITIALIZED; 00069 } 00070 if ((journal->state != SEQUENTIAL_JOURNAL_STATE_INITIALIZED) && (journal->state != SEQUENTIAL_JOURNAL_STATE_LOGGING_BODY)) { 00071 return JOURNAL_STATUS_ERROR; /* journal is in an un-expected state. */ 00072 } 00073 if (journal->state == SEQUENTIAL_JOURNAL_STATE_INITIALIZED) { 00074 if (sizeofBlob > journal->info.capacity) { 00075 return JOURNAL_STATUS_BOUNDED_CAPACITY; /* adding this log chunk would cause us to exceed capacity (write past the tail). */ 00076 } 00077 } else if (journal->state == SEQUENTIAL_JOURNAL_STATE_LOGGING_BODY) { 00078 if (journal->log.offset + sizeofBlob > journal->log.tailOffset) { 00079 return JOURNAL_STATUS_BOUNDED_CAPACITY; /* adding this log chunk would cause us to exceed capacity (write past the tail). */ 00080 } 00081 } 00082 00083 return JOURNAL_STATUS_OK; 00084 } 00085 00086 static inline int32_t flashJournalStrategySequential_commit_sanityChecks(SequentialFlashJournal_t *journal) 00087 { 00088 if (journal == NULL) { 00089 return JOURNAL_STATUS_PARAMETER; 00090 } 00091 if (journal->state == SEQUENTIAL_JOURNAL_STATE_LOGGING_BODY) { 00092 if (journal->prevCommand != FLASH_JOURNAL_OPCODE_LOG_BLOB) { 00093 return JOURNAL_STATUS_ERROR; 00094 } 00095 if ((journal->log.offset == ARM_STORAGE_INVALID_OFFSET) || 00096 (journal->log.tailOffset == ARM_STORAGE_INVALID_OFFSET) || 00097 (journal->log.tailOffset < journal->log.offset) || 00098 (journal->log.tail.sizeofBlob == 0) || 00099 (journal->log.tail.sizeofBlob > journal->info.capacity)) { 00100 return JOURNAL_STATUS_ERROR; /* journal is in an un-expected state. */ 00101 } 00102 } 00103 00104 return JOURNAL_STATUS_OK; 00105 } 00106 00107 int32_t flashJournalStrategySequential_initialize(FlashJournal_t *_journal, 00108 ARM_DRIVER_STORAGE *mtd, 00109 const FlashJournal_Ops_t *ops, 00110 FlashJournal_Callback_t callback) 00111 { 00112 int32_t rc; 00113 00114 SequentialFlashJournal_t *journal; 00115 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00116 journal->state = SEQUENTIAL_JOURNAL_STATE_NOT_INITIALIZED; 00117 00118 /* fetch MTD's total capacity */ 00119 uint64_t mtdCapacity; 00120 if ((rc = mtdGetTotalCapacity(mtd, &mtdCapacity)) != JOURNAL_STATUS_OK) { 00121 return rc; 00122 } 00123 ARM_STORAGE_INFO mtdInfo; 00124 if ((rc = mtd->GetInfo(&mtdInfo)) != ARM_DRIVER_OK) { 00125 return JOURNAL_STATUS_STORAGE_API_ERROR; 00126 } 00127 00128 /* initialize the journal structure */ 00129 memcpy(&journal->ops, ops, sizeof(FlashJournal_Ops_t)); 00130 journal->mtd = mtd; 00131 journal->mtdCapabilities = mtd->GetCapabilities(); /* fetch MTD's capabilities */ 00132 journal->sequentialSkip = mtdCapacity / SEQUENTIAL_FLASH_JOURNAL_MAX_LOGGED_BLOBS; 00133 journal->info.capacity = journal->sequentialSkip - (sizeof(SequentialFlashJournalLogHead_t) + sizeof(SequentialFlashJournalLogTail_t)); /* effective capacity */ 00134 journal->info.program_unit = mtdInfo.program_unit; 00135 journal->callback = callback; 00136 journal->prevCommand = FLASH_JOURNAL_OPCODE_INITIALIZE; 00137 00138 /* initialize MTD */ 00139 ARM_STORAGE_CAPABILITIES mtdCaps = mtd->GetCapabilities(); 00140 rc = mtd->Initialize(mtdHandler); 00141 if (rc < ARM_DRIVER_OK) { 00142 memset(journal, 0, sizeof(FlashJournal_t)); 00143 return JOURNAL_STATUS_STORAGE_API_ERROR; 00144 } 00145 if ((mtdCaps.asynchronous_ops) && (rc == ARM_DRIVER_OK)) { 00146 return JOURNAL_STATUS_OK; /* we've got pending asynchronous activity. */ 00147 } 00148 00149 if ((rc = discoverLatestLoggedBlob(journal)) != JOURNAL_STATUS_OK) { 00150 return rc; 00151 } 00152 00153 return 1; /* synchronous completion */ 00154 } 00155 00156 FlashJournal_Status_t flashJournalStrategySequential_getInfo(FlashJournal_t *_journal, FlashJournal_Info_t *infoP) 00157 { 00158 SequentialFlashJournal_t *journal; 00159 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00160 00161 memcpy(infoP, &journal->info, sizeof(FlashJournal_Info_t)); 00162 return JOURNAL_STATUS_OK; 00163 } 00164 00165 int32_t flashJournalStrategySequential_read(FlashJournal_t *_journal, void *blob, size_t sizeofBlob) 00166 { 00167 SequentialFlashJournal_t *journal; 00168 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00169 00170 int32_t rc; 00171 if ((rc = flashJournalStrategySequential_read_sanityChecks(journal, blob, sizeofBlob)) != JOURNAL_STATUS_OK) { 00172 return rc; 00173 } 00174 00175 journal->read.blob = blob; 00176 journal->read.sizeofBlob = sizeofBlob; 00177 00178 if ((journal->prevCommand != FLASH_JOURNAL_OPCODE_READ_BLOB) || (journal->read.totalDataRead == 0)) { 00179 journal->read.offset = journal->mtdStartOffset 00180 + (journal->currentBlobIndex * journal->sequentialSkip) 00181 + sizeof(SequentialFlashJournalLogHead_t); 00182 journal->read.totalDataRead = 0; 00183 } else { 00184 /* journal->read.offset is already set from the previous read execution */ 00185 // printf("flashJournalStrategySequential_read: continuing read of %lu from offset %lu\n", sizeofBlob, (uint32_t)journal->read.offset); 00186 } 00187 journal->read.dataBeingRead = blob; 00188 journal->read.amountLeftToRead = ((journal->info.sizeofJournaledBlob - journal->read.totalDataRead) < sizeofBlob) ? 00189 (journal->info.sizeofJournaledBlob - journal->read.totalDataRead) : sizeofBlob; 00190 // printf("amount left to read %u\n", journal->read.amountLeftToRead); 00191 00192 journal->state = SEQUENTIAL_JOURNAL_STATE_READING; 00193 journal->prevCommand = FLASH_JOURNAL_OPCODE_READ_BLOB; 00194 return flashJournalStrategySequential_read_progress(); 00195 } 00196 00197 int32_t flashJournalStrategySequential_log(FlashJournal_t *_journal, const void *blob, size_t size) 00198 { 00199 SequentialFlashJournal_t *journal; 00200 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00201 00202 int32_t rc; 00203 if ((rc = flashJournalStrategySequential_log_sanityChecks(journal, blob, size)) != JOURNAL_STATUS_OK) { 00204 return rc; 00205 } 00206 00207 journal->log.blob = blob; 00208 journal->log.sizeofBlob = size; 00209 00210 if (journal->prevCommand != FLASH_JOURNAL_OPCODE_LOG_BLOB) { 00211 uint32_t logBlobIndex = journal->currentBlobIndex + 1; 00212 if (logBlobIndex == SEQUENTIAL_FLASH_JOURNAL_MAX_LOGGED_BLOBS) { 00213 logBlobIndex = 0; 00214 } 00215 journal->log.eraseOffset = journal->mtdStartOffset + (logBlobIndex * journal->sequentialSkip); 00216 00217 /* ensure that the request is at least as large as the minimum program unit */ 00218 if (size < journal->info.program_unit) { 00219 return JOURNAL_STATUS_SMALL_LOG_REQUEST; 00220 } 00221 00222 journal->state = SEQUENTIAL_JOURNAL_STATE_LOGGING_ERASE; /* start with erasing the log region */ 00223 journal->prevCommand = FLASH_JOURNAL_OPCODE_LOG_BLOB; 00224 } else { 00225 journal->log.dataBeingLogged = blob; 00226 journal->log.amountLeftToLog = size; 00227 } 00228 00229 return flashJournalStrategySequential_log_progress(); 00230 } 00231 00232 int32_t flashJournalStrategySequential_commit(FlashJournal_t *_journal) 00233 { 00234 SequentialFlashJournal_t *journal; 00235 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00236 00237 int32_t rc; 00238 if ((rc = flashJournalStrategySequential_commit_sanityChecks(journal)) != JOURNAL_STATUS_OK) { 00239 return rc; 00240 } 00241 00242 if (journal->prevCommand == FLASH_JOURNAL_OPCODE_LOG_BLOB) { 00243 journal->log.offset = journal->log.tailOffset; 00244 journal->log.dataBeingLogged = (const uint8_t *)&journal->log.tail; 00245 journal->log.amountLeftToLog = sizeof(SequentialFlashJournalLogTail_t); 00246 journal->state = SEQUENTIAL_JOURNAL_STATE_LOGGING_TAIL; 00247 } else { 00248 uint32_t logBlobIndex = journal->currentBlobIndex + 1; 00249 if (logBlobIndex == SEQUENTIAL_FLASH_JOURNAL_MAX_LOGGED_BLOBS) { 00250 logBlobIndex = 0; 00251 } 00252 journal->log.eraseOffset = journal->mtdStartOffset + (logBlobIndex * journal->sequentialSkip); 00253 journal->state = SEQUENTIAL_JOURNAL_STATE_LOGGING_ERASE; 00254 } 00255 00256 journal->prevCommand = FLASH_JOURNAL_OPCODE_COMMIT; 00257 return flashJournalStrategySequential_log_progress(); 00258 } 00259 00260 int32_t flashJournalStrategySequential_reset(FlashJournal_t *_journal) 00261 { 00262 SequentialFlashJournal_t *journal; 00263 activeJournal = journal = (SequentialFlashJournal_t *)_journal; 00264 00265 journal->state = SEQUENTIAL_JOURNAL_STATE_RESETING; 00266 00267 journal->prevCommand = FLASH_JOURNAL_OPCODE_RESET; 00268 return flashJournalStrategySequential_reset_progress(); 00269 }
Generated on Tue Jul 12 2022 12:28:51 by
 1.7.2
 1.7.2 
    