Skip to content

Commit 04fe292

Browse files
uicr: Add flash size to UICR data.
1 parent c2818af commit 04fe292

File tree

3 files changed

+43
-15
lines changed

3 files changed

+43
-15
lines changed

docs/quick-guide.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ if (microbitFs.isAppendedScriptPresent(finalHexStr)) {
6262
```js
6363
var uicrData = getIntelHexUicrData(IntelHexStr);
6464
console.log('Flash Page Size:' + uicrData.flashPageSize);
65+
console.log('Flash Size:' + uicrData.flashSize);
6566
console.log('Runtime Start Page:' + uicrData.runtimeStartPage);
6667
console.log('Runtime Start Address:' + uicrData.runtimeStartAddress);
6768
console.log('Runtime End Used:' + uicrData.runtimeEndUsed);

src/__tests__/uicr.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ import * as fs from 'fs';
77
import { getIntelHexUicrData } from '../uicr';
88

99
describe('Read MicroPython UICR data.', () => {
10+
const uPyHexFile = fs.readFileSync('./src/__tests__/upy-v1.0.1.hex', 'utf8');
11+
1012
it('Read MicroPython v1.0.1 hex file UICR', () => {
11-
const uPyHexFile = fs.readFileSync(
12-
'./src/__tests__/upy-v1.0.1.hex',
13-
'utf8'
14-
);
1513
const expectedPageSize = 1024;
14+
const expectedFlashSize = 256 * 1024;
1615
const expectedRuntimeStartPage = 0;
1716
const MicroPythonLastByteUsed = 0x388b8;
1817
const expectedRuntimeEndPage = Math.ceil(
@@ -28,6 +27,7 @@ describe('Read MicroPython UICR data.', () => {
2827
const result = getIntelHexUicrData(uPyHexFile);
2928

3029
expect(result.flashPageSize).toEqual(expectedPageSize);
30+
expect(result.flashSize).toEqual(expectedFlashSize);
3131
expect(result.runtimeStartPage).toEqual(expectedRuntimeStartPage);
3232
expect(result.runtimeStartAddress).toEqual(
3333
expectedRuntimeStartPage * expectedPageSize
@@ -48,9 +48,11 @@ describe('Read MicroPython UICR data.', () => {
4848
':0410140000C0030015\n' +
4949
':040000050003C0C173\n' +
5050
':00000001FF\n';
51+
5152
const failCase = () => {
5253
const result = getIntelHexUicrData(makeCodeUicr);
5354
};
55+
5456
expect(failCase).toThrow(Error);
5557
});
5658

src/uicr.ts

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const UICR_CUSTOMER_UPY_OFFSET: number = 0x40;
1717
const UICR_UPY_START: number =
1818
UICR_START + UICR_CUSTOMER_OFFSET + UICR_CUSTOMER_UPY_OFFSET;
1919

20-
const UPY_MAGIC_HEADER: number = 0x17eeb07c;
20+
const UPY_MAGIC_HEADER: number[] = [0x17eeb07c];
2121
const UPY_DELIMITER: number = 0xffffffff;
2222
const UPY_REGIONS_TERMINATOR: number = 0x00000000;
2323

@@ -46,6 +46,7 @@ enum MicropythonUicrAddress {
4646
/** MicroPython data stored in the UICR Customer area. */
4747
interface MicropythonUicrData {
4848
flashPageSize: number;
49+
flashSize: number;
4950
runtimeStartPage: number;
5051
runtimeStartAddress: number;
5152
runtimeEndUsed: number;
@@ -101,13 +102,13 @@ function getStringFromIntelHexMap(
101102
address: number
102103
): string {
103104
const memBlock = intelHexMap.slice(address).get(address);
104-
let i = 0;
105-
for (i = 0; i < memBlock.length && memBlock[i] !== 0; i++);
106-
if (i === memBlock.length) {
105+
let iStrEnd = 0;
106+
while (iStrEnd < memBlock.length && memBlock[iStrEnd] !== 0) iStrEnd++;
107+
if (iStrEnd === memBlock.length) {
107108
// Could not find a null character to indicate the end of the string
108109
return '';
109110
}
110-
const stringBytes = memBlock.slice(0, i);
111+
const stringBytes = memBlock.slice(0, iStrEnd);
111112
return bytesToStr(stringBytes);
112113
}
113114

@@ -119,11 +120,33 @@ function getStringFromIntelHexMap(
119120
* @return True if the magic number matches, false otherwise.
120121
*/
121122
function confirmMagicValue(intelHexMap: MemoryMap): boolean {
122-
const readMagicHeader: number = getUint32FromIntelHexMap(
123+
const readMagicHeader = getMagicValue(intelHexMap);
124+
return UPY_MAGIC_HEADER.includes(readMagicHeader);
125+
}
126+
127+
/**
128+
* Reads the UICR data that contains the Magic Value that indicates the
129+
* MicroPython presence in the hex data.
130+
*
131+
* @param intelHexMap - Memory map of the Intel Hex data.
132+
* @returns The Magic Value from UICR.
133+
*/
134+
function getMagicValue(intelHexMap: MemoryMap): number {
135+
return getUint32FromIntelHexMap(
123136
intelHexMap,
124137
MicropythonUicrAddress.MagicValue
125138
);
126-
return readMagicHeader === UPY_MAGIC_HEADER;
139+
}
140+
141+
/**
142+
* Reads the UICR data from an Intel Hex map and retrieves the flash size.
143+
*
144+
* @param intelHexMap - Memory map of the Intel Hex data.
145+
* @returns The micro:bit flash size.
146+
*/
147+
function getFlashSize(intelHexMap: MemoryMap): number {
148+
// This is the micro:bit flash size
149+
return 0x40000;
127150
}
128151

129152
/**
@@ -196,18 +219,20 @@ function getHexMapUicrData(intelHexMap: MemoryMap): MicropythonUicrData {
196219
if (!confirmMagicValue(uicrMap)) {
197220
throw new Error('Could not find valid MicroPython UICR data.');
198221
}
199-
const pageSize: number = getPageSize(uicrMap);
222+
const flashPageSize: number = getPageSize(uicrMap);
223+
const flashSize: number = getFlashSize(uicrMap);
200224
const startPage: number = getStartPage(uicrMap);
201225
const pagesUsed: number = getPagesUsed(uicrMap);
202226
const versionAddress: number = getVersionLocation(uicrMap);
203227
const version: string = getStringFromIntelHexMap(intelHexMap, versionAddress);
204228

205229
return {
206-
flashPageSize: pageSize,
230+
flashPageSize,
231+
flashSize,
207232
runtimeStartPage: startPage,
208-
runtimeStartAddress: startPage * pageSize,
233+
runtimeStartAddress: startPage * flashPageSize,
209234
runtimeEndUsed: pagesUsed,
210-
runtimeEndAddress: pagesUsed * pageSize,
235+
runtimeEndAddress: pagesUsed * flashPageSize,
211236
uicrStartAddress: MicropythonUicrAddress.MagicValue,
212237
uicrEndAddress: MicropythonUicrAddress.End,
213238
versionAddress,

0 commit comments

Comments
 (0)