Ligero (subconjunto) de la biblioteca C estándar (biblioteca ANSI C)

5

Estoy portando la biblioteca estándar de C para "OS" de metal desnudo (ARM Cortex-M4, ARM GCC). Quiero tener funciones como strlen, sprintf, (y asignador de memoria, tal vez), etc.

He portado PDCLib y Newlib. Newlib no es ligero (e intenta implementar operaciones de archivos, etc.). PDCLib no está en desarrollo activo.

Por lo tanto, quiero Microlib exactamente. Pero no es para GCC y código cerrado.

¿Hay algunas alternativas para esto? ¿Y hay algunos "subconjuntos de metal desnudo" de la biblioteca estándar de C?

    
pregunta Kuraga

2 respuestas

11

Cuando quiero una biblioteca realmente liviana (y / o que sea segura para subprocesos) normalmente escribo la mía. No es difícil de hacer.

Ya que habla sobre un "asignador de memoria", permítame sugerir que un par malloc () / free es trivial para escribir, quizás unas pocas docenas de líneas:

#define STATUSFREE 0
#define STATUSUSED 1
struct tag {
    struct tag * next;
    int status;
};
struct tag * heap;
void free( void * p ) {
    struct tag * ptag= ((struct tag *)p) - 1;
        ptag->status= STATUSFREE;
}
void * malloc( size_t s ) {
    struct tag *ptag, *pnext;
        for ( ptag= heap; ptag != NULL; ptag= ptag->next )
            if (ptag->status == STATUSFREE) {
                for ( pnext= ptag->next; pnext->status == STATUSFREE; pnext= pnext->next )
                    ;
                if ( s <= (size_t) (((char *) pnext) - (char *) (ptag+1)) ) {
                    if ( s <= (size_t) (((char *) pnext) - (char *) (ptag+2)) ) {
                        ptag->next= (struct tag *) (s + (char *) (ptag+1));
                        ptag->next->status= STATUSFREE;
                        ptag->next->next= pnext;
                    } else
                        ptag->next= pnext;
                    ptag->status= STATUSUSED;
                    return ptag+1;
                }
                ptag->next= pnext;
            }
    return NULL;
}

Lo inicializas de la siguiente manera. Primero, configure un bloque fijo de memoria usando una asignación de matriz estándar como esta:

static char mspace[1000];

Se puede colocar en algún módulo que escribas. Debe asignarse como tiempo de vida estático, por supuesto.

Luego, en otro lugar (como en main ()), haz lo siguiente:

((struct tag *) &mspace[0])->status= STATUSFREE;
((struct tag *) &mspace[0])->next= &((struct tag *) &mspace[sizeof(mspace)])[-1];
((struct tag *) &mspace[sizeof(mspace)])[-1].status= STATUSUSED;
((struct tag *) &mspace[sizeof(mspace)])[-1].next= NULL;
heap= (struct tag *) &mspace[0];

Es muy rápido y muy fácil.

strlen () es, por supuesto, mucho más fácil y puedes encontrar todo tipo de implementación en la web para eso.

El resto? Te recomiendo que escribas eso también. Un libro muy, muy útil aquí es P. J. Plauger (uno de los fundadores de Whitesmiths LTD - compiler company) "The Standard C Library". Solo consigue una copia. No te arrepentirás. Cubre cosas como sprintf () para usted, que es mucho más complicado y puede implicar tratar con valores de punto flotante al convertir para salida. (Cuando vuelva a crear Sprintf (), como resultado de eso, arrastrará un montón de código, pero solo es necesario si desea una función de biblioteca tan poderosa).

    
respondido por el jonk
0

Deberías echar un vistazo a musl .

Es ligero y de código abierto, y está diseñado para aplicaciones integradas.
No sé si esto satisface exactamente sus requisitos.

    
respondido por el Antonio

Lea otras preguntas en las etiquetas