Erste version der Software für der Prototyp

Committer:
borlanic
Date:
Thu Mar 29 07:02:09 2018 +0000
Revision:
0:380207fcb5c1
Child:
4:75df35ef4fb6
Encoder, IMU --> OK; Controller --> in bearbeitung

Who changed what in which revision?

UserRevisionLine numberNew contents of line
borlanic 0:380207fcb5c1 1 /* mbed Microcontroller Library
borlanic 0:380207fcb5c1 2 * Copyright (c) 2017 ARM Limited
borlanic 0:380207fcb5c1 3 *
borlanic 0:380207fcb5c1 4 * Licensed under the Apache License, Version 2.0 (the "License");
borlanic 0:380207fcb5c1 5 * you may not use this file except in compliance with the License.
borlanic 0:380207fcb5c1 6 * You may obtain a copy of the License at
borlanic 0:380207fcb5c1 7 *
borlanic 0:380207fcb5c1 8 * http://www.apache.org/licenses/LICENSE-2.0
borlanic 0:380207fcb5c1 9 *
borlanic 0:380207fcb5c1 10 * Unless required by applicable law or agreed to in writing, software
borlanic 0:380207fcb5c1 11 * distributed under the License is distributed on an "AS IS" BASIS,
borlanic 0:380207fcb5c1 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
borlanic 0:380207fcb5c1 13 * See the License for the specific language governing permissions and
borlanic 0:380207fcb5c1 14 * limitations under the License.
borlanic 0:380207fcb5c1 15 */
borlanic 0:380207fcb5c1 16
borlanic 0:380207fcb5c1 17 #include "ChainingBlockDevice.h"
borlanic 0:380207fcb5c1 18
borlanic 0:380207fcb5c1 19
borlanic 0:380207fcb5c1 20 ChainingBlockDevice::ChainingBlockDevice(BlockDevice **bds, size_t bd_count)
borlanic 0:380207fcb5c1 21 : _bds(bds), _bd_count(bd_count)
borlanic 0:380207fcb5c1 22 , _read_size(0), _program_size(0), _erase_size(0), _size(0)
borlanic 0:380207fcb5c1 23 , _erase_value(-1)
borlanic 0:380207fcb5c1 24 {
borlanic 0:380207fcb5c1 25 }
borlanic 0:380207fcb5c1 26
borlanic 0:380207fcb5c1 27 static bool is_aligned(uint64_t x, uint64_t alignment)
borlanic 0:380207fcb5c1 28 {
borlanic 0:380207fcb5c1 29 return (x / alignment) * alignment == x;
borlanic 0:380207fcb5c1 30 }
borlanic 0:380207fcb5c1 31
borlanic 0:380207fcb5c1 32 int ChainingBlockDevice::init()
borlanic 0:380207fcb5c1 33 {
borlanic 0:380207fcb5c1 34 _read_size = 0;
borlanic 0:380207fcb5c1 35 _program_size = 0;
borlanic 0:380207fcb5c1 36 _erase_size = 0;
borlanic 0:380207fcb5c1 37 _erase_value = -1;
borlanic 0:380207fcb5c1 38 _size = 0;
borlanic 0:380207fcb5c1 39
borlanic 0:380207fcb5c1 40 // Initialize children block devices, find all sizes and
borlanic 0:380207fcb5c1 41 // assert that block sizes are similar. We can't do this in
borlanic 0:380207fcb5c1 42 // the constructor since some block devices may need to be
borlanic 0:380207fcb5c1 43 // initialized before they know their block size/count
borlanic 0:380207fcb5c1 44 for (size_t i = 0; i < _bd_count; i++) {
borlanic 0:380207fcb5c1 45 int err = _bds[i]->init();
borlanic 0:380207fcb5c1 46 if (err) {
borlanic 0:380207fcb5c1 47 return err;
borlanic 0:380207fcb5c1 48 }
borlanic 0:380207fcb5c1 49
borlanic 0:380207fcb5c1 50 bd_size_t read = _bds[i]->get_read_size();
borlanic 0:380207fcb5c1 51 if (i == 0 || (read >= _read_size && is_aligned(read, _read_size))) {
borlanic 0:380207fcb5c1 52 _read_size = read;
borlanic 0:380207fcb5c1 53 } else {
borlanic 0:380207fcb5c1 54 MBED_ASSERT(_read_size > read && is_aligned(_read_size, read));
borlanic 0:380207fcb5c1 55 }
borlanic 0:380207fcb5c1 56
borlanic 0:380207fcb5c1 57 bd_size_t program = _bds[i]->get_program_size();
borlanic 0:380207fcb5c1 58 if (i == 0 || (program >= _program_size && is_aligned(program, _program_size))) {
borlanic 0:380207fcb5c1 59 _program_size = program;
borlanic 0:380207fcb5c1 60 } else {
borlanic 0:380207fcb5c1 61 MBED_ASSERT(_program_size > program && is_aligned(_program_size, program));
borlanic 0:380207fcb5c1 62 }
borlanic 0:380207fcb5c1 63
borlanic 0:380207fcb5c1 64 bd_size_t erase = _bds[i]->get_erase_size();
borlanic 0:380207fcb5c1 65 if (i == 0 || (erase >= _erase_size && is_aligned(erase, _erase_size))) {
borlanic 0:380207fcb5c1 66 _erase_size = erase;
borlanic 0:380207fcb5c1 67 } else {
borlanic 0:380207fcb5c1 68 MBED_ASSERT(_erase_size > erase && is_aligned(_erase_size, erase));
borlanic 0:380207fcb5c1 69 }
borlanic 0:380207fcb5c1 70
borlanic 0:380207fcb5c1 71 int value = _bds[i]->get_erase_value();
borlanic 0:380207fcb5c1 72 if (i == 0 || value == _erase_value) {
borlanic 0:380207fcb5c1 73 _erase_value = value;
borlanic 0:380207fcb5c1 74 } else {
borlanic 0:380207fcb5c1 75 _erase_value = -1;
borlanic 0:380207fcb5c1 76 }
borlanic 0:380207fcb5c1 77
borlanic 0:380207fcb5c1 78 _size += _bds[i]->size();
borlanic 0:380207fcb5c1 79 }
borlanic 0:380207fcb5c1 80
borlanic 0:380207fcb5c1 81 return 0;
borlanic 0:380207fcb5c1 82 }
borlanic 0:380207fcb5c1 83
borlanic 0:380207fcb5c1 84 int ChainingBlockDevice::deinit()
borlanic 0:380207fcb5c1 85 {
borlanic 0:380207fcb5c1 86 for (size_t i = 0; i < _bd_count; i++) {
borlanic 0:380207fcb5c1 87 int err = _bds[i]->deinit();
borlanic 0:380207fcb5c1 88 if (err) {
borlanic 0:380207fcb5c1 89 return err;
borlanic 0:380207fcb5c1 90 }
borlanic 0:380207fcb5c1 91 }
borlanic 0:380207fcb5c1 92
borlanic 0:380207fcb5c1 93 return 0;
borlanic 0:380207fcb5c1 94 }
borlanic 0:380207fcb5c1 95
borlanic 0:380207fcb5c1 96 int ChainingBlockDevice::sync()
borlanic 0:380207fcb5c1 97 {
borlanic 0:380207fcb5c1 98 for (size_t i = 0; i < _bd_count; i++) {
borlanic 0:380207fcb5c1 99 int err = _bds[i]->sync();
borlanic 0:380207fcb5c1 100 if (err) {
borlanic 0:380207fcb5c1 101 return err;
borlanic 0:380207fcb5c1 102 }
borlanic 0:380207fcb5c1 103 }
borlanic 0:380207fcb5c1 104
borlanic 0:380207fcb5c1 105 return 0;
borlanic 0:380207fcb5c1 106 }
borlanic 0:380207fcb5c1 107
borlanic 0:380207fcb5c1 108 int ChainingBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
borlanic 0:380207fcb5c1 109 {
borlanic 0:380207fcb5c1 110 MBED_ASSERT(is_valid_read(addr, size));
borlanic 0:380207fcb5c1 111 uint8_t *buffer = static_cast<uint8_t*>(b);
borlanic 0:380207fcb5c1 112
borlanic 0:380207fcb5c1 113 // Find block devices containing blocks, may span multiple block devices
borlanic 0:380207fcb5c1 114 for (size_t i = 0; i < _bd_count && size > 0; i++) {
borlanic 0:380207fcb5c1 115 bd_size_t bdsize = _bds[i]->size();
borlanic 0:380207fcb5c1 116
borlanic 0:380207fcb5c1 117 if (addr < bdsize) {
borlanic 0:380207fcb5c1 118 bd_size_t read = size;
borlanic 0:380207fcb5c1 119 if (addr + read > bdsize) {
borlanic 0:380207fcb5c1 120 read = bdsize - addr;
borlanic 0:380207fcb5c1 121 }
borlanic 0:380207fcb5c1 122
borlanic 0:380207fcb5c1 123 int err = _bds[i]->read(buffer, addr, read);
borlanic 0:380207fcb5c1 124 if (err) {
borlanic 0:380207fcb5c1 125 return err;
borlanic 0:380207fcb5c1 126 }
borlanic 0:380207fcb5c1 127
borlanic 0:380207fcb5c1 128 buffer += read;
borlanic 0:380207fcb5c1 129 addr += read;
borlanic 0:380207fcb5c1 130 size -= read;
borlanic 0:380207fcb5c1 131 }
borlanic 0:380207fcb5c1 132
borlanic 0:380207fcb5c1 133 addr -= bdsize;
borlanic 0:380207fcb5c1 134 }
borlanic 0:380207fcb5c1 135
borlanic 0:380207fcb5c1 136 return 0;
borlanic 0:380207fcb5c1 137 }
borlanic 0:380207fcb5c1 138
borlanic 0:380207fcb5c1 139 int ChainingBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
borlanic 0:380207fcb5c1 140 {
borlanic 0:380207fcb5c1 141 MBED_ASSERT(is_valid_program(addr, size));
borlanic 0:380207fcb5c1 142 const uint8_t *buffer = static_cast<const uint8_t*>(b);
borlanic 0:380207fcb5c1 143
borlanic 0:380207fcb5c1 144 // Find block devices containing blocks, may span multiple block devices
borlanic 0:380207fcb5c1 145 for (size_t i = 0; i < _bd_count && size > 0; i++) {
borlanic 0:380207fcb5c1 146 bd_size_t bdsize = _bds[i]->size();
borlanic 0:380207fcb5c1 147
borlanic 0:380207fcb5c1 148 if (addr < bdsize) {
borlanic 0:380207fcb5c1 149 bd_size_t program = size;
borlanic 0:380207fcb5c1 150 if (addr + program > bdsize) {
borlanic 0:380207fcb5c1 151 program = bdsize - addr;
borlanic 0:380207fcb5c1 152 }
borlanic 0:380207fcb5c1 153
borlanic 0:380207fcb5c1 154 int err = _bds[i]->program(buffer, addr, program);
borlanic 0:380207fcb5c1 155 if (err) {
borlanic 0:380207fcb5c1 156 return err;
borlanic 0:380207fcb5c1 157 }
borlanic 0:380207fcb5c1 158
borlanic 0:380207fcb5c1 159 buffer += program;
borlanic 0:380207fcb5c1 160 addr += program;
borlanic 0:380207fcb5c1 161 size -= program;
borlanic 0:380207fcb5c1 162 }
borlanic 0:380207fcb5c1 163
borlanic 0:380207fcb5c1 164 addr -= bdsize;
borlanic 0:380207fcb5c1 165 }
borlanic 0:380207fcb5c1 166
borlanic 0:380207fcb5c1 167 return 0;
borlanic 0:380207fcb5c1 168 }
borlanic 0:380207fcb5c1 169
borlanic 0:380207fcb5c1 170 int ChainingBlockDevice::erase(bd_addr_t addr, bd_size_t size)
borlanic 0:380207fcb5c1 171 {
borlanic 0:380207fcb5c1 172 MBED_ASSERT(is_valid_erase(addr, size));
borlanic 0:380207fcb5c1 173
borlanic 0:380207fcb5c1 174 // Find block devices containing blocks, may span multiple block devices
borlanic 0:380207fcb5c1 175 for (size_t i = 0; i < _bd_count && size > 0; i++) {
borlanic 0:380207fcb5c1 176 bd_size_t bdsize = _bds[i]->size();
borlanic 0:380207fcb5c1 177
borlanic 0:380207fcb5c1 178 if (addr < bdsize) {
borlanic 0:380207fcb5c1 179 bd_size_t erase = size;
borlanic 0:380207fcb5c1 180 if (addr + erase > bdsize) {
borlanic 0:380207fcb5c1 181 erase = bdsize - addr;
borlanic 0:380207fcb5c1 182 }
borlanic 0:380207fcb5c1 183
borlanic 0:380207fcb5c1 184 int err = _bds[i]->erase(addr, erase);
borlanic 0:380207fcb5c1 185 if (err) {
borlanic 0:380207fcb5c1 186 return err;
borlanic 0:380207fcb5c1 187 }
borlanic 0:380207fcb5c1 188
borlanic 0:380207fcb5c1 189 addr += erase;
borlanic 0:380207fcb5c1 190 size -= erase;
borlanic 0:380207fcb5c1 191 }
borlanic 0:380207fcb5c1 192
borlanic 0:380207fcb5c1 193 addr -= bdsize;
borlanic 0:380207fcb5c1 194 }
borlanic 0:380207fcb5c1 195
borlanic 0:380207fcb5c1 196 return 0;
borlanic 0:380207fcb5c1 197 }
borlanic 0:380207fcb5c1 198
borlanic 0:380207fcb5c1 199 bd_size_t ChainingBlockDevice::get_read_size() const
borlanic 0:380207fcb5c1 200 {
borlanic 0:380207fcb5c1 201 return _read_size;
borlanic 0:380207fcb5c1 202 }
borlanic 0:380207fcb5c1 203
borlanic 0:380207fcb5c1 204 bd_size_t ChainingBlockDevice::get_program_size() const
borlanic 0:380207fcb5c1 205 {
borlanic 0:380207fcb5c1 206 return _program_size;
borlanic 0:380207fcb5c1 207 }
borlanic 0:380207fcb5c1 208
borlanic 0:380207fcb5c1 209 bd_size_t ChainingBlockDevice::get_erase_size() const
borlanic 0:380207fcb5c1 210 {
borlanic 0:380207fcb5c1 211 return _erase_size;
borlanic 0:380207fcb5c1 212 }
borlanic 0:380207fcb5c1 213
borlanic 0:380207fcb5c1 214 int ChainingBlockDevice::get_erase_value() const
borlanic 0:380207fcb5c1 215 {
borlanic 0:380207fcb5c1 216 return _erase_value;
borlanic 0:380207fcb5c1 217 }
borlanic 0:380207fcb5c1 218
borlanic 0:380207fcb5c1 219 bd_size_t ChainingBlockDevice::size() const
borlanic 0:380207fcb5c1 220 {
borlanic 0:380207fcb5c1 221 return _size;
borlanic 0:380207fcb5c1 222 }