2010-03-04 9 views
5

Estoy trabajando en el firmware para un proyecto USB integrado. El programador de producción que me gustaría utilizar escribe automáticamente el número de serie en la memoria flash del dispositivo en una dirección de memoria especificada. El programador almacena el número de serie como dígitos hexadecimales en un número específico de bytes. Por ejemplo, si yo digo que para almacenar el número de serie 123456 en la dirección 0x3C00 mi memoria se parece a esto:¿Cómo puedo convertir un entero en una cadena Unicode en C?

0x3C00 - 00 
0x3C01 - 01 
0x3C02 - E2 
0x3C03 - 40 
//(123456 in Hex = 1E240) 

El problema es, cuando mi aplicación host lee el número de serie del dispositivo que está buscando un Unicode matriz de caracteres Así que mi número de serie debe ser ...

{ '1','0', 
    '2','0', 
    '3','0', 
    '4','0', 
    '5','0', 
    '6','0'} 

Cuando el

Así que en mi firmware, que estoy escribiendo en C, es posible recuperar el número de serie hexadecimal de la memoria flash, codificarlo en una matriz de caracteres Unicode y almacenarlo en una variable en Ram?

+0

creo que la matriz de muestra debería ser 'ushort [] serie = { '1', '2' , '3', '4', '5', '6'} ' –

+0

¿Podemos suponer que su compilador C entiende unicode? –

Respuesta

2

Si el número de serie cabe en 32 bits y la plataforma es big endian y admite Unicode, 32 bit ints y las bibliotecas estándar de C, esto es bastante sencillo ya que se han mostrado otras respuestas. Si la plataforma tiene 32 bitts y 8 bit chars pero es little endian y/o no admite Unicode, y si el número de serie puede variar en longitud, entonces lo siguiente puede ser útil, aunque es un poco workmanlike.

void extract_serial_number(unsigned char* address, unsigned int bytes, char* buffer) { 
    unsigned int value = 0; 
    char c, *start = buffer; 
    while (bytes--) {      /* read the serial number into an integer */ 
     value = value << 8; 
     value |= *address++; 
    } 
    while (value > 0) {     /* convert to 16 bit Unicode (reversed) */ 
     *buffer++ = '0' + value % 10; 
     *buffer++ = '\0'; 
     value /= 10; 
    } 
    *buffer++ = '\0'; 
    *buffer++ = '\0'; 
    buffer -= 4; 
    while (buffer > start) {    /* reverse the string */ 
     c = *buffer; 
     *buffer = *start; 
     *start = c; 
     buffer -= 2; 
     start += 2; 
    } 
} 
3

Usted debe ser capaz de usar algo como esto:

wchar_t buf[10]; 
swprintf(buf, L"%d", your_int_value); 

Los detalles pueden ser diferentes dependiendo de su aplicación exacta de la biblioteca de tiempo de ejecución C. Por ejemplo, su swprintf() puede esperar que el número de caracteres de buf:

swprintf(buf, sizeof(buf)/sizeof(buf[0]), L"%d", your_int_value); 
+0

dudo que sea posible en el firmware – Andrey

+0

Dado que es un número de 32 bits, tendrá que usar% ld en lugar de% d. – semaj

+0

@Andrey: Firmware es solo software con otro nombre. El firmware puede tener extensas bibliotecas de tiempo de ejecución disponibles. –

4

Parece que usted quiere:

wsprintf(wchar_buffer, L"%d", serial_number) 

(suponiendo que el número de serie cabe en un entero de 32 bits En todo. caso, wsprintf va a imprimir el número de serie como una cadena wchar (unicode).

+0

'wchar_t' no es necesariamente 16 bits UCS2 (ni siquiera es necesariamente Unicode en absoluto). – caf

+0

Cierto, pero si ese es el caso, entonces usted tiene problemas mayores. Debería poder leer los documentos de su compilador para determinar si 'wchar_t' tiene el tamaño de char que necesita (y si no, cómo establecer el indicador para que' wchar_t' haga lo que quiera). –

+0

¿Puedes explicar qué significa L? – SeanLetendre

2

no está seguro de que este código se ajusta a su dispositivo, pero vamos a tratar

char buffer[MAX_SIZE]; 
char unicodeBuffer[MAX_SIZE]; 
sprintf(buffer, "%d", i); 
int len = strlen(buffer); 
int i = 0; 
for (int i = 0; i <= (len << 1) - 2; i++) 
    unicodeBuffer[i] = i % 2 ? buffer[i] : 0; 
unicodeBuffer[i + 1] = 0; 
unicodeBuffer[i + 2] = 0; 
+0

Eso no funciona; solo está copiando la mitad de los caracteres del búfer creado por 'sprintf'. – caf

2

Si usted tiene acceso a sprintf en su entorno incorporado, entonces esto debería funcionar:

#define MAX_SIZE(type) ((CHAR_BIT * sizeof(type) - 1)/3 + 2) 

/* Destination UCS2 buffer size must be at least 2*MAX_SIZE(int) */ 
void int_to_ucs2(char *dest, int q) 
{ 
    char buffer[MAX_SIZE(q)]; 
    char *src = buffer; 

    sprintf(buffer, "%d", q); 

    do { 
     *dest++ = *src; 
     *dest++ = 0; 
    } while (*src++); 
} 
Cuestiones relacionadas