Skip to content

setting size and flash top config #10414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Mar 31, 2025
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
435accc
update check
tballmsft Feb 26, 2025
4e71bbc
make sure to backstop flashusableend
tballmsft Feb 27, 2025
c97fb56
off by one
tballmsft Mar 4, 2025
d6e1cb8
plumb cres through
tballmsft Mar 5, 2025
623acee
Merge branch 'tball/checkSize' of https://github.com/microsoft/pxt in…
tballmsft Mar 5, 2025
c65de8b
take settings size into account
tballmsft Mar 7, 2025
0b3974e
missed a call
tballmsft Mar 7, 2025
89468f0
remove CFG_
tballmsft Mar 7, 2025
8d4a903
read bottom of flash
tballmsft Mar 10, 2025
9f97e03
finish plumbing
tballmsft Mar 10, 2025
e923b1c
more plumbing
tballmsft Mar 10, 2025
47f03ad
still debugging
tballmsft Mar 11, 2025
9c7fccb
more debugging
tballmsft Mar 11, 2025
bbffca0
fix parsing logic
tballmsft Mar 11, 2025
ad7d11b
fix error
tballmsft Mar 12, 2025
8c60332
remove some logging
tballmsft Mar 12, 2025
2ec23a1
whitespace
tballmsft Mar 12, 2025
e8b7f14
remore incorrect increment
tballmsft Mar 12, 2025
d6fa059
renaming
tballmsft Mar 12, 2025
9b99594
Merge branch 'master' of https://github.com/microsoft/pxt into tball/…
tballmsft Mar 12, 2025
262a821
Merge branch 'master' of https://github.com/microsoft/pxt into tball/…
tballmsft Mar 17, 2025
e1dc8fd
Merge branch 'tball/settingSizeConfig' of https://github.com/microsof…
tballmsft Mar 17, 2025
7f8c0ec
Merge branch 'master' of https://github.com/microsoft/pxt into tball/…
tballmsft Mar 27, 2025
1aa5071
more work on flash usable end
tballmsft Mar 27, 2025
66c378d
fix null dereference
tballmsft Mar 27, 2025
174df84
remove debugging
tballmsft Mar 27, 2025
4fa8d74
remove trailing spaces
tballmsft Mar 27, 2025
4ae6851
remove TODO
tballmsft Mar 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pxtcompiler/emitter/backvm.ts
Original file line number Diff line number Diff line change
@@ -340,7 +340,7 @@ _start_${name}:
vmsource += "\n; The end.\n"
bin.writeFile(BINARY_ASM, vmsource)

let res = assemble(opts.target, bin, vmsource)
let res = assemble(opts.target, bin, vmsource, cres)

const srcmap = res.thumbFile.getSourceMap()
const encodedSrcMap = encodeSourceMap(srcmap)
2 changes: 1 addition & 1 deletion pxtcompiler/emitter/emitter.ts
Original file line number Diff line number Diff line change
@@ -992,7 +992,7 @@ namespace ts.pxtc {
}
}

hexfile.setupFor(optstarget, extinfo || emptyExtInfo());
hexfile.setupFor(optstarget, extinfo || emptyExtInfo(), res);
hexfile.setupInlineAssembly(opts);
}

75 changes: 61 additions & 14 deletions pxtcompiler/emitter/hexfile.ts
Original file line number Diff line number Diff line change
@@ -51,6 +51,8 @@ namespace ts.pxtc {
jmpStartAddr: number;
jmpStartIdx: number;

topFlashAddr: number;

elfInfo: pxt.elf.Info;
espInfo: pxt.esp.Image;
}
@@ -69,6 +71,7 @@ namespace ts.pxtc {
codeStartAddr: undefined,
elfInfo: undefined,
espInfo: undefined,
topFlashAddr: 0
}
}

@@ -82,6 +85,10 @@ namespace ts.pxtc {
return ctx.codeStartAddrPadded
}

export function getTopFlashAddress() {
return ctx.topFlashAddr
}

// utility function
function swapBytes(str: string) {
let r = ""
@@ -163,7 +170,7 @@ namespace ts.pxtc {
// see PXT_EXPORTData
const pointerListMarker = "0108010842424242010801083ed8e98d"

export function setupFor(opts: CompileTarget, extInfo: ExtensionInfo) {
export function setupFor(opts: CompileTarget, extInfo: ExtensionInfo, cres: CompileResult) {
ctx = cachedCtxs.find(c => c.sha == extInfo.sha)

if (ctx)
@@ -219,6 +226,8 @@ namespace ts.pxtc {
if (hasMarker(drom.data, off)) {
found = true
off += marker.length
ctx.topFlashAddr = pxt.HF2.read32(drom.data, off)
off += 4
const ptroff = off
for (let ptr of extInfo.vmPointers || []) {
if (ptr == "0") continue
@@ -270,7 +279,10 @@ namespace ts.pxtc {
ctx.jmpStartAddr = jmpIdx / 2
ctx.jmpStartIdx = -1

let ptrs = hexlines[0].slice(jmpIdx + 32, jmpIdx + 32 + funs.length * 8 + 16)
const hexb = hexlines[0].slice(jmpIdx + 32, jmpIdx + 40)
ctx.topFlashAddr = parseInt(swapBytes(hexb), 16)

let ptrs = hexlines[0].slice(jmpIdx + 40, jmpIdx + 40 + funs.length * 8 + 16)
readPointers(ptrs)
checkFuns()
return
@@ -328,11 +340,26 @@ namespace ts.pxtc {
}
m = /^:..(....)00/.exec(hexlines[i])
if (m) {
if (ctx.jmpStartIdx >= 0 && ctx.jmpStartIdx + 1 == i) {
let n = /^:..(....)00(.{4,})/.exec(hexlines[i]);
if (n) {
let step = opts.shortPointers ? 4 : 8
let hexb = swapBytes(n[2].slice(0, step))
ctx.topFlashAddr = parseInt(hexb, 16)
}
}
let newAddr = parseInt(upperAddr + m[1], 16)
if (!opts.flashUsableEnd && lastAddr && newAddr - lastAddr > 64 * 1024)
hitEnd()
if (opts.flashUsableEnd && newAddr >= opts.flashUsableEnd)

if (!opts.flashUsableEnd && lastAddr && newAddr - lastAddr > 64 * 1024) {
// the above check is sort of odd - not clear why this case is here
hitEnd()
}
if (opts.flashUsableEnd) {
let realUsableEnd = getFlashUsableEnd(target,cres)
if (newAddr >= realUsableEnd) {
hitEnd()
}
}
lastIdx = i
lastAddr = newAddr
}
@@ -342,6 +369,7 @@ namespace ts.pxtc {

// random magic number, which marks the beginning of the array of function pointers in the .hex file
// it is defined in pxt-microbit-core
// TODO: would be nice to use pointerListMarker
m = /^:10....000108010842424242010801083ED8E98D/.exec(hexlines[i])
if (m) {
ctx.jmpStartAddr = lastAddr
@@ -363,14 +391,20 @@ namespace ts.pxtc {
let m = /^:..(....)00(.{4,})/.exec(hexlines[i]);
if (!m) continue;

readPointers(m[2])
if (i === ctx.jmpStartIdx + 1) {
// skip over the flash top address
let step = opts.shortPointers ? 4 : 8
readPointers(m[2].slice(step))
} else {
readPointers(m[2])
}

if (funs.length == 0) break
}

checkFuns();
return


function readPointers(s: string) {
let step = opts.shortPointers ? 4 : 8
while (s.length >= step) {
@@ -1014,16 +1048,29 @@ ${hexfile.hexPrelude()}
}
}

// compute the real top of flash
export function getFlashUsableEnd(target: CompileTarget, cres: CompileResult) {
// check if settings size is set
let actualSettingsSize = 0
if (cres.configData) {
let settingsSizeDefault = cres.configData.find(ce => ce.name === "SETTINGS_SIZE_DEFL")
let settingsSize = cres.configData.find(ce => ce.name === "SETTINGS_SIZE")
actualSettingsSize = settingsSize ? settingsSize.value : settingsSizeDefault ? settingsSizeDefault.value : 0
}

const topFlashAddr = hexfile.getTopFlashAddress()
return (topFlashAddr > 0 ? topFlashAddr : target.flashUsableEnd ? target.flashUsableEnd : target.flashEnd) - actualSettingsSize
}

let peepDbg = false
export function assemble(target: CompileTarget, bin: Binary, src: string) {
export function assemble(target: CompileTarget, bin: Binary, src: string, cres: CompileResult) {
let b = mkProcessorFile(target)
b.emit(src);

let flashUsableEnd = target.flashUsableEnd ? target.flashUsableEnd : target.flashEnd

src = `; Interface tables: ${bin.itFullEntries}/${bin.itEntries} (${Math.round(100 * bin.itFullEntries / bin.itEntries)}%)\n` +
`; Virtual methods: ${bin.numVirtMethods} / ${bin.numMethods}\n` +
b.getSource(!peepDbg, bin.numStmts, flashUsableEnd);
b.getSource(!peepDbg, bin.numStmts, getFlashUsableEnd(target, cres));

throwAssemblerErrors(b)

@@ -1129,7 +1176,7 @@ __flash_checksums:
}
const prefix = opts.extinfo.outputPrefix || ""
bin.writeFile(prefix + pxtc.BINARY_ASM, src)
const res = assemble(opts.target, bin, src)
const res = assemble(opts.target, bin, src, cres)
if (res.thumbFile.commPtr)
bin.commSize = res.thumbFile.commPtr - hexfile.getCommBase()
if (res.src)
@@ -1236,7 +1283,7 @@ __flash_checksums:
const opts0 = U.flatClone(opts)
// normally, this would already have been done, but if the main variant
// is disabled, another variant may be set up
hexfile.setupFor(opts.target, opts.extinfo || emptyExtInfo())
hexfile.setupFor(opts.target, opts.extinfo || emptyExtInfo(), cres)
assembleAndPatch(src, bin, opts, cres)
if (!cres.builtVariants) {
cres.builtVariants = [];
@@ -1251,12 +1298,12 @@ __flash_checksums:
localOpts.extinfo = other.extinfo
other.target.isNative = true
localOpts.target = other.target
hexfile.setupFor(localOpts.target, localOpts.extinfo)
hexfile.setupFor(localOpts.target, localOpts.extinfo, cres)
assembleAndPatch(src, bin, localOpts, cres)
cres.builtVariants.push(other.extinfo?.appVariant);
}
} finally {
hexfile.setupFor(opts0.target, opts0.extinfo)
hexfile.setupFor(opts0.target, opts0.extinfo, cres)
}
}

12 changes: 6 additions & 6 deletions pxtlib/emitter/assembler.ts
Original file line number Diff line number Diff line change
@@ -1067,7 +1067,7 @@ namespace ts.pxtc.assembler {
return r
}

public getSource(clean: boolean, numStmts = 1, flashUsableEnd = 0) {
public getSource(clean: boolean, numStmts = 1, usableEnd = 0) {
let lenPrev = 0
let size = (lbl: string) => {
let curr = this.labels[lbl] || lenPrev
@@ -1083,16 +1083,16 @@ namespace ts.pxtc.assembler {
let lenAllCode = lenPrev
let totalEnd = (lenTotal + this.baseOffset) & 0xffffff

if (flashUsableEnd && totalEnd > flashUsableEnd) {
const e = new Error(lf("program too big by {0} bytes!", totalEnd - flashUsableEnd));
if (usableEnd && totalEnd > usableEnd) {
const e = new Error(lf("program too big by {0} bytes!", totalEnd - usableEnd));
(e as any).ksErrorCode = 9283;
throw e;
}

flashUsableEnd = flashUsableEnd || 128 * 1024
usableEnd = usableEnd || 128 * 1024
let totalInfo = lf("; total bytes: {0} ({1}% of {2}k flash with {3} free)",
totalEnd, (100 * totalEnd / flashUsableEnd).toFixed(1), (flashUsableEnd / 1024).toFixed(1),
flashUsableEnd - totalEnd)
totalEnd, (100 * totalEnd / usableEnd).toFixed(1), (usableEnd / 1024).toFixed(1),
usableEnd - totalEnd)
let res =
// ARM-specific
lf("; generated code sizes (bytes): {0} (incl. {1} user, {2} helpers, {3} vtables, {4} lits); src size {5}\n",