[Update] Upstream

This commit is contained in:
Quentin
2020-04-08 12:48:09 +02:00
18 changed files with 157 additions and 137 deletions

View File

@@ -20,8 +20,8 @@ Zeros = "Nullstellen"
Tangent = "Tangente"
Intersection = "Schnittmenge"
Preimage = "Urbild"
SelectLowerBound = "Untere Integrationsgrenze"
SelectUpperBound = "Obere Integrationsgrenze"
SelectLowerBound = "Untere Integrationsgrenze "
SelectUpperBound = "Obere Integrationsgrenze "
NoMaximumFound = "Kein Maximalwert gefunden"
NoMinimumFound = "Kein Mindestwert gefunden"
NoZeroFound = "Keine Nullstelle gefunden"
@@ -29,5 +29,5 @@ NoIntersectionFound = "Kein Schnittpunkt gefunden"
NoPreimageFound = "Kein Urbild gefunden"
DerivativeFunctionColumn = "Spalte der Ableitungsfunktion"
HideDerivativeColumn = "Ableitungsfunktion ausblenden"
AllowedCharactersAZaz09 = "Erlaubte Zeichen: A-Z, a-z, 0-9, _"
AllowedCharactersAZaz09 = "Erlaubte Zeichen: A..Z, a..z, 0..9, _"
ReservedName = "Reserviertes Wort"

View File

@@ -20,8 +20,8 @@ Zeros = "Zeros"
Tangent = "Tangent"
Intersection = "Intersection"
Preimage = "Inverse image"
SelectLowerBound = "Select lower bound"
SelectUpperBound = "Select upper bound"
SelectLowerBound = "Select lower bound "
SelectUpperBound = "Select upper bound "
NoMaximumFound = "No maximum found"
NoMinimumFound = "No minimum found"
NoZeroFound = "No zero found"
@@ -29,5 +29,5 @@ NoIntersectionFound = "No intersection found"
NoPreimageFound = "No inverse image found"
DerivativeFunctionColumn = "Derivative function column"
HideDerivativeColumn = "Hide the derivative function"
AllowedCharactersAZaz09 = "Allowed characters: A-Z, a-z, 0-9, _"
AllowedCharactersAZaz09 = "Allowed characters: A.Z, a..z, 0..9, _"
ReservedName = "Reserved name"

View File

@@ -20,8 +20,8 @@ Zeros = "Raíces"
Tangent = "Tangente"
Intersection = "Intersección"
Preimage = "Imagen inversa"
SelectLowerBound = "Seleccionar el límite inferior"
SelectUpperBound = "Seleccionar el límite superior"
SelectLowerBound = "Seleccionar el límite inferior "
SelectUpperBound = "Seleccionar el límite superior "
NoMaximumFound = "Níngun máximo encontrado"
NoMinimumFound = "Níngun mínimo encontrado"
NoZeroFound = "Ninguna raíz encontrada"
@@ -29,5 +29,5 @@ NoIntersectionFound = "Ninguna intersección encontrada"
NoPreimageFound = "Ninguna imagen inversa encontrada"
DerivativeFunctionColumn = "Columna de la derivada"
HideDerivativeColumn = "Ocultar la derivada"
AllowedCharactersAZaz09 = "Caracteres permitidos : A-Z, a-z, 0-9, _"
AllowedCharactersAZaz09 = "Caracteres permitidos : A..Z, a..z, 0..9, _"
ReservedName = "Nombre reservado"

View File

@@ -4,7 +4,7 @@ FunctionTab = "Fonctions"
AddFunction = "Ajouter une fonction"
DeleteFunction = "Supprimer la fonction"
CurveType = "Type de courbe"
CartesianType = "Cartésien "
CartesianType = "Cartésienne "
PolarType = "Polaire "
ParametricType = "Paramétrique "
IntervalT = "Intervalle t"
@@ -16,18 +16,18 @@ NoFunction = "Aucune fonction"
NoActivatedFunction = "Aucune fonction activée"
PlotOptions = "Options de la courbe"
Compute = "Calculer"
Zeros = "Zéros"
Zeros = "Racines"
Tangent = "Tangente"
Intersection = "Intersection"
Preimage = "Antécédent"
SelectLowerBound = "Sélectionner la borne inférieure"
SelectUpperBound = "Sélectionner la borne supérieure"
SelectLowerBound = "Sélectionner la borne inférieure "
SelectUpperBound = "Sélectionner la borne supérieure "
NoMaximumFound = "Aucun maximum trouvé"
NoMinimumFound = "Aucun minimum trouvé"
NoZeroFound = "Aucun zéro trouvé"
NoZeroFound = "Aucune racine trouvée"
NoIntersectionFound = "Aucune intersection trouvée"
NoPreimageFound = "Aucun antécédent trouvé"
DerivativeFunctionColumn = "Colonne de la fonction dérivée"
HideDerivativeColumn = "Masquer la fonction dérivée"
AllowedCharactersAZaz09 = "Caractères autorisés : A-Z, a-z, 0-9, _"
AllowedCharactersAZaz09 = "Caractères autorisés : A..Z, a..z, 0..9, _"
ReservedName = "Nom réservé"

View File

@@ -20,8 +20,8 @@ Zeros = "Raízes"
Tangent = "Tangente"
Intersection = "Intersecção"
Preimage = "Imagem inversa"
SelectLowerBound = "Selecionar limite superior"
SelectUpperBound = "Selecionar limite inferior"
SelectLowerBound = "Selecionar limite superior "
SelectUpperBound = "Selecionar limite inferior "
NoMaximumFound = "Nenhum máximo encontrado"
NoMinimumFound = "Nenhum mínimo encontrado"
NoZeroFound = "Nenhuma raiz encontrada"
@@ -29,5 +29,5 @@ NoIntersectionFound = "Nenhuma intersecção encontrada"
NoPreimageFound = "Nenhuma imagem inversa encontrada"
DerivativeFunctionColumn = "Coluna da função derivada"
HideDerivativeColumn = "Esconder função derivada"
AllowedCharactersAZaz09 = "Caracteres permitidos : A-Z, a-z, 0-9, _"
AllowedCharactersAZaz09 = "Caracteres permitidos : A..Z, a..z, 0..9, _"
ReservedName = "Nome reservado"

View File

@@ -10,13 +10,13 @@ UniformDistribution = "Loi uniforme"
ExponentialDistribution = "Loi exponentielle"
GeometricDistribution = "Loi géométrique"
PoissonDistribution = "Loi de Poisson"
ChiSquaredDistribution = "Loi du chi2"
ChiSquaredDistribution = "Loi du Khi-2"
StudentDistribution = "Loi de Student"
FisherDistribution = "Loi de Fisher"
ChooseParameters = "Choisir les paramètres"
RepetitionNumber = "n : Nombre de répétitions"
SuccessProbability = "p : Probabilité de succès"
IntervalDefinition = "[a,b] : Intervalle"
IntervalDefinition = "[a;b] : Intervalle"
LambdaExponentialDefinition = "λ : Paramètre"
MeanDefinition = "μ : Espérance ou moyenne"
DeviationDefinition = "σ : Écart type"

View File

@@ -6,9 +6,9 @@ EditionMode = "Eingabe"
EditionLinear = "Linear "
Edition2D = "Natürlich "
ComplexFormat = "Komplex"
ExamMode = "Testmodus"
ExamModeActive = "Testmodus neustarten"
ToDeactivateExamMode1 = "Um den Testmodus auszuschalten,"
ExamMode = "Prüfungsmodus"
ExamModeActive = "Wieder starten Modus"
ToDeactivateExamMode1 = "Um den Prüfungsmodus auszuschalten,"
ToDeactivateExamMode2 = "schließen Sie den Rechner an einen"
ToDeactivateExamMode3 = "Computer oder eine Steckdose an."
# --------------------- Please do not edit these messages ---------------------
@@ -22,13 +22,13 @@ AboutWarning4 = "for any resulting damage."
# -----------------------------------------------------------------------------
About = "Über"
Degrees = "Grad "
Gradians = "Gone "
Gradians = "Gon "
Radian = "Bogenmaß "
Decimal = "Dezimal "
Engineering = "Technisch "
Scientific = "Wissenschaftlich "
SignificantFigures = "Signifikante Stellen "
Real = "Reel "
Real = "Reell "
Cartesian = "Algebraische "
Polar = "Polar "
Brightness = "Helligkeit"

View File

@@ -1,9 +1,9 @@
ActivateDeactivate = "Aktivieren/Deaktivieren"
ActivateDutchExamMode = "Activate Dutch exam mode"
ActivateExamMode = "Starten Testmodus"
ActivateExamMode = "Starten Prüfungsmodus"
ActiveExamModeMessage1 = "Alle Ihre Daten werden "
ActiveExamModeMessage2 = "gelöscht, wenn Sie den "
ActiveExamModeMessage3 = "Testmodus einschalten."
ActiveExamModeMessage3 = "Prüfungsmodus einschalten."
ActiveDutchExamModeMessage1 = "All your data will be deleted when"
ActiveDutchExamModeMessage2 = "you activate the exam mode. Python"
ActiveDutchExamModeMessage3 = "application will be unavailable."
@@ -20,8 +20,8 @@ Deviation = "Varianz"
DisplayValues = "Werte anzeigen"
Empty = "Leer"
Eng = "tech"
ExitExamMode1 = "Möchten Sie den Testmodus "
ExitExamMode2 = "verlassen?"
ExitExamMode1 = "Möchten Sie den"
ExitExamMode2 = "Prüfungsmodus verlassen?"
Exponential = "Exponentielle"
FillWithFormula = "Mit einer Formel füllen"
ForbiddenValue = "Verbotener Wert"

View File

@@ -2,10 +2,9 @@
namespace Shared {
static KDColor s_cursorWorkingBuffer[Dots::LargeDotDiameter*Dots::LargeDotDiameter];
void RoundCursorView::drawRect(KDContext * ctx, KDRect rect) const {
KDRect r = bounds();
KDColor cursorWorkingBuffer[Dots::LargeDotDiameter*Dots::LargeDotDiameter];
#ifdef GRAPH_CURSOR_SPEEDUP
/* Beware that only the pixels of the intersection of rect with KDContext's
* clipping rect are pulled. All other pixels are left unaltered. Indeed
@@ -15,7 +14,7 @@ void RoundCursorView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->getPixels(r, m_underneathPixelBuffer);
m_underneathPixelBufferLoaded = true;
#endif
ctx->blendRectWithMask(r, m_color, (const uint8_t *)Dots::LargeDotMask, s_cursorWorkingBuffer);
ctx->blendRectWithMask(r, m_color, (const uint8_t *)Dots::LargeDotMask, cursorWorkingBuffer);
}
KDSize RoundCursorView::minimalSizeForOptimalDisplay() const {
@@ -67,10 +66,11 @@ bool RoundCursorView::eraseCursorIfPossible() {
return false;
}
// Erase the cursor
KDColor cursorWorkingBuffer[Dots::LargeDotDiameter*Dots::LargeDotDiameter];
KDContext * ctx = KDIonContext::sharedContext();
ctx->setOrigin(currentFrame.origin());
ctx->setClippingRect(currentFrame);
ctx->fillRectWithPixels(KDRect(0,0,k_cursorSize, k_cursorSize), m_underneathPixelBuffer, s_cursorWorkingBuffer);
ctx->fillRectWithPixels(KDRect(0,0,k_cursorSize, k_cursorSize), m_underneathPixelBuffer, cursorWorkingBuffer);
// TODO Restore the context to previous values?
return true;
}

View File

@@ -2,6 +2,6 @@ USBConnected = "LA CALCULATRICE EST CONNECTÉE"
ConnectedMessage1 = "Pour transférer des données, connectez-"
ConnectedMessage2 = "vous depuis votre ordinateur sur le site"
ConnectedMessage3 = "workshop.numworks.com"
ConnectedMessage4 = "Appuyez sur la touche RETOUR de la"
ConnectedMessage5 = "calculatrice ou débranchez-la pour la"
ConnectedMessage6 = "déconnecter."
ConnectedMessage4 = "Appuyez sur la touche RETOUR"
ConnectedMessage5 = "de la calculatrice ou débranchez-la"
ConnectedMessage6 = "pour la déconnecter."

View File

@@ -4,86 +4,61 @@ import re
import subprocess
import sys
import matplotlib.pyplot as plt
import random
from matplotlib.ticker import FormatStrFormatter
def filter_set(data, pred):
result = {}
for k,v in data.items():
if (pred(v)):
result[k] = v
return result
readelf_line_regex = re.compile("[0-9]+:\s+([0-9a-f]+)\s+([0-9]+)\s+[A-Z]+")
def parse_line(line):
hex_start, dec_size = re.findall(readelf_line_regex, line)[0]
return (int(hex_start, 16), int(dec_size))
def pred_ram(symbol):
return (symbol[0] >= 0x20000000) and (symbol[0] <= 0x20040000)
readelf_output = subprocess.check_output([
"arm-none-eabi-readelf",
"-W", # Don't limit line lenght
"-s", # Sizes
sys.argv[1]
]).decode('utf-8')
def pred_size(symbol):
return (symbol[1] >= 64)
for line in readelf_output.splitlines():
words = line.split()
if not words:
continue
symbol = words[-1]
if symbol == "_ZN3Ion17staticStorageAreaE":
storage = parse_line(line)
if symbol == "_ZZN13AppsContainer19sharedAppsContainerEvE20appsContainerStorage":
container = parse_line(line)
if symbol == "_stack_start":
stack_start, _ = parse_line(line)
if symbol == "_stack_end":
stack_end, _ = parse_line(line)
if symbol == "_heap_start":
heap_start, _ = parse_line(line)
if symbol == "_heap_end":
heap_end, _ = parse_line(line)
def load_symbols(filename):
nm_output = subprocess.check_output([
"arm-none-eabi-nm",
"--print-size",
filename
]).decode('utf-8').splitlines()
nm_symbol_regex = re.compile("^([0-9A-Fa-f]+) ([0-9A-Fa-f]+) (.) (.+)$")
nm_sizeless_regex = re.compile("^([0-9a-z]+) (.) (.+)$")
symbol_results = [ re.match(nm_symbol_regex, line).groups() for line in nm_output if re.match(nm_symbol_regex, line) ]
sizeless_results = [ re.match(nm_sizeless_regex, line).groups() for line in nm_output if re.match(nm_sizeless_regex, line) ]
results = {}
for result in symbol_results:
results[result[3]] = ((int(result[0],16),int(result[1],16),result[2],result[3]))
for result in sizeless_results:
results[result[2]] = ((int(result[0],16),0,result[1],result[2]))
# Fixup stack and heap
for i in (("_stack_start", "_stack_end", "_stack"), ("_heap_start", "_heap_end", "_heap")):
if i[0] in results and i[1] in results:
start = results[i[0]]
end = results[i[1]]
results[i[2]] = (min(start[0], end[0]), abs(end[0]-start[0]), start[2], i[2])
del results[i[0]]
del results[i[1]]
return results
def demangle_symbols(symbols):
symbol_names = []
for name in symbols.keys():
symbol_names.append(name)
symbols_encoded = "\n".join(symbol_names).encode('utf-8')
demangled_output = subprocess.check_output(["c++filt"], input=symbols_encoded).decode('utf-8').splitlines()
demangled_symbols = {}
cpt=0
for symbol in symbols.values():
demangled_symbols[demangled_output[cpt]] = (symbol[0], symbol[1], symbol[2], demangled_output[cpt])
cpt += 1
return demangled_symbols
stack_size = stack_start - stack_end # Stack grows downwards
stack = (stack_end, stack_size)
heap_size = heap_end - heap_start
heap = (heap_start, heap_size)
def format_kb(i):
return ("%.3f KiB" % (i/1024))
return ("%d KB" % (i/1024))
def plot_symbols(symbols, range_start, range_end):
fig,ax = plt.subplots()
cpt = 0
for symbol in symbols.values():
symbol_name = symbol[3].lstrip("_")
symbol_color=(random.uniform(0,1),random.uniform(0,1),random.uniform(0,1))
ax.broken_barh([(symbol[0], symbol[1])], (0, 1), color=symbol_color, label=symbol_name + " - " + format_kb(symbol[1]))
cpt += 1
ax.set_yticks([])
ax.set_xticks(list(range(range_start, range_end+1, int((range_end-range_start)/16))))
xlabels = map(lambda t: '0x%08X' % int(t), ax.get_xticks())
ax.set_xticklabels(xlabels);
ax.legend()
fig.set_size_inches(20, 2)
return fig
fig,ax = plt.subplots()
data=load_symbols(sys.argv[1])
data=demangle_symbols(data)
data = filter_set(data, pred_ram)
data = filter_set(data, pred_size)
def plot(value, name, c):
ax.broken_barh([value], (0, 1), color=c, label=name + " - " + format_kb(value[1]))
fig=plot_symbols(data,0x20000000,0x20040000)
plot(container, "Container", "blue")
plot(storage, "Storage", "red")
plot(heap, "Heap", "pink")
plot(stack, "Stack", "green")
fig.show()
input()
ax.set_yticks([])
ax.set_xticks(list(range(0x20000000,0x20040001,0x10000)))
xlabels = map(lambda t: '0x%08X' % int(t), ax.get_xticks())
ax.set_xticklabels(xlabels);
ax.legend()
fig.set_size_inches(20, 2)
fig.savefig(sys.argv[2])

View File

@@ -51,7 +51,7 @@ define rule_for_arch_executable
.PRECIOUS: $$(BUILD_DIR)/$(1)/%.$$(EXE)
$$(BUILD_DIR)/$(1)/%.$$(EXE): force_remake
$(Q) echo "MAKE ARCH=$(1)"
$(Q) $$(MAKE) ARCH=$(1) --silent $$*.$$(EXE)
$(Q) $$(MAKE) ARCH=$(1) $$*.$$(EXE)
endef
$(foreach ARCH,$(ARCHS),$(eval $(call rule_for_arch_executable,$(ARCH))))

View File

@@ -5,6 +5,12 @@ HANDY_TARGETS_EXTENSIONS += dfu hex bin
%_ram_map: %.$(EXE)
$(PYTHON) build/device/ram_map.py $(BUILD_DIR)/$<
$(eval $(call rule_for, \
RAMSIZE, %_ram_map.png, %.elf, \
$$(PYTHON) build/device/ram_map.py $$< $$@, \
local \
))
.PHONY: %_size
%_size: $(BUILD_DIR)/%.$(EXE)

View File

@@ -508,15 +508,46 @@ bool LayoutField::privateHandleEvent(Ion::Events::Event event) {
return false;
}
static inline bool IsSimpleMoveEvent(Ion::Events::Event event) {
return event == Ion::Events::Left
|| event == Ion::Events::Right
|| event == Ion::Events::Up
|| event == Ion::Events::Down;
#define static_assert_immediately_follows(a, b) static_assert( \
static_cast<uint8_t>(a) + 1 == static_cast<uint8_t>(b), \
"Ordering error" \
)
#define static_assert_sequential(a, b, c, d) \
static_assert_immediately_follows(a, b); \
static_assert_immediately_follows(b, c); \
static_assert_immediately_follows(c, d);
static_assert_sequential(
LayoutCursor::Direction::Left,
LayoutCursor::Direction::Up,
LayoutCursor::Direction::Down,
LayoutCursor::Direction::Right
);
static_assert_sequential(
Ion::Events::Left,
Ion::Events::Up,
Ion::Events::Down,
Ion::Events::Right
);
static inline bool IsMoveEvent(Ion::Events::Event event) {
return
static_cast<uint8_t>(event) >= static_cast<uint8_t>(Ion::Events::Left) &&
static_cast<uint8_t>(event) <= static_cast<uint8_t>(Ion::Events::Right);
}
static inline LayoutCursor::Direction DirectionForMoveEvent(Ion::Events::Event event) {
assert(IsMoveEvent(event));
return static_cast<LayoutCursor::Direction>(
static_cast<uint8_t>(LayoutCursor::Direction::Left) +
static_cast<uint8_t>(event) - static_cast<uint8_t>(Ion::Events::Left)
);
}
bool LayoutField::privateHandleMoveEvent(Ion::Events::Event event, bool * shouldRecomputeLayout) {
if (!IsSimpleMoveEvent(event)) {
if (!IsMoveEvent(event)) {
return false;
}
if (resetSelection()) {
@@ -524,16 +555,7 @@ bool LayoutField::privateHandleMoveEvent(Ion::Events::Event event, bool * should
return true;
}
LayoutCursor result;
if (event == Ion::Events::Left) {
result = m_contentView.cursor()->cursorAtDirection(LayoutCursor::Direction::Left, shouldRecomputeLayout);
} else if (event == Ion::Events::Right) {
result = m_contentView.cursor()->cursorAtDirection(LayoutCursor::Direction::Right, shouldRecomputeLayout);
} else if (event == Ion::Events::Up) {
result = m_contentView.cursor()->cursorAtDirection(LayoutCursor::Direction::Up, shouldRecomputeLayout);
} else {
assert(event == Ion::Events::Down);
result = m_contentView.cursor()->cursorAtDirection(LayoutCursor::Direction::Down, shouldRecomputeLayout);
}
result = m_contentView.cursor()->cursorAtDirection(DirectionForMoveEvent(event), shouldRecomputeLayout);
if (result.isDefined()) {
m_contentView.setCursor(result);
return true;
@@ -541,20 +563,37 @@ bool LayoutField::privateHandleMoveEvent(Ion::Events::Event event, bool * should
return false;
}
bool eventIsSelection(Ion::Events::Event event) {
return event == Ion::Events::ShiftLeft || event == Ion::Events::ShiftRight || event == Ion::Events::ShiftUp || event == Ion::Events::ShiftDown;
static_assert_sequential(
Ion::Events::ShiftLeft,
Ion::Events::ShiftUp,
Ion::Events::ShiftDown,
Ion::Events::ShiftRight
);
static inline bool IsSelectionEvent(Ion::Events::Event event) {
return
static_cast<uint8_t>(event) >= static_cast<uint8_t>(Ion::Events::ShiftLeft) &&
static_cast<uint8_t>(event) <= static_cast<uint8_t>(Ion::Events::ShiftRight);
}
static inline LayoutCursor::Direction DirectionForSelectionEvent(Ion::Events::Event event) {
assert(IsSelectionEvent(event));
return static_cast<LayoutCursor::Direction>(
static_cast<uint8_t>(LayoutCursor::Direction::Left) +
static_cast<uint8_t>(event) - static_cast<uint8_t>(Ion::Events::ShiftLeft)
);
}
bool LayoutField::privateHandleSelectionEvent(Ion::Events::Event event, bool * shouldRecomputeLayout) {
if (!eventIsSelection(event)) {
if (!IsSelectionEvent(event)) {
return false;
}
Layout addedSelection;
LayoutCursor::Direction direction = event == Ion::Events::ShiftLeft ? LayoutCursor::Direction::Left :
(event == Ion::Events::ShiftRight ? LayoutCursor::Direction::Right :
(event == Ion::Events::ShiftUp ? LayoutCursor::Direction::Up :
LayoutCursor::Direction::Down));
LayoutCursor result = m_contentView.cursor()->selectAtDirection(direction, shouldRecomputeLayout, &addedSelection);
LayoutCursor result = m_contentView.cursor()->selectAtDirection(
DirectionForSelectionEvent(event),
shouldRecomputeLayout,
&addedSelection
);
if (addedSelection.isUninitialized()) {
return false;
}

View File

@@ -53,7 +53,7 @@ bool RunLoop::step() {
}
#if ESCHER_LOG_EVENTS_BINARY
Ion::Console::writeChar((char)event.id());
Ion::Console::writeChar(static_cast<uint8_t>(event));
#endif
#if ESCHER_LOG_EVENTS_NAME
const char * name = event.name();

View File

@@ -17,7 +17,7 @@ public:
constexpr Event() : m_id(4*PageSize){} // Return Ion::Event::None by default
constexpr Event(int i) : m_id(i){} // TODO: Assert here that i>=0 && i<255
uint8_t id() const { return m_id; }
constexpr explicit operator uint8_t() const { return m_id; }
#if DEBUG
const char * name() const;
#endif

View File

@@ -29,9 +29,9 @@ public:
enum class Direction {
Left,
Right,
Up,
Down
Down,
Right
};
enum class Position {

View File

@@ -82,7 +82,7 @@ Expression TrigonometryCheatTable::simplify(const Expression e, ExpressionNode::
* For instance, when simplfy a Cosine, we always compute the value for an angle
* in the top right trigonometric quadrant. */
const TrigonometryCheatTable * TrigonometryCheatTable::Table() {
const static Row sTableRows[] = {
static const Row sTableRows[] = {
Row(Row::Pair("-90", -90.0f),
Row::Pair("π*(-2)^(-1)", -1.5707963267948966f),
Row::Pair("-100", -100.0f),