Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Complete C standard library
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Complete C standard library

Posté le 19/08/2018 19:31

Motivation
Until now there was no complete C standard library (aka libc) available for the Casio calculators. Although some parts of this library have been provided by fxlib and gint, there was no libc implementation complying with the standard and compatible with the sh3eb architecture ready to use.

To change that, I decided to port newlib to the Casio CPU. Newlib is an alternative libc implementation intended for use on embedded systems.


Alpha
Follow this link and click the download button in the top right corner:

>>> v1.1 <<<


Instructions on how to install newlib alongside with gcc (big shout-out to Lephé):

Compiler sous Linux avec GCC


Features for Casio fx9860g calculators:
* C standard library libc
printf implementation to print text to the display
→ Dynamic allocation of memory using malloc and free
→ Memory manipulation using memcpy, memcmp, memset etc.
→ String manipulation using strcpy, strcmp, strstr, strtok
→ ...
* Math library libm
→ Floating point arithmetics
→ ...
* Automatic library and include path recognition after installation
* Basic Casio features:
→ implementation of GetKey, Bdisp_AllClr_DDVRAM, Bdisp_PutDisp_DD, Print and locate without fxlib (but you can use it if you want)


Code
To contribute or get all those bleeding edge features, see the code including all further information:

libc (my GitLab repository)


The project you find in my repository is a fork of the official newlib repository. To make it easier for everyone to follow, I try to keep a clean git history. That means that all my changes are located on a dedicated branch with meaningful commits.

I also try to keep the changes to the upstream library minimal. That increases maintainability a lot.


Contributing
If you have a ideas, feature request, found a bug or simply want to contribute, just send me a message and you're in! You can also create Issues and Merge Requests directly in the repository. As in every OpenSource project: merge requests welcome!


Précédente 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 Suivante
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 23/08/2018 22:04 | #


Lephenixnoir a écrit :
[...] a good complete, packaged, documented thing, I fail to see.

I'm surprised that there are so many cool applications here and yet not a really solid basis (hardware support, libc etc.). (So good job creating gint xD)

Lephenixnoir a écrit :
I can't deny dprint() or sprintf() to the non-libc user since I have a lightweight implementation at hand.

Of course not, classical case for #ifndef __NEWLIB_H__

Lephenixnoir a écrit :
I find the way you elude how hellish USB is, fascinating.

To be honest I never developed apps for USB. Right after I started all those cool ideas that sound much better in my head than they are in reality... and finished them about 60% just to abandon them - I might collaborate with you implementing USB to... (which device do you even want to communicate to? You'd have to write a linux usb driver... That requires a good use case for motivation)
Stop starting~ Start finishing~
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 23/08/2018 22:15 | #


Of course not, classical case for #ifndef __NEWLIB_H__

Since this is at gint compile-time, where I don't include newlib headers, I'd rather rely on the configuration file. Or do you mean I can decide whether to expose my printf()-family functions at add-in compile time?

To be honest I never developed apps for USB. Right after I started all those cool ideas that sound much better in my head than they are in reality... and finished them about 60% just to abandon them - I might collaborate with you implementing USB to... (which device do you even want to communicate to? You'd have to write a linux usb driver... That requires a good use case for motivation)

Am I wrong assuming that we could communicate with Linux without having to write a new Linux driver?

Honestly the possibilities are vast! Start with a more-automated transfer tool than LINK. Then USB logs for add-ins that may crash before even being able to display anything (... ). And controlling a music player from the calculator to make better sound than the 1-bit serial sound. A GIF/video recorder that does not use protocol 7...
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 23/08/2018 22:33 | #


Lephenixnoir a écrit :
Since this is at gint compile-time, where I don't include newlib headers, I'd rather rely on the configuration file

Never mind, I'm an idiot. This is a classical use case of the weak attribute, though. Now for real

Lephenixnoir a écrit :
Am I wrong assuming that we could communicate with Linux without having to write a new Linux driver?

Frankly I don't know. I expect that we had to write a driver (probably use libusb)...

Ok debugging would be neat. xD

Lephenixnoir a écrit :
the 1-bit serial sound

Please tell me that the calculator has a beeper integrated!
Stop starting~ Start finishing~
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 23/08/2018 22:40 | #


Never mind, I'm an idiot. This is a classical use case of the weak attribute, though. Now for real

Well spotted!

Please tell me that the calculator has a beeper integrated!

Totally not, we can either make 1-bit sound using raw serial data, or - using a technique which I attribute to Martin Poupe - spam the serial port so hard that it can't keep up with the 0-5V switches and ends up oscillating somewhere in the middle, allowing the add-in to output an analog signal by varying the relative amount of 0's and 1's in the serial stream to bump the tension up or down. Although the output is at low volume since the oscillation range is slim, I must admit that it works extremely well.

Now I just pushed a simple test to the repository for the test application: it's a somewhat exhaustive test for the core memory functions, memcpy(), memset() and memmove(). It checks that the result is correct for all alignment/overlap scenarios, and does it with different operation lengths to trigger optimization mechanisms.

As expected the result is good: 768/768. However, printf() triggered a SysERROR of type INTERRUPT, which should never happen with reasonable add-ins, so you might want to have a look into it. I also had to define an _end symbol in the linker script to be able to build without interfering with your current work on _sbrk; I hope it won't disturb.

Also, I've had a quick look at the size of the resulting program (35~40k), which is reasonable but quite high. Not sure what we can do about it...
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Dark storm En ligne Labélisateur Points: 11631 Défis: 176 Message

Citer : Posté le 23/08/2018 22:57 | #


A demo of the sound you can get oncalc. The hardware (a capacity) purpose is to improve the quality of the output sound.


Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 23/08/2018 23:29 | #


Cool. I always wondered what the jack at the top right side is good for!

@Lephe A dumb bug again. I didn't notice that the strings passed from printf to write are not null-terminated. Fixed now.

Also, thank you for testing!

About the code size: I'm sure there are configure options to reduce the code size. I'll look into that tomorrow.

Addendum: they can also be set by default for our target to safe the user from typing a hundred frags into the command line.
Stop starting~ Start finishing~
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 23/08/2018 23:44 | #


@Lephe A dumb bug again. I didn't notice that the strings passed from printf to write are not null-terminated. Fixed now.

Aye, typical trap, I'd fall into it as well xD

You're welcome! Don't forget to start with -Os since there's pretty much 30k of code in there
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 24/08/2018 12:30 | #


I disabled some features by default for the sh3eb target now. Lephé, could you add the --enable-target-optspace to the configure call in the Compiler sous Linux avec GCC tutorial, please?
Stop starting~ Start finishing~
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 24/08/2018 14:26 | #


Yes, that's done! I also rebuilt my compiler with it, and checked the new size of your add-in : it's about 29k which is at least 5k less than before. A nice improvement!
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 24/08/2018 14:26 | #


Thanks
Stop starting~ Start finishing~
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 29/08/2018 11:25 | #


Hi Memallox, I definitely saw the message you sent me some days ago, but by the time I saw it, I wasn't able to answer very easily… and now that I am, I'm not sure, with what I see on this topic, that I could provide you with anything new anyway… x)
I'm glad to see that this project is pretty well engaged, and I will spend some time giving a more precise look to the git repo and to all that has been said here… !
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 31/08/2018 14:56 | #


I seems that newlib is not C99 compliant. While it provides all functionality I would expect from a libc implementation at first glance, I noticed that it does not provide the %zu format specifier (which is definitely part of the C99 standard).


int variable = 42;
printf("Size of variable: %zu", sizeof(variable));
// prints "Size of variable: zu" instead of "Size of variable: 4"


After further investigation, there is no claim that newlib is compliant to anything. I guess that's because some functionality is stripped from the library since it is targeted for embedded devices. Do you think that's a problem? We might implement features we desperately need by ourselves. Cakeisalie5 is probably an expert here due to his efforts with libcarrot, his own experimental self-made libc implementation!

Ajouté le 31/08/2018 à 15:03 :
@Nemhardy
No problem! (:

At the moment I'm steadily working on this project to get to an intuitive and easy-to-use solution. If you have any code or just ideas feel free to discuss them here. I really appreciate any support!
Stop starting~ Start finishing~
Cakeisalie5 Hors ligne Ancien administrateur Points: 1896 Défis: 11 Message

Citer : Posté le 31/08/2018 15:07 | #


I refuse to be called an expert è_é

The z case seems to be managed by newlib (reference), at the condition that _WANT_IO_C99_FORMATS is defined. It seems that for this macro to be defined, the --enable-newlib-io-c99-formats must be passed while configuring newlib

Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 31/08/2018 15:14 | #


Oh thank you Cakeisalie5! I did totally not see this. I enabled it for the sh3eb arch by default. I will probably publish it alongside with a some other changes today.

However, I still think that newlib is not C99 compliant (which is no a drama) xD
Stop starting~ Start finishing~
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 31/08/2018 17:34 | #


Memallox a écrit :
However, I still think that newlib is not C99 compliant (which is no a drama) xD

Really, when you compare the SDK alternative (C89 compiler + partial C89 standard library), with the GCC system (C11 compiler + partially C99-compliant newlib), the improvement is already huge.

So I understand that I don't need to edit the GCC tutorial to add the new flag, right?
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 31/08/2018 17:57 | #


Lephenixnoir a écrit :
The improvement is already huge

You are right, of course xD

Lephenixnoir a écrit :
I don't need to edit the GCC tutorial to add the new flag, right?

No, you don't need to add the new argument, I will add them to the default host configuration

Ajouté le 31/08/2018 à 21:12 :
I just uploaded v1.01 which offers now full support of printf. This includes not only the %z format specifier, but also control characters like \r, \n, \t, \v etc.

The new console behaves just like any terminal, but without scrolling (that's not what most of us need anyway).

Unlike with Print() from fxlib, the cursor's default position is (0/0) (instead of undefined). Yes, indexing is now 0-based :D. To change the position, locate() can be called.
Stop starting~ Start finishing~
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 31/08/2018 21:59 | #


I just uploaded v1.01 which offers now full support of printf.

Good job!

This includes not only the %z format specifier, but also control characters like \r, \n, \t, \v etc.

Are you sure that escape characters are handled by printf() and not the lexical analyzer of the compiler ?
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 31/08/2018 22:32 | #


Lephenixnoir a écrit :
Are you sure that escape characters are handled by printf() and not the lexical analyzer of the compiler ?


Of course the \n is converted to the LF character by the compiler. What I meant is that Print does not understand it's meaning per se and prints out some weird special character instead of performing a line feed.

The interpretation of these control characters is the job of the terminal which in this case is fed by _write(). I guess this would usually be the kernel's job. Btw, if you're considering implementing such a feature, feel free to get inspired by my code :P.
Stop starting~ Start finishing~
Lephenixnoir En ligne Administrateur Points: 24145 Défis: 170 Message

Citer : Posté le 31/08/2018 22:54 | # | Fichier joint


Of course the \n is converted to the LF character by the compiler. What I meant is that Print does not understand it's meaning per se and prints out some weird special character instead of performing a line feed.

Oh, right, just starting this high-level thinking about the standard and I already forgot what kind of platform we're running on. Sorry for that -_-"

Btw, if you're considering implementing such a feature, feel free to get inspired by my code :P.

Thanks for the reference! I quickly compared with the console I implemented when I experimented around with the early x86 kernel environment, and I see that both of our codes fail to address an efficiency concern: avoid checking all special characters when there is actually none. I attached my own program for reference.

The only way around I see is to define a 256-byte lookup table telling whether there is special behaviour for a given character. This makes it 1 lookup for all written bytes, regardless of the number of special behaviours.

Even though I'm saying all this, it really doesn't matter for the calculator, as we never output really long text. This is more of a theoretic concern about how we can efficiently implement a console. The kernel console is much more sensible to this kind of optimization
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Memallox Hors ligne Membre Points: 161 Défis: 0 Message

Citer : Posté le 31/08/2018 23:11 | #


Oh you're right. To be honest, I thought about that switch, too, but I couldn'd come up with a better way. The lookup table is a great idea. To save space one could even use a lookup table which has a bit only for each character. That would require only 32 byte... or both solutions depending on space/performance optimisation... ideas over ideas xD

I created an issue and postponed the issue since I have a bigger problem right now:

I found a challenge which I didn't find a clean solution for. As previously discussed, I need to replace calloc() by a Casio syscall which in my case is called _calloc_ptr().

calloc() is declared in stdlib.h and defined in newlib/libc/stdlib/mallocr.c:3189. Now the standard procedure to add target-specific code to stdlib is to create a file (machine/stdlib.h) which will be included into stdlib.h by default.

A quick glance into stdlib.h:

#ifndef _STDLIB_H_
#define _STDLIB_H_

#include <machine/ieeefp.h>
#include "_ansi.h"
[...]
#include <machine/stdlib.h>
[...]


What I want to do is something like:
#define calloc calloc_ptr


However, I cannot put that preprocessor directive into machine/stdlib.h since it would replace the declaration of calloc with calloc_ptr and result in a redefinition error. I somehow need to #define calloc calloc_ptr after the declaration of calloc. Any ideas on how to do that?

Addendum: If possible, I want to modify target-specific files only (rather than stdlib.h) because otherwise my repository would be a bitch to maintain xD.

Stop starting~ Start finishing~
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 31/08/2018 23:16 | #


Couldn't you just put the function declaration inside the define?

#define calloc(num, size) calloc_ptr(num, size)

Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Précédente 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 98 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd