Etat actuel: le prototype du simulateur est fonctionnel (qualite version alpha). J'ai reussi a compiler un firmware pour une N110.
Attention, les instructions qui suivent permettent de compiler un firmware qui lie entre eux epsilon et giac, dont les licenses sont incompatibles. Il n'est donc pas possible de diffuser legalement un tel firmware, on peut juste se compiler son propre firmware pour soi a des fins de prototypage.
Les commandes Giac/Xcas sont utilisables depuis l'app Calculs. Pour le moment, il faut taper les commandes Xcas en toutes lettres. On peut utiliser les templates de la calculatrice (fraction, integrale, somme, matrices). Pour stocker une valeur dans une variable, utiliser =, par exemple a=2 ou a=ranm(2,2).
Remarque: comme epsilon/poincare n'accepte pas les fonctions utilisateur ayant plus d'un argument, j'ai mis en place un workaround dans giac pour transformer de matrice 1 ligne vers liste des arguments (et aussi autorise les fonctions a plus d'un argument dans le parseur de poincare). Cela apparait dans l'historique des calculs avec des crochets qu'il faut juste ignorer. Le seul cas vraiment genant pour le lycee me semble etre la fonction limit qui meriterait un template.
=================
Compilation giac
=================
Recuperer https://www-fourier.ujf-grenoble.fr/~pa ... stable.tgz (version du 24 aout ou ulterieure)
Compilation de giac pour le simulateur:
- Code: Select all
export CXXFLAGS='-DNUMWORKS -g'
./configure --prefix=/usr
make
sudo make install
Compilation pour la calculatrice, d'apres
https://zardam.github.io/post/numworks-giac/
Installer libtommath: voir lien ci-dessus
Pour giac: dans le repertoire src:
- Code: Select all
cp config.h.numworks config.h
cp static_lexer_numworks.h static_lexer.h
cp static_lexer__numworks.h static_lexer_.h
make -f Makefile.numworks
==============
Compilation epsilon
==============
- Code: Select all
git clone -b newlib https://github.com/zardam/epsilon
# faire les modifs dans le source indiquees ci-dessous!
# faire make V=1 pour voir les details
# make PLATFORM=emscripten
# simulateur:
make PLATFORM=simulator clean
make PLATFORM=simulator DEBUG=1
./emu (a linker build/simulator/epsilon.elf)
# calculatrice:
make clean
make
# N100
# make epsilon_flash
# flashage calculatrice N110
# sudo est inutile sur Mac
make USE_LIBA=0 EPSILON_DEVICE_BENCH=0 EPSILON_USB_DFU_XIP=0 EPSILON_ONBOARDING_APP=1 EPSILON_BOOT_PROMPT=update build/device/n0110/epsilon_two_binaries -j
sudo dfu-util -D build/device/n0110/epsilon.internal.bin -s 0x08000000
sudo dfu-util -D build/device/n0110/epsilon.external.bin -s 0x90000000
================
Modifications du source d'epsilon pour linker avec giac:
================
definitions des flags C++ dans scripts/default.mak
1/ scripts/config.mak: ajouter
- Code: Select all
# giac
ifeq ($(PLATFORM),device)
SFLAGS += -DGIAC_NUMWORKS
LDFLAGS += -L../giac-1.5.0/src -L../libtommath-0.39 -lgiac -ltommath
endif
ifeq ($(PLATFORM),emscripten)
SFLAGS += -DGIAC_NUMWORKS
LDFLAGS += -O3 -v -s TOTAL_MEMORY=1GB -s LEGACY_GL_EMULATION=1 -s GL_UNSAFE_OPTS=0 --memory-init-file 0 -s ASSERTIONS=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -L/home/parisse/emgiac/giac -lgiac -lpari -lmpfi -lmpfr -lgmp -lglpk --js-library /home/parisse/emgiac/giac/time.js
endif
ifeq ($(PLATFORM),simulator)
SFLAGS += -DGIAC_NUMWORKS
LDFLAGS += -lgiac
endif
2/ apps/calculation:
au debut de calculation.cpp (avant namespace ...)
- Code: Select all
#ifdef GIAC_NUMWORKS
extern "C" const char * caseval(const char *);
#endif
plus loin
- Code: Select all
void Calculation::setContent(const char * c, Context * context, Expression ansExpression) {
reset();
#ifdef GIAC_NUMWORKS
Preferences * preferences = Preferences::sharedPreferences();
if (preferences->angleUnit() == Preferences::AngleUnit::Radian)
caseval("angle_radian:=1");
else
caseval("angle_radian:=0");
char buf[1024]="add_autosimplify(";
strlcpy(&buf[strlen(buf)],c,sizeof(buf)-strlen(buf));
buf[strlen(buf)+1]=0;
buf[strlen(buf)]=')';
const char * out=caseval(buf);
strlcpy(m_inputText,c,sizeof(m_inputText));
strlcpy(m_exactOutputText,out,sizeof(m_exactOutputText));
strlcpy(buf,"evalf(",sizeof(buf));
strlcpy(&buf[strlen(buf)],out,sizeof(buf)-strlen(buf));
buf[strlen(out)+7]=0;
buf[strlen(out)+6]=')';
out=caseval(buf);
if (strcmp(out,m_exactOutputText)==0 || (m_exactOutputText[0]=='[' && out[0]!='[')){
bool undef=false;
int l=strlen(m_exactOutputText);
for (int i=0;i<l;++i){
char ch=m_exactOutputText[i];
if ( (ch>='a' && ch<='z') || (ch>='A' && ch<='Z')){
undef=true;
break;
}
}
strlcpy(m_approximateOutputText,undef?"undef":m_exactOutputText,sizeof(m_approximateOutputText));
}
else
strlcpy(m_approximateOutputText,out,sizeof(m_approximateOutputText));
#else
{
Symbol ansSymbol = Symbol::Ans();
Expression input = Expression::Parse(c).replaceSymbolWithExpression(ansSymbol, ansExpression);
/* We do not store directly the text enter by the user because we do not want
* to keep Ans symbol in the calculation store. */
PoincareHelpers::Serialize(input, m_inputText, sizeof(m_inputText));
}
Expression exactOutput;
Expression approximateOutput;
PoincareHelpers::ParseAndSimplifyAndApproximate(m_inputText, &exactOutput, &approximateOutput, *context, false);
PoincareHelpers::Serialize(exactOutput, m_exactOutputText, sizeof(m_exactOutputText));
PoincareHelpers::Serialize(approximateOutput, m_approximateOutputText, sizeof(m_approximateOutputText));
#endif
}
3/ dans poincare/include/poincare/symbol_abstract.h: constexpr static size_t k_maxNameSize = 8;
a remplacer par 16
4/ dans poincare/src/parsing, parser.cpp, fonction void Parser::parseCustomIdentifier
- Code: Select all
...
assert(!parameter.isUninitialized());
#ifdef GIAC_NUMWORKS
if (parameter.numberOfChildren() == 1)
parameter = parameter.childAtIndex(0);
#else
if (parameter.numberOfChildren() != 1) {
m_status = Status::Error; // Unexpected number of paramters.
return;
}
parameter = parameter.childAtIndex(0);
#endif
...
5/ Pour visualiser qu'on utilise le moteur de calcul de Xcas, on peut par exemple modifier la couleur d'affichage de deg/rad en rouge:
dans apps/title_bar_view.cpp
- Code: Select all
TitleBarView::TitleBarView() :
View(),
m_titleView(KDFont::SmallFont, I18n::Message::Default, 0.5f, 0.5f, KDColorWhite, Palette::YellowDark), // YellowDark
m_preferenceView(KDFont::SmallFont, 1.0f, 0.5, KDColorWhite, Palette::Red) // YellowDark
{
m_examModeIconView.setImage(ImageStore::ExamIcon);
}
Pour avoir les angles en radian au boot
poincare/src/preferences.cpp m_angleUnit(AngleUnit::Radian),
6/ pour modifier les menus de la Toolbox, modifier apps/math_toolbox.cpp
les noms doivent etre definis dans apps/shared.universal.i18n ou/et apps/shared.[langue].i18n
par exemple
SimplifyCommandWithArg = "simplify(f)"
SimplifyValue = "simplify expression"
attention, faire clean ou deux fois make sinon les messages sont decales
7/ dans le fichier ion/src/device/n0110/flash.ld J'ai singe le fichier correspondant du port de zardam en ajoutant
- Code: Select all
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} >INTERNAL_FLASH
juste avant la section .data
8/ dans ion/src/device/shared/boot/rt0.cpp, dans la fonction start()
deplacer Ion::Device::Board::init(); avant
#define SUPPORT_CPP_GLOBAL_CONSTRUCTORS
et modifier la valeur de ce define a 1 (initialement a 0)
9/ Ayant une erreur de linkage relative a __errno entre flash interne et flash externe, j'ai desactive la verification dans ion/src/device/n0110/flash.ld:
/* NOCROSSREFS_TO(.text.external .text.internal); */