initrd, lcd, file cleanup
parent
058c283919
commit
e5ae7f10f3
@ -1,16 +1,44 @@
|
|||||||
|
CROSS = arm-none-eabi-
|
||||||
|
CC = gcc
|
||||||
|
AS = as
|
||||||
|
AR = ar
|
||||||
|
OBJCOPY = objcopy
|
||||||
|
|
||||||
MCUFLAGS = -mthumb -mcpu=cortex-m4
|
MCUFLAGS = -mthumb -mcpu=cortex-m4
|
||||||
CFLAGS = -Iinclude $(MCUFLAGS)
|
AFLAGS = $(MCUFLAGS)
|
||||||
|
CFLAGS = $(MCUFLAGS) -Iinclude -ffreestanding -Wall -Werror -Wextra
|
||||||
all:
|
OFLAGS = -O ihex
|
||||||
arm-none-eabi-as $(MCUFLAGS) startup_stm32l476xx.s -c -o out/startup_stm32l476xx.o
|
|
||||||
arm-none-eabi-gcc $(CFLAGS) system_stm32l4xx.c -c -o out/system_stm32l4xx.o
|
CFILES = $(wildcard src/*.c)
|
||||||
arm-none-eabi-gcc $(CFLAGS) stm32l4xx_it.c -c -o out/stm32l4xx_it.o
|
AFILES = $(wildcard src/*.s)
|
||||||
arm-none-eabi-gcc $(CFLAGS) clock.c -c -o out/clock.o
|
|
||||||
arm-none-eabi-gcc $(CFLAGS) heap.c -c -o out/heap.o
|
OUTDIR = out
|
||||||
arm-none-eabi-gcc $(CFLAGS) task.c -c -o out/task.o
|
OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \
|
||||||
arm-none-eabi-gcc $(CFLAGS) main.c -c -o out/main.o
|
$(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES))
|
||||||
arm-none-eabi-gcc $(CFLAGS) -T link.ld out/*.o -o out/main.elf
|
|
||||||
arm-none-eabi-objcopy -O ihex out/main.elf main.hex
|
LIBDIR = -Llib
|
||||||
|
LIBS = -llua
|
||||||
|
|
||||||
|
HEX = main.hex
|
||||||
|
|
||||||
|
all: $(HEX)
|
||||||
|
|
||||||
|
$(HEX): $(OFILES)
|
||||||
|
@echo " LINK " $(HEX)
|
||||||
|
@$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img out/initrd.img.o
|
||||||
|
@$(CROSS)$(CC) $(CFLAGS) $(LIBDIR) $(LIBS) -T link.ld out/*.o -o out/main.elf
|
||||||
|
@$(CROSS)$(OBJCOPY) $(OFLAGS) out/main.elf $(HEX)
|
||||||
|
|
||||||
|
$(OUTDIR)/%.o: src/%.c
|
||||||
|
@echo " CC " $<
|
||||||
|
@$(CROSS)$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(OUTDIR)/%.asm.o: src/%.s
|
||||||
|
@echo " AS " $<
|
||||||
|
@$(CROSS)$(AS) $(AFLAGS) -c $< -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf out/*
|
@echo " CLEAN"
|
||||||
|
@rm -rf out/*
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef GPIO_H_
|
||||||
|
#define GPIO_H_
|
||||||
|
|
||||||
|
#include <stm32l476xx.h>
|
||||||
|
|
||||||
|
#define GPIO_PORT(p, b) GPIO##p, b
|
||||||
|
|
||||||
|
enum GPIO_MODE
|
||||||
|
{
|
||||||
|
INPUT = 0,
|
||||||
|
OUTPUT,
|
||||||
|
ALTERNATE,
|
||||||
|
ANALOG
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GPIO_TYPE
|
||||||
|
{
|
||||||
|
PUSHPULL = 0,
|
||||||
|
OPENDRAIN
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GPIO_SPEED
|
||||||
|
{
|
||||||
|
LOW = 0,
|
||||||
|
MEDIUM,
|
||||||
|
HIGH,
|
||||||
|
VERYHIGH
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GPIO_PUPD
|
||||||
|
{
|
||||||
|
NOPUPD,
|
||||||
|
PULLUP,
|
||||||
|
PULLDOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
void gpio_init(void);
|
||||||
|
|
||||||
|
void gpio_pupd(GPIO_TypeDef *port, uint8_t pin, uint8_t pupd);
|
||||||
|
void gpio_type(GPIO_TypeDef *port, uint8_t pin, uint8_t type);
|
||||||
|
void gpio_mode(GPIO_TypeDef *port, uint8_t pin, uint8_t mode);
|
||||||
|
void gpio_dout(GPIO_TypeDef *port, uint8_t pin, uint8_t val);
|
||||||
|
uint8_t gpio_din(GPIO_TypeDef *port, uint8_t pin);
|
||||||
|
|
||||||
|
#endif // GPIO_H_
|
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef INITRD_H_
|
||||||
|
#define INITRD_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char signature[8];
|
||||||
|
} __attribute__ ((packed)) initrd_header;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[16];
|
||||||
|
uint8_t unused[32];
|
||||||
|
char size[10];
|
||||||
|
char sig[2];
|
||||||
|
} __attribute__ ((packed)) initrd_file;
|
||||||
|
|
||||||
|
uint8_t initrd_validate(void);
|
||||||
|
char *initrd_getfile(const char *name);
|
||||||
|
uint32_t initrd_getfilesize(const char *name);
|
||||||
|
|
||||||
|
#endif // INITRD_H_
|
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef LCD_H_
|
||||||
|
#define LCD_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void lcd_init(void);
|
||||||
|
|
||||||
|
void lcd_puts(const char *s);
|
||||||
|
void lcd_puti(int i);
|
||||||
|
void lcd_puth(int h);
|
||||||
|
void lcd_putb(uint8_t b);
|
||||||
|
void lcd_clear(void);
|
||||||
|
|
||||||
|
#endif // LCD_H_
|
@ -0,0 +1 @@
|
|||||||
|
Hello, world!
|
@ -0,0 +1,3 @@
|
|||||||
|
print "yay"
|
||||||
|
|
||||||
|
yesyesye
|
Binary file not shown.
@ -1,75 +0,0 @@
|
|||||||
#include <stm32l476xx.h>
|
|
||||||
#include <clock.h>
|
|
||||||
#include <heap.h>
|
|
||||||
#include <task.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accomplishments:
|
|
||||||
* - GPIO in/out
|
|
||||||
* - got to 80MHz clock
|
|
||||||
* - basic heap
|
|
||||||
* - multitask, can exit
|
|
||||||
*/
|
|
||||||
|
|
||||||
void pulse(uint8_t byte);
|
|
||||||
void kmain(void);
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
asm("cpsid i");
|
|
||||||
|
|
||||||
// prepare flash latency for 40MHz operation
|
|
||||||
FLASH->ACR &= ~(FLASH_ACR_LATENCY);
|
|
||||||
FLASH->ACR |= FLASH_ACR_LATENCY_4WS;
|
|
||||||
|
|
||||||
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; // A clk enable
|
|
||||||
GPIOA->MODER &= ~(GPIO_MODER_MODE5 | GPIO_MODER_MODE6); // A5 -> output, A0 input
|
|
||||||
GPIOA->MODER |= GPIO_MODER_MODE5_0 | GPIO_MODER_MODE6_0;
|
|
||||||
GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPD5 | GPIO_PUPDR_PUPD6);
|
|
||||||
GPIOA->PUPDR |= GPIO_PUPDR_PUPD5_0 | GPIO_PUPDR_PUPD6_0; // pulldown for button (1)
|
|
||||||
//if (GPIOA->IDR & 0x01)
|
|
||||||
|
|
||||||
clock_init();
|
|
||||||
task_init(kmain);
|
|
||||||
|
|
||||||
while (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void task(void);
|
|
||||||
void kmain(void)
|
|
||||||
{
|
|
||||||
asm("cpsie i");
|
|
||||||
|
|
||||||
task_start(task, 1024);
|
|
||||||
while (1) {
|
|
||||||
GPIOA->BSRR |= 1 << 6;
|
|
||||||
delay(500);
|
|
||||||
GPIOA->BRR |= 1 << 6;
|
|
||||||
delay(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void task(void)
|
|
||||||
{
|
|
||||||
while (1) {
|
|
||||||
GPIOA->BSRR |= 1 << 5;
|
|
||||||
delay(200);
|
|
||||||
GPIOA->BRR |= 1 << 5;
|
|
||||||
delay(200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void _exit(int code)
|
|
||||||
{ for (;;); }
|
|
||||||
|
|
||||||
void pulse(uint8_t byte)
|
|
||||||
{
|
|
||||||
int8_t i = 7;
|
|
||||||
do {
|
|
||||||
GPIOA->BSRR |= 1 << 5;
|
|
||||||
delay((byte & (1 << i)) ? 400 : 100);
|
|
||||||
GPIOA->BRR |= 1 << 5;
|
|
||||||
delay((byte & (1 << i)) ? 100 : 400);
|
|
||||||
} while (--i >= 0);
|
|
||||||
}
|
|
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo "Making initrd.img..."
|
||||||
|
rm -f initrd.img
|
||||||
|
arm-none-eabi-ar r initrd.img initrd/*
|
@ -0,0 +1,44 @@
|
|||||||
|
#include <gpio.h>
|
||||||
|
|
||||||
|
void gpio_init(void)
|
||||||
|
{
|
||||||
|
// enable clocks
|
||||||
|
RCC->AHB2ENR |= 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_pupd(GPIO_TypeDef *port, uint8_t pin, uint8_t pupd)
|
||||||
|
{
|
||||||
|
port->PUPDR &= ~(0x03 << (2 * pin));
|
||||||
|
port->PUPDR |= pupd << (2 * pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_speed(GPIO_TypeDef *port, uint8_t pin, uint8_t speed)
|
||||||
|
{
|
||||||
|
port->OSPEEDR &= ~(0x03 << (2 * pin));
|
||||||
|
port->OSPEEDR |= speed << (2 * pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_type(GPIO_TypeDef *port, uint8_t pin, uint8_t type)
|
||||||
|
{
|
||||||
|
port->OTYPER &= ~(1 << pin);
|
||||||
|
port->OTYPER |= type << pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_mode(GPIO_TypeDef *port, uint8_t pin, uint8_t mode)
|
||||||
|
{
|
||||||
|
port->MODER &= ~(0x03 << (2 * pin));
|
||||||
|
port->MODER |= mode << (2 * pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_dout(GPIO_TypeDef *port, uint8_t pin, uint8_t val)
|
||||||
|
{
|
||||||
|
if (val)
|
||||||
|
port->BSRR |= (1 << pin);
|
||||||
|
else
|
||||||
|
port->BRR |= (1 << pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t gpio_din(GPIO_TypeDef *port, uint8_t pin)
|
||||||
|
{
|
||||||
|
return port->IDR & (1 << pin);
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
#include <initrd.h>
|
||||||
|
|
||||||
|
extern uint8_t _binary_initrd_img_start[];
|
||||||
|
extern uint8_t _binary_initrd_img_size[];
|
||||||
|
|
||||||
|
static const void *initrd_start = (void *)_binary_initrd_img_start;
|
||||||
|
static const uint32_t initrd_size = (uint32_t)_binary_initrd_img_size;
|
||||||
|
|
||||||
|
static const char *initrd_sig = "!<arch>\n";
|
||||||
|
|
||||||
|
uint8_t initrd_validate(void)
|
||||||
|
{
|
||||||
|
initrd_header *header = (initrd_header *)initrd_start;
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
if (header->signature[i] != initrd_sig[i])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t initrd_nametest(char *file, const char *want)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < 16; i++) {
|
||||||
|
if (want[i] == '\0')
|
||||||
|
return (file[i] == '/');
|
||||||
|
else if (want[i] != file[i])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t pow10(uint8_t n)
|
||||||
|
{
|
||||||
|
uint32_t i = 1;
|
||||||
|
while (n--)
|
||||||
|
i *= 10;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t initrd_getsize(initrd_file *file)
|
||||||
|
{
|
||||||
|
uint32_t size = 0;
|
||||||
|
char *p = file->size + 10;
|
||||||
|
while (*--p == ' ');
|
||||||
|
|
||||||
|
for (int8_t i = p - file->size, j = 0; i >= 0; i--, j++)
|
||||||
|
size += (*p-- - '0') * pow10(j);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
initrd_file *initrd_getfileptr(const char *name)
|
||||||
|
{
|
||||||
|
initrd_file *file = (initrd_file *)(initrd_start + sizeof(initrd_header));
|
||||||
|
uint32_t offset = sizeof(initrd_header);
|
||||||
|
|
||||||
|
while (offset < initrd_size) {
|
||||||
|
if (initrd_nametest(file->name, name))
|
||||||
|
return file;
|
||||||
|
uint32_t size = initrd_getsize(file) + sizeof(initrd_file);
|
||||||
|
offset += size;
|
||||||
|
file += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *initrd_getfile(const char *name)
|
||||||
|
{
|
||||||
|
initrd_file *file = initrd_getfileptr(name);
|
||||||
|
if (file == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
char *ptr = (char *)((void *)file + sizeof(initrd_file));
|
||||||
|
ptr[initrd_getsize(file) - 1] = 0;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t initrd_getfilesize(const char *name)
|
||||||
|
{
|
||||||
|
initrd_file *file = initrd_getfileptr(name);
|
||||||
|
if (file == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return initrd_getsize(file);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,117 @@
|
|||||||
|
#include <lcd.h>
|
||||||
|
#include <clock.h>
|
||||||
|
#include <gpio.h>
|
||||||
|
|
||||||
|
#define LCD_D0 GPIO_PORT(A, 0)
|
||||||
|
#define LCD_D1 GPIO_PORT(A, 1)
|
||||||
|
#define LCD_D2 GPIO_PORT(A, 4)
|
||||||
|
#define LCD_D3 GPIO_PORT(B, 0)
|
||||||
|
#define LCD_D4 GPIO_PORT(C, 1)
|
||||||
|
#define LCD_D5 GPIO_PORT(C, 0)
|
||||||
|
#define LCD_D6 GPIO_PORT(C, 2)
|
||||||
|
#define LCD_D7 GPIO_PORT(C, 3)
|
||||||
|
#define LCD_E GPIO_PORT(C, 12)
|
||||||
|
#define LCD_RS GPIO_PORT(C, 10)
|
||||||
|
|
||||||
|
#define lcd_data() gpio_dout(LCD_RS, 1)
|
||||||
|
|
||||||
|
void lcd_pulse(void)
|
||||||
|
{
|
||||||
|
gpio_dout(LCD_E, 1);
|
||||||
|
delay(1);
|
||||||
|
gpio_dout(LCD_E, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_byte(uint8_t byte)
|
||||||
|
{
|
||||||
|
gpio_dout(LCD_D0, byte & 0x01);
|
||||||
|
gpio_dout(LCD_D1, byte & 0x02);
|
||||||
|
gpio_dout(LCD_D2, byte & 0x04);
|
||||||
|
gpio_dout(LCD_D3, byte & 0x08);
|
||||||
|
gpio_dout(LCD_D4, byte & 0x10);
|
||||||
|
gpio_dout(LCD_D5, byte & 0x20);
|
||||||
|
gpio_dout(LCD_D6, byte & 0x40);
|
||||||
|
gpio_dout(LCD_D7, byte & 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_cmd(uint8_t cmd)
|
||||||
|
{
|
||||||
|
gpio_dout(LCD_RS, 0);
|
||||||
|
lcd_byte(cmd);
|
||||||
|
lcd_pulse();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_putchar(int c)
|
||||||
|
{
|
||||||
|
lcd_data();
|
||||||
|
lcd_byte((uint8_t)c);
|
||||||
|
lcd_pulse();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcd_index = 0;
|
||||||
|
void lcd_puts(const char *s)
|
||||||
|
{
|
||||||
|
lcd_cmd(0x06);
|
||||||
|
while (*s) {
|
||||||
|
lcd_putchar(*s++);
|
||||||
|
if (++lcd_index == 0x10) {
|
||||||
|
lcd_cmd(0x80 | 0x40);
|
||||||
|
} else if (lcd_index == 0x20) {
|
||||||
|
lcd_cmd(0x80);
|
||||||
|
lcd_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char *itoa(int n, int base);
|
||||||
|
void lcd_puti(int i)
|
||||||
|
{
|
||||||
|
lcd_puts(itoa(i, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_puth(int h)
|
||||||
|
{
|
||||||
|
lcd_puts(itoa(h, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_putb(uint8_t b)
|
||||||
|
{
|
||||||
|
lcd_puts(itoa(b, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_clear(void)
|
||||||
|
{
|
||||||
|
lcd_cmd(0x01);
|
||||||
|
delay(2);
|
||||||
|
lcd_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_init(void)
|
||||||
|
{
|
||||||
|
gpio_mode(LCD_D0, OUTPUT);
|
||||||
|
gpio_mode(LCD_D1, OUTPUT);
|
||||||
|
gpio_mode(LCD_D2, OUTPUT);
|
||||||
|
gpio_mode(LCD_D3, OUTPUT);
|
||||||
|
gpio_mode(LCD_D4, OUTPUT);
|
||||||
|
gpio_mode(LCD_D5, OUTPUT);
|
||||||
|
gpio_mode(LCD_D6, OUTPUT);
|
||||||
|
gpio_mode(LCD_D7, OUTPUT);
|
||||||
|
gpio_mode(LCD_E, OUTPUT);
|
||||||
|
gpio_mode(LCD_RS, OUTPUT);
|
||||||
|
gpio_dout(LCD_D0, 0);
|
||||||
|
gpio_dout(LCD_D1, 0);
|
||||||
|
gpio_dout(LCD_D2, 0);
|
||||||
|
gpio_dout(LCD_D3, 0);
|
||||||
|
gpio_dout(LCD_D4, 0);
|
||||||
|
gpio_dout(LCD_D5, 0);
|
||||||
|
gpio_dout(LCD_D6, 0);
|
||||||
|
gpio_dout(LCD_D7, 0);
|
||||||
|
gpio_dout(LCD_E, 0);
|
||||||
|
gpio_dout(LCD_RS, 0);
|
||||||
|
|
||||||
|
lcd_cmd(0x38);
|
||||||
|
lcd_cmd(0x10);
|
||||||
|
lcd_cmd(0x0D);
|
||||||
|
delay(5);
|
||||||
|
lcd_clear();
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
#include <stm32l476xx.h>
|
||||||
|
#include <clock.h>
|
||||||
|
#include <heap.h>
|
||||||
|
#include <task.h>
|
||||||
|
#include <gpio.h>
|
||||||
|
#include <lcd.h>
|
||||||
|
#include <initrd.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accomplishments:
|
||||||
|
* - GPIO in/out
|
||||||
|
* - got to 80MHz clock
|
||||||
|
* - basic heap
|
||||||
|
* - multitask, can exit
|
||||||
|
* - gpio lib
|
||||||
|
* - lcd support
|
||||||
|
* - initrd support
|
||||||
|
* - lua?
|
||||||
|
*/
|
||||||
|
|
||||||
|
void pulse(uint8_t byte);
|
||||||
|
void kmain(void);
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
asm("cpsid i");
|
||||||
|
|
||||||
|
// prepare flash latency for 40MHz operation
|
||||||
|
FLASH->ACR &= ~(FLASH_ACR_LATENCY);
|
||||||
|
FLASH->ACR |= FLASH_ACR_LATENCY_4WS;
|
||||||
|
|
||||||
|
//MPU->CTRL |= MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;
|
||||||
|
clock_init();
|
||||||
|
gpio_init();
|
||||||
|
|
||||||
|
gpio_mode(GPIOA, 5, OUTPUT);
|
||||||
|
|
||||||
|
task_init(kmain);
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void task(void);
|
||||||
|
void kmain(void)
|
||||||
|
{
|
||||||
|
asm("cpsie i");
|
||||||
|
|
||||||
|
lcd_init();
|
||||||
|
|
||||||
|
char *s = initrd_getfile("test.txt");
|
||||||
|
lcd_puts(s);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void _exit(int code)
|
||||||
|
{
|
||||||
|
(void)code;
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *itoa(int n, int base)
|
||||||
|
{
|
||||||
|
static char buf[16];
|
||||||
|
char *p = buf + 15;
|
||||||
|
*p = '\0';
|
||||||
|
do *--p = "0123456789ABCDEF"[n % base];
|
||||||
|
while (n /= base);
|
||||||
|
return p;
|
||||||
|
}
|
Loading…
Reference in New Issue