Witam,
Od niedawna jestem świeżym posiadaczem płytki testowej dla LPC2148 (z Kamami) i powoli rozgrywam tajniki tych mikroprocków. Wcześniej sporo pisałem na AVR'ki. Mam problem z funkcją sprintf()/iprintf(). Otóż wszystko działa poprawnie, kiedy wywołuję np. taki kod:
Na wyświetlaczu dostaję piękne "A: 2". Natomiast nie działa, kiedy chcę operować na liczbach zmiennoprzecinkowych:
Na wyświetlaczu nie widać nic, program zdaje się wieszać (nie wywołuje się już żadna instrukcja po sprintf()). Nie wiem, co może być powodem problemu, może ktoś poratować?
Dla wszystkiego, wrzucam plik syscalls.c i startup.s:
Pozdrawiam,
Bartosz
Od niedawna jestem świeżym posiadaczem płytki testowej dla LPC2148 (z Kamami) i powoli rozgrywam tajniki tych mikroprocków. Wcześniej sporo pisałem na AVR'ki. Mam problem z funkcją sprintf()/iprintf(). Otóż wszystko działa poprawnie, kiedy wywołuję np. taki kod:
int a=2;
char buf[16];
sprintf(buf, "A: %d", a);
LCDWrite(buf);
Na wyświetlaczu dostaję piękne "A: 2". Natomiast nie działa, kiedy chcę operować na liczbach zmiennoprzecinkowych:
double a=2;
char buf[16];
sprintf(buf, "A: %0.2lf", a);
LCDWrite(buf);
Na wyświetlaczu nie widać nic, program zdaje się wieszać (nie wywołuje się już żadna instrukcja po sprintf()). Nie wiem, co może być powodem problemu, może ktoś poratować?
Dla wszystkiego, wrzucam plik syscalls.c i startup.s:
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "uart.h"
#undef errno
extern int errno;
caddr_t _sbrk(int incr)
{
extern char _end; /* Defined by the linker */
extern char _ram_end;
static char *heap_end;
char *prev_heap_end;
if(heap_end == 0)
{
heap_end = &_end;
}
prev_heap_end = heap_end;
if(heap_end + incr > (char*)&_ram_end)
{
errno = ENOMEM;
return (caddr_t) -1;
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
int _isatty(int fd)
{
return 1;
}
int _lseek(int fd, off_t pos, int whence)
{
return 0;
}
int _close(int file) {
return -1;
}
int _read(int fd, void *buffer, unsigned int count)
{
return(0);
}
int _fstat(int file, struct stat *st) {
st->st_mode = S_IFCHR;
return 0;
}
int open(const char *name, int flags, int mode) {
return -1;
}
int
_write(int file, char *ptr, int len) {
int todo;
for (todo = 0; todo < len; todo++) {
UART_PutChar((*ptr++));
}
return len;
}
/* ***************************************************************************************************************
crt.s STARTUP ASSEMBLY CODE
-----------------------
Module includes the interrupt vectors and start-up code.
*************************************************************************************************************** */
/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000200
.set ABT_STACK_SIZE, 0x00000200
.set FIQ_STACK_SIZE, 0x00000200
.set IRQ_STACK_SIZE, 0x00000200
.set SVC_STACK_SIZE, 0x00000200
#.set _MEMMAP, 0xE01FC040
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set MODE_USR, 0x10 /* Normal User Mode */
.set MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
.set MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
.set MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */
.set MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */
.set MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */
.set MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */
.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */
.text
.arm
.global Reset_Handler
.global _startup
.func _startup
_startup:
# Exception Vectors
_vectors: ldr PC, Reset_Addr
ldr PC, Undef_Addr
ldr PC, SWI_Addr
ldr PC, PAbt_Addr
ldr PC, DAbt_Addr
nop /* Reserved Vector (holds Philips ISP checksum) */
ldr PC, [PC,#-0xFF0] /* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin */
ldr PC, FIQ_Addr
Reset_Addr: .word Reset_Handler /* defined in this module below */
Undef_Addr: .word UNDEF_Routine /* defined in main.c */
SWI_Addr: .word SWI_Routine /* defined in main.c */
PAbt_Addr: .word UNDEF_Routine /* defined in main.c */
DAbt_Addr: .word UNDEF_Routine /* defined in main.c */
IRQ_Addr: .word IRQ_Routine /* defined in main.c */
FIQ_Addr: .word FIQ_Routine /* defined in main.c */
.word 0 /* rounds the vectors and ISR addresses to 64 bytes total */
Reset_Handler:
/* Setup a stack for each mode - note that this only sets up a usable stack
for User mode. Also each mode is setup with interrupts initially disabled. */
ldr r0, =_stack_end
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* User Mode */
mov sp, r0
/* copy .data section (Copy from ROM to RAM) */
ldr R1, =_text_end
ldr R2, =_data_start
ldr R3, =_data_end
1: cmp R2, R3
ldrlo R0, [R1], #4
strlo R0, [R2], #4
blo 1b
/* Clear .bss section (Zero init) */
mov R0, #0
ldr R1, =_bss_start
ldr R2, =_bss_end
2: cmp R1, R2
strlo R0, [R1], #4
blo 2b
/* Enter the C code */
b main
.endfunc
.end
Pozdrawiam,
Bartosz