s5p6818裸机程序的设计:以GPIO为例

为了调试方便,首先确保对于硬件的控制没有问题。

Makefile

#         Makefile edited by Schips
#         2019-06-21 schips@dingtalk.com

# 文件类型
PSFS        =.c

# 源文件所在目录
SRC_LIST    = .
# 头文件所在目录
INCLUDE        = . inc

# 编译选项
CFLAGS        = -nostdlib -O3 

# 库路径
LDLIBS        =

# 库名
LIBS         =

# 输出文件名
TGT         = demo
OTHER_CSRC  = 
OTHER_ASRC  = 
ASRC        = 

########################################
# 不需要改动
INC_P = -I 
LIBD_P = -L 
LIB_P = -l
CFLAGS      += $(addprefix $(INC_P), $(INCLUDE)) 
LDFLAGS     += $(addprefix $(LIBD_P), $(LDLIBS)) 
LIB_ALL     += $(addprefix $(LIB_P), $(LIBS)) 
SRC_LIST    ?= .
SRCSS        += $(addsuffix /*$(PSFS), $(SRC_LIST)) 
CSRC        += $(wildcard  $(SRCSS))

OBJS        = $(CSRC:$(PSFS)=.o) $(ASRC:.S=.o)
NOLINK_OBJS = $(OTHER_CSRC:$(PSFS)=.o) $(OTHER_ASRC:.S=.o)
DEPS        = $(OBJS:.o=.d) $(NOLINK_OBJS:.o=.d)
BIN         = $(TGT)

.PHONY: clean all

all: $(BIN)

$(BIN): $(OBJS) $(NOLINK_OBJS)
    @arm-none-linux-gnueabi-ld -Ttext 0x40000000 -o $@.elf $^
    @arm-none-linux-gnueabi-objcopy -O binary $@.elf $@.bin
    @arm-none-linux-gnueabi-objdump -D $@.elf > $@.dis    

clean:
    @rm -f $(DEPS)
    @rm -f $(OBJS) $(NOLINK_OBJS) 
    @rm *.o *.elf *.bin *.dis -f

# ---------------------------------------------------------------------------
# rules for code generation
# ---------------------------------------------------------------------------
%.o:    %$(PSFS)
    @arm-none-linux-gnueabi-gcc -o $@ $< -c $(CFLAGS)

%.o:    %.S
    @arm-none-linux-gnueabi-gcc -o $@ $< -c -nostdlib

# ---------------------------------------------------------------------------
#  # compiler generated dependencies
# ---------------------------------------------------------------------------
-include $(LWOS_DEPS) $(PORT_DEPS) $(APPL_DEPS)

 示例代码

/*
#    schips@dingtalk.com
#    https://gitee.com/schips/
#    Thu 18 Jul 2019 03:33:59 PM HKT
*/

#if 1
#define TO_ADDR(addr, pos)   (*((volatile unsigned int *)((addr)+ (pos))))
#else
// 测试用(能够直接确定 访问的地址是哪个)
#include <stdio.h>
#define TO_ADDR(addr, pos)   (((volatile unsigned int )((addr)+ (pos))))
#endif

#define SET_BIT(value, bit)     ((value) |= (1 << (bit)))
#define CLR_BIT(value, bit)     ((value) &= ~(1 << (bit)))
#define GET_BIT(value, bit)     ((((value)>>(bit)) &  0x01)==1)
#define SET_BYTE(value, byte)   ((value)  |=  (byte))
#define CLR_BYTE(value, byte)   ((value)  &= ~(byte))
#define GET_BYTE(value, byte)   (((value) &  (byte)) == (byte) )

#define GPIO_A_BASE 0xC001a000
#define GPIO_B_BASE 0xC001b000
#define GPIO_C_BASE 0xC001c000
#define GPIO_D_BASE 0xC001d000
#define GPIO_E_BASE 0xC001e000

#define POS_GPIO_OUT        0x00
#define POS_GPIO_ENB        0x04
#define POS_GPIO_ALTFEN0    0x20
#define POS_GPIO_ALTFEN1    0x24

#define GPIO_A_OUT TO_ADDR(GPIO_A_BASE, POS_GPIO_OUT)
#define GPIO_B_OUT TO_ADDR(GPIO_B_BASE, POS_GPIO_OUT)
#define GPIO_C_OUT TO_ADDR(GPIO_C_BASE, POS_GPIO_OUT)
#define GPIO_D_OUT TO_ADDR(GPIO_D_BASE, POS_GPIO_OUT)
#define GPIO_E_OUT TO_ADDR(GPIO_E_BASE, POS_GPIO_OUT)

#define GPIO_A_OUTENB  TO_ADDR(GPIO_A_BASE, POS_GPIO_ENB)
#define GPIO_B_OUTENB  TO_ADDR(GPIO_B_BASE, POS_GPIO_ENB)
#define GPIO_C_OUTENB  TO_ADDR(GPIO_C_BASE, POS_GPIO_ENB)
#define GPIO_D_OUTENB  TO_ADDR(GPIO_D_BASE, POS_GPIO_ENB)
#define GPIO_E_OUTENB  TO_ADDR(GPIO_E_BASE, POS_GPIO_ENB)
//( 0 ~ 15 )
#define GPIO_A_ALTFN0  TO_ADDR(GPIO_A_BASE, POS_GPIO_ALTFEN0)
#define GPIO_B_ALTFN0  TO_ADDR(GPIO_B_BASE, POS_GPIO_ALTFEN0)
#define GPIO_C_ALTFN0  TO_ADDR(GPIO_C_BASE, POS_GPIO_ALTFEN0)
#define GPIO_D_ALTFN0  TO_ADDR(GPIO_D_BASE, POS_GPIO_ALTFEN0)
#define GPIO_E_ALTFN0  TO_ADDR(GPIO_E_BASE, POS_GPIO_ALTFEN0)
// (16 ~ 31)
#define GPIO_A_ALTFN1  TO_ADDR(GPIO_A_BASE, POS_GPIO_ALTFEN1)
#define GPIO_B_ALTFN1  TO_ADDR(GPIO_B_BASE, POS_GPIO_ALTFEN1)
#define GPIO_C_ALTFN1  TO_ADDR(GPIO_C_BASE, POS_GPIO_ALTFEN1)
#define GPIO_D_ALTFN1  TO_ADDR(GPIO_D_BASE, POS_GPIO_ALTFEN1)
#define GPIO_E_ALTFN1  TO_ADDR(GPIO_E_BASE, POS_GPIO_ALTFEN1)
/*
//OK
*(volatile unsigned int *)(0xC001e000) &= ~(1<<13);
GPIO_E_OUT |= (1<<13);
*(volatile unsigned int *)(0xC001e000) |=  (1<<13);
*/

void delay(int val);


void _start(void)
{
    CLR_BYTE(GPIO_E_ALTFN0, 3 << (13*2));

    SET_BIT(GPIO_E_OUTENB, 13);
   
    while(1)
    {
        SET_BIT(GPIO_E_OUT, 13);
        delay(0x4000000); 

        CLR_BIT(GPIO_E_OUT, 13);
        delay(0x4000000); 
    }
}

void delay(int val)
{
    volatile int i = val;
    while(i--);
    
}

#if 0
int main(int argc, char *argv[])
{
    int i  = 0xf0;
    printf("%x[%d] : %d
", i, 0, GET_BIT(i, 0));
    i = SET_BIT(i, 0);
    printf("%x
", i);

    printf("%x[%d] : %d
", i, 0, GET_BIT(i, 0));
    i = CLR_BIT(i, 0);
    printf("%x
", i);
    printf("%x[%d] : %d
", i, 7, GET_BIT(i, 7));
    return 0;
    printf("GPIO_E_BASE   	%x
", GPIO_E_BASE  );
    printf("GPIO_A_OUT    	%x
", GPIO_A_OUT   );
    printf("GPIO_C_OUTENB 	%x
", GPIO_C_OUTENB);
    printf("GPIO_D_ALTFN0 	%x
", GPIO_D_ALTFN0);
    printf("GPIO_B_ALTFN1 	%x
", GPIO_B_ALTFN1);
 
    return 0;
}
#endif

烧写方式

  软件通过uboot的tftp命令传入。由于uboot本身的问题,导致ftfp命令需要输入至少2次才能够正常工作。

  tftp以后到指定的地址 使用go命令即可

原文地址:https://www.cnblogs.com/schips/p/11213945.html