嵌入式(C工程与寄存器封装)

1、在main函数执行之前先运行启动文件(汇编):初始化系统的异常向量表以及各个模式对用的栈。

2、链接脚本文件作用:告诉编译器代码的分布以及起始地址

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
        . = 0x40008000;
        . = ALIGN(4);
        .text      :
        {
                start/start.o(.text)
                *(.text)
        }
        . = ALIGN(4);
    .rodata :
        { *(.rodata) }
    . = ALIGN(4);
    .data :
        { *(.data) }
    . = ALIGN(4);
    .bss :
    { *(.bss) }
}

启动文件

.text
.global _start
_start:
        /*
         * Vector table
         */
        b reset
        b .
        b .
        b .
        b .
        b .
        b .
        b .

reset:
        /*
         * Set vector address in CP15 VBAR register
         */
        ldr     r0, =_start
        mcr     p15, 0, r0, c12, c0, 0  @Set VBAR

        /*
         * Set the cpu to SVC32 mode, Disable FIQ/IRQ
         */
          mrs r0, cpsr
          bic r0, r0, #0x1f
          orr     r0, r0, #0xd3
          msr     cpsr ,r0
  
          /*
          * Defines access permissions for each coprocessor
           */
         mov r0, #0xfffffff
         mcr p15, 0, r0, c1, c0, 2
  
          /*
           * Invalidate L1 I/D                                                                                                                       
           */
         mov     r0, #0                  @Set up for MCR
         mcr     p15, 0, r0, c8, c7, 0   @Invalidate TLBs
         mcr     p15, 0, r0, c7, c5, 0   @Invalidate icache
  
          /*
           * Set the FPEXC EN bit to enable the FPU
           */
          mov r3, #0x40000000
          fmxr FPEXC, r3
         /*
           * Disable MMU stuff and caches
           */
          mrc     p15, 0, r0, c1, c0, 0
          bic     r0, r0, #0x00002000             @Clear bits 13 (--V-)
          bic     r0, r0, #0x00000007             @Clear bits 2:0 (-CAM)
          orr     r0, r0, #0x00001000             @Set bit 12 (---I) Icache
          orr     r0, r0, #0x00000002             @Set bit 1 (--A-) Align
          orr     r0, r0, #0x00000800             @Set bit 11 (Z---) BTB
          mcr     p15, 0, r0, c1, c0, 0
  
          /*
           * Initialize stacks                                                                                                                      
           */
  init_stack:
          /*svc mode stack*/
          msr cpsr, #0xd3
          ldr sp, _stack_svc_end
  
          /*undef mode stack*/
          msr cpsr, #0xdb
          ldr sp, _stack_und_end
         /*abort mode stack*/
          msr cpsr,#0xd7
          ldr sp,_stack_abt_end
  
          /*irq mode stack*/
          msr cpsr,#0xd2
          ldr sp, _stack_irq_end
  
          /*fiq mode stack*/
          msr cpsr,#0xd1
          ldr sp, _stack_fiq_end
  
          /*user mode stack, enable FIQ/IRQ*/
          msr cpsr,#0x10
          ldr sp, _stack_usr_end
  
          /*Call main*/
          b main
  
  _stack_svc_end:
          .word stack_svc + 512
  _stack_und_end:
          .word stack_und + 512
  _stack_abt_end:
          .word stack_abt + 512
  _stack_irq_end:
      .word stack_irq + 512
  _stack_fiq_end:
     .word stack_fiq + 512
  _stack_usr_end:
     .word stack_usr + 512
 
  .data
  stack_svc:
          .space 512
  stack_und:
          .space 512
  stack_abt:
          .space 512
  stack_irq:
          .space 512
  stack_fiq:
          .space 512
  stack_usr:
          .space 512

Makefile

#=============================================================================#
NAME = interface
CROSS_COMPILE = arm-none-linux-gnueabi-
#=============================================================================#
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
OBJDUMP = $(CROSS_COMPILE)objdump
OBJCOPY = $(CROSS_COMPILE)objcopy
CFLAGS  += -g -O0 -mabi=apcs-gnu -mfpu=neon -mfloat-abi=softfp -fno-builtin \
		   -nostdinc -I ./common/include      		                                       
#============================================================================#
OBJSss  := $(wildcard start/*.S) $(wildcard common/src/*.S) $(wildcard *.S) \
		   $(wildcard start/*.c) $(wildcard common/src/*.c) 			    \
		   $(wildcard usr/*.c) $(wildcard *.c) 
OBJSs  	:= $(patsubst %.S,%.o,$(OBJSss))
OBJS 	:= $(patsubst %.c,%.o,$(OBJSs))
#============================================================================#
%.o: %.S
	$(CC) $(CFLAGS) -c -o $@ $<
%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<
all:clean $(OBJS)
	$(LD) $(OBJS) -T map.lds -o $(NAME).elf
	$(OBJCOPY) -O binary  $(NAME).elf $(NAME).bin 
	$(OBJDUMP) -D $(NAME).elf > $(NAME).dis 
#============================================================================#
clean:
	rm -rf $(OBJS) *.elf *.bin *.dis *.o
#============================================================================#

点灯c代码

/*
 * 一.汇编语言访问存储器
 * 	1.读存储器
 * 		LDR R1,[R2]
 * 	2.写存储器
 * 		STR R1,[R2]
 * 二.C语言访问存储器
 * 	1.读存储器
 * 		data = *ADDR
 * 	2.写存储器
 * 	 	*ADDR = data
 */

void Delay(unsigned int Time)
{
	while(Time --);
}

#if 0
int main()
{
	/*通过设置GPX2CON寄存器来将GPX2_7引脚设置成输出功能*/
	*(unsigned int *)0x11000c40 = 0x10000000;  //要强转成4字节才能是一个地址
	while(1)
	{
		/*点亮LED2*/
		*(unsigned int *)0x11000c44 = 0x00000080;
		/*延时*/
		Delay(1000000);
		/*熄灭LED2*/
		*(unsigned int *)0x11000c44 = 0x00000000;
		/*延时*/
		Delay(1000000);
	}
	return 0;
}
#endif

#if 0
#define GPX2CON (*(unsigned int *)0x11000c40)  
#define GPX2DAT (*(unsigned int *)0x11000c44)

int main()
{
	GPX2CON = 0x10000000;

	while(1)
	{
		/*点亮LED2*/
		GPX2DAT = 0x00000080;
		/*延时*/
		Delay(1000000);
		/*熄灭LED2*/
		GPX2DAT = 0x00000000;
		/*延时*/
		Delay(1000000);
	}
	return 0;
}
#endif

#if 0
typedef struct
{
	unsigned int CON;
	unsigned int DAT;
	unsigned int PUD;
	unsigned int DRV;
}gpx2;

#define GPX2 (*(gpx2 *)0x11000c40)

int main()
{
	GPX2.CON = 0x10000000;

	while(1)
	{
		/*点亮LED2*/
		GPX2.DAT = 0x00000080;
		/*延时*/
		Delay(1000000);
		/*熄灭LED2*/
		GPX2.DAT = 0x00000000;
		/*延时*/
		Delay(1000000);
	}
	return 0;
}
#endif

#if 0
#include "exynos_4412.h"

int main()
{
	GPX2.CON = 0x10000000;

	while(1)
	{
		/*点亮LED2*/
		GPX2.DAT = 0x00000080;
		/*延时*/
		Delay(1000000);
		/*熄灭LED2*/
		GPX2.DAT = 0x00000000;
		/*延时*/
		Delay(1000000);
	}
	return 0;
}
#endif


#include "exynos_4412.h"

int main()
{
	GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);

	while(1)
	{
		/*点亮LED2*/
		GPX2.DAT = GPX2.DAT | (1 << 7);
		/*延时*/
		Delay(1000000);
		/*熄灭LED2*/
		GPX2.DAT = GPX2.DAT & (~(1 << 7));
		/*延时*/
		Delay(1000000);
	}
	return 0;
}

/*
 * 1.unsigned int a; 将a的第3位置1,其他位保持不变
 * 	******** ******** ******** ********
 * 	******** ******** ******** ****1***
 * 	00000000 00000000 00000000 00001000
 *
 * 	a = a | (1 << 3);
 *
 * 2.unsigned int a; 将a的第3位置0,其他位保持不变
 * 	******** ******** ******** ********
 * 	******** ******** ******** ****0***
 * 	11111111 11111111 11111111 11110111
 *
 * 	a = a & (~(1 << 3));
 *
 * 	3.unsigned int a; 将a的第[7:4]位置为0101,其他位保持不变
 * 	******** ******** ******** ********
 * 	******** ******** ******** 0101****
 *
 * 	1).先清零
 * 	11111111 11111111 11111111 00001111
 * 	00000000 00000000 00000000 11110000
 *  00000000 00000000 00000000 00001111
 *
 * 	a = a & (~(0xF << 4));
 *
 * 	2).再置位
 * 	00000000 00000000 00000000 01010000
 * 	00000000 00000000 00000000 00000101
 *
 * 	a = a | (0x5 << 4);
 *
 * 	=> a = a & (~(0xF << 4)) | (0x5 << 4);
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式学习者。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值