linux内核ddr初始化,嵌入式Linux裸机开发(五)——SDRAM初始化

嵌入式Linux裸机开发(五)——SDRAM初始化

一、SDRAM初始化流程

S5PV210有两个独立的DRAM控制器,一个最大支持512MB,一个最大支持1024MB,但两个控制器必须支持相同类型的内存。

根据三星S5PV210文档可知,DDR2类型内存的初始化流程如下:

1、提供稳压电源给内存控制器和内存芯片,内存控制器必须保持CLE在低电平,此时就会提供稳压电源。注:当CKE引脚为低电平时,XDDR2SEL应该处于高电平

2、根据时钟频率正确配置PhyControl0.ctrl_start_point和PhyControl0.ctrl_inc的值。配置的PhyControl0.ctrl_dll_on值为'1'以打开PHY DLL。

3、数据选取脉DQS清除:依照时钟频率和内存的tAC参数正确设置PhyControl1.ctrl_shiftc和PhyControl1.ctrl_offsetcbit位的值。

4、设置PhyControl0.ctrl_start位的值为'1'

5、设置ConControl,同时关闭auto refresh自动刷新计数器

6、设置MemControl,同时关闭所有的power down(休眠模式)。

7、设置MemConfig0寄存器。如果有两组内存芯片(比如有8片DDR,这8片DDR是分别挂在Memory Port1和Memory Port2上),再配置MemConfig1寄存器。

8、设置PrechConfig和PwrdnConfig寄存器

9、根据内存的tAC参数设置TimingAref,TimingRow, TimingData和TimingPower寄存器

10、如果需要QoS标准,配置QosControl0—15和QosConfig0-15寄存器

11、等待PhyStatus0.ctrl_locked位变为'1'。检查是否PHY DLL是否已锁

12、PHY DLL补偿在内存操作时由PVT(Process, Voltage and Temperature,处理器、电压和温度)变化引起的延迟量。但是,PHY DLL不能因某些可靠的内存操作而切断,除非是工作在低频率下。如果关闭PHY DLL,依照PhyStatus0.ctrl_lock_value[9:2]位的值正确配置PhyControl0.ctrl_force位的值来弥补延迟量(fix delay amount)。清除PhyControl0.ctrl_dll_on位的值来关闭PHY DLL。

13、上电后,确定最小值为200us的稳定时钟是否发出

14、使用DirectCmd寄存器发出一个NOP命令,保证CKE引脚为高电平

15、等最小400ns

16、使用DirectCmd寄存器发出一个PALL命令

17、使用DirectCmd寄存器发出一个EMRS2命令,program操作参数

18、使用DirectCmd寄存器发出一个EMRS3命令,program操作参数

19、使用DirectCmd寄存器发出一个EMRS命令来使能内存DLLs

20、使用DirectCmd寄存器发出一个MRS命令,重启内存DLL

21、使用DirectCmd寄存器发出一个PALL命令

22、使用DirectCmd寄存器发出两个Auto Refresh(自动刷新)命令

23、使用DirectCmd寄存器发出一个MRS命令,program操作参数,不要重启内存DLL

24、等待最小200时钟周期

25、使用DirectCmd寄存器发出一个EMRS命令给程序的运行参数。如果OCD校正(Off-Chip Driver,片外驱动调校)没有使用,改善一个EMRS命令去设置OCD校准的默认值。在此之后,发送一个EMRS指令去退出OCD校准模式,继续program操作参数

26、如果有两组DDR芯片,重复14-25步配置chip1的内存,刚刚配置的是chip0,也就是第一组内存芯片

27、配置ConControlto来打开自动刷新计数器

28、如果需要power down(休眠)模式,配置MemControl寄存器。

二、电路原理图解读

查阅核心板电路原理图,找到DDR相关部分,S5PV210有两个内存端口,分别为DRAM0和DRAM1,对应地址范围如下:

DRAM0:0x20000000——0x3FFFFFFF512MB

DRAM1:0x40000000——0x7FFFFFFF1024MB

d65e8201df657bc0328d3f2005b2e5e7.png

Smart210开发板共有四片128MB的内存芯片,每片芯片有14根地址线Xm1ADDR[13:0],8根数据线Xm1DATA[7:0],其余为控制总线。

7e225e600308656f0a9dcea8103e1567.png

四片内存芯片并联后逻辑上只是一片内存芯片,大小为512MB,数据线为Xm1DATA[31:0],地址线不变Xm1ADDR[13:0]。根据DRAM原理图的片选引脚nCS、CKE、nWE选择知道,smart210开发板的四片内存芯片挂接到DMC0。

三、SDRAM初始化

sdram_init.S源代码:

#include "s5pv210.h"

// MemControlBL=4, 1Chip, DDR2 Type, dynamic self refresh, force precharge, dynamic power down off

#define DMC0_MEMCONTROL0x00202400

// MemConfig0256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed

#define DMC0_MEMCONFIG_00x20F00313

// MemConfig1

#define DMC0_MEMCONFIG_10x00F00313

// TimingAref   7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E) 200MHZ=0x618

#define DMC0_TIMINGA_REF        0x00000618

// TimingRow    for @200MHz

#define DMC0_TIMING_ROW         0x2B34438A

// TimingData   CL=3

#define DMC0_TIMING_DATA        0x24240000

// TimingPower

#define DMC0_TIMING_PWR         0x0BDC0343

.global sdram_init

sdram_init:

//IO端口驱动强度设置

// 1. 设置DMC0 Drive Strength (Setting 2X)

ldrr0, =ELFIN_GPIO_BASE

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_0DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_1DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_2DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_3DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_4DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_5DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_6DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_7DRV_SR_OFFSET]

ldrr1, =0x00002AAA

strr1, [r0, #MP1_8DRV_SR_OFFSET]

// 2. 初始化PHY DLL

ldrr0, =APB_DMC_0_BASE

//step 3: PhyControl0 DLL parameter setting, manual 0x00101000

ldrr1, =0x00101000

strr1, [r0, #DMC_PHYCONTROL0]

//PhyControl1 DLL parameter setting, LPDDR/LPDDR2 Case

ldrr1, =0x00000086

strr1, [r0, #DMC_PHYCONTROL1]

//step 2: PhyControl0 DLL on

ldrr1, =0x00101002

strr1, [r0, #DMC_PHYCONTROL0]

//step 4: PhyControl0 DLL start

ldrr1, =0x00101003

strr1, [r0, #DMC_PHYCONTROL0]

find_lock_val:

//Loop until DLL is locked

ldrr1, [r0, #DMC_PHYSTATUS]

andr2, r1, #0x7

cmpr2, #0x7

bnefind_lock_val

//Force Value locking

andr1, #0x3fc0

movr2, r1, LSL #18

orrr2, r2, #0x100000

orrr2 ,r2, #0x1000

orrr1, r2, #0x3

strr1, [r0, #DMC_PHYCONTROL0]

// 3. 初始化DMC0

//step 5: ConControl auto refresh off

ldrr1, =0x0FFF2010

strr1, [r0, #DMC_CONCONTROL]

//step 6: MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off

ldrr1, =DMC0_MEMCONTROL

strr1, [r0, #DMC_MEMCONTROL]

//step 7: MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed

ldrr1, =DMC0_MEMCONFIG_0

strr1, [r0, #DMC_MEMCONFIG0]

//MemConfig1

ldrr1, =DMC0_MEMCONFIG_1

strr1, [r0, #DMC_MEMCONFIG1]

//step 8:PrechConfig

ldrr1, =0xFF000000

strr1, [r0, #DMC_PRECHCONFIG]

//step 9:TimingAref7.8us//133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)

ldrr1, =DMC0_TIMINGA_REF

strr1, [r0, #DMC_TIMINGAREF]

//TimingRowfor //200MHz

ldrr1, =DMC0_TIMING_ROW

strr1, [r0, #DMC_TIMINGROW]

//TimingDataCL=4

ldrr1, =DMC0_TIMING_DATA

strr1, [r0, #DMC_TIMINGDATA]

//TimingPower

ldrr1, =DMC0_TIMING_PWR

strr1, [r0, #DMC_TIMINGPOWER]

// 4. 初始化DDR2 DRAM

//DirectCmdchip0 Deselect

ldrr1, =0x07000000//NOP

strr1, [r0, #DMC_DIRECTCMD]

//step 16:DirectCmdchip0 PALL

ldrr1, =0x01000000//

strr1, [r0, #DMC_DIRECTCMD]

//step 17:DirectCmdchip0 EMRS2

ldrr1, =0x00020000

strr1, [r0, #DMC_DIRECTCMD]

//step 18:DirectCmdchip0 EMRS3

ldrr1, =0x00030000

strr1, [r0, #DMC_DIRECTCMD]

//step 19:DirectCmdchip0 EMRS1 (MEM DLL on, DQS# disable)

ldrr1, =0x00010400

strr1, [r0, #DMC_DIRECTCMD]

//step 20:DirectCmdchip0 MRS (MEM DLL reset) CL=4, BL=4

ldrr1, =0x00000542

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 PALL

ldrr1, =0x01000000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 REFA

ldrr1, =0x05000000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 REFA

ldrr1, =0x05000000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 MRS (MEM DLL unreset)

ldrr1, =0x00000442

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 EMRS1 (OCD default)

ldrr1, =0x00010780

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 EMRS1 (OCD exit)

ldrr1, =0x00010400

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 Deselect

ldrr1, =0x07100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 PALL

ldrr1, =0x01100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS2

ldrr1, =0x00120000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS3

ldrr1, =0x00130000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS1 (MEM DLL on, DQS# disable)

ldrr1, =0x00110400

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 MRS (MEM DLL reset) CL=4, BL=4

ldrr1, =0x00100542

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 PALL

ldrr1, =0x01100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 REFA

ldrr1, =0x05100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 REFA

ldrr1, =0x05100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 MRS (MEM DLL unreset)

ldrr1, =0x00100442

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS1 (OCD default)

ldrr1, =0x00110780

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS1 (OCD exit)

ldrr1, =0x00110400

strr1, [r0, #DMC_DIRECTCMD]

//ConControlauto refresh on

ldrr1, =0x0FF02030

strr1, [r0, #DMC_CONCONTROL]

//PwrdnConfig

ldrr1, =0xFFFF00FF

strr1, [r0, #DMC_PWRDNCONFIG]

//MemControlBL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off

ldrr1, =0x00202400

strr1, [r0, #DMC_MEMCONTROL]

movpc, lr

四、重定位至SDRAM实践

程序源码文件包含:

start.S:程序主函数

sdram_init.S:初始化SDRAM的函数

led_blink.c:led闪烁函数

Makefile和link.lds

start.S:

//#define WDTCON0xE2700000

#define SVC_SP0xD0037D80

.global _start

_start:

//C语言运行时栈设置SVC模式下的栈CPU复位后为SVC模式,DRAM尚未初始化,

//只有SRAM可用,0xD0037780,0xD0037D80,大小1.5K

ldr sp,=SVC_SP

//初始化SDRAM

bl sdram_init

//重定位

adr r0,_start//加载_start当前运行地址

ldr r1,=_start//加载_start的链接地址

ldr r2,=bss_start//加载bss段的起始地址

cmp r0,r1//比较运行地址和链接地址是否相等

beq clean_bss//相等则表明不需要重定位

//拷贝text段和data段

copy_loop:

ldr r3,[r0],#4

str r3,[r1],#4

cmp r1,r2

bne copy_loop

//清除bss段满足C语言运行时要求,编译器会负责清除bss段,

//编译器清除了运行时地址的bss段,链接地址的bss段未清除

clean_bss:

ldr r0,=bss_start

ldr r1,=bss_end

cmp r0,r1

beq run_on_dram//相等则bss为空

mov r2,#0

clear_loop:

str r2,[r0],#4//现将r2放入r0的值对应的内存地址中,然后r0=r0+4

cmp r0,r1

bne clear_loop

run_on_dram:

ldr pc,=led_blink

.end

sdram_init.S源码:

#include "s5pv210.h"

// MemControlBL=4, 1Chip, DDR2 Type, dynamic self refresh, force precharge, dynamic power down off

#define DMC0_MEMCONTROL0x00202400

// MemConfig0256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed

#define DMC0_MEMCONFIG_00x20F00313

// MemConfig1

#define DMC0_MEMCONFIG_10x00F00313

// TimingAref   7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)

#define DMC0_TIMINGA_REF        0x00000618

// TimingRow    for @200MHz

#define DMC0_TIMING_ROW         0x2B34438A

// TimingData   CL=3

#define DMC0_TIMING_DATA        0x24240000

// TimingPower

#define DMC0_TIMING_PWR         0x0BDC0343

.globl sdram_init

sdram_init:

// 1. 设置DMC0 Drive Strength (Setting 2X)

ldrr0, =ELFIN_GPIO_BASE

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_0DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_1DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_2DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_3DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_4DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_5DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_6DRV_SR_OFFSET]

ldrr1, =0x0000AAAA

strr1, [r0, #MP1_7DRV_SR_OFFSET]

ldrr1, =0x00002AAA

strr1, [r0, #MP1_8DRV_SR_OFFSET]

// 2. 初始化PHY DLL

ldrr0, =APB_DMC_0_BASE

//step 3: PhyControl0 DLL parameter setting, manual 0x00101000

ldrr1, =0x00101000

strr1, [r0, #DMC_PHYCONTROL0]

//PhyControl1 DLL parameter setting, LPDDR/LPDDR2 Case

ldrr1, =0x00000086

strr1, [r0, #DMC_PHYCONTROL1]

//step 2: PhyControl0 DLL on

ldrr1, =0x00101002

strr1, [r0, #DMC_PHYCONTROL0]

//step 4: PhyControl0 DLL start

ldrr1, =0x00101003

strr1, [r0, #DMC_PHYCONTROL0]

find_lock_val:

//Loop until DLL is locked

ldrr1, [r0, #DMC_PHYSTATUS]

andr2, r1, #0x7

cmpr2, #0x7

bnefind_lock_val

//Force Value locking

andr1, #0x3fc0

movr2, r1, LSL #18

orrr2, r2, #0x100000

orrr2 ,r2, #0x1000

orrr1, r2, #0x3

strr1, [r0, #DMC_PHYCONTROL0]

// 3. 初始化DMC0

//step 5: ConControl auto refresh off

ldrr1, =0x0FFF2010

strr1, [r0, #DMC_CONCONTROL]

//step 6: MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off

ldrr1, =DMC0_MEMCONTROL

strr1, [r0, #DMC_MEMCONTROL]

//step 7: MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed

ldrr1, =DMC0_MEMCONFIG_0

strr1, [r0, #DMC_MEMCONFIG0]

//MemConfig1

ldrr1, =DMC0_MEMCONFIG_1

strr1, [r0, #DMC_MEMCONFIG1]

//step 8:PrechConfig

ldrr1, =0xFF000000

strr1, [r0, #DMC_PRECHCONFIG]

//step 9:TimingAref7.8us//133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)

ldrr1, =DMC0_TIMINGA_REF

strr1, [r0, #DMC_TIMINGAREF]

//TimingRowfor //200MHz

ldrr1, =DMC0_TIMING_ROW

strr1, [r0, #DMC_TIMINGROW]

//TimingDataCL=4

ldrr1, =DMC0_TIMING_DATA

strr1, [r0, #DMC_TIMINGDATA]

//TimingPower

ldrr1, =DMC0_TIMING_PWR

strr1, [r0, #DMC_TIMINGPOWER]

// 4. 初始化DDR2 DRAM

//DirectCmdchip0 Deselect

ldrr1, =0x07000000

strr1, [r0, #DMC_DIRECTCMD]

//step 16:DirectCmdchip0 PALL

ldrr1, =0x01000000

strr1, [r0, #DMC_DIRECTCMD]

//step 17:DirectCmdchip0 EMRS2

ldrr1, =0x00020000

strr1, [r0, #DMC_DIRECTCMD]

//step 18:DirectCmdchip0 EMRS3

ldrr1, =0x00030000

strr1, [r0, #DMC_DIRECTCMD]

//step 19:DirectCmdchip0 EMRS1 (MEM DLL on, DQS# disable)

ldrr1, =0x00010400

strr1, [r0, #DMC_DIRECTCMD]

//step 20:DirectCmdchip0 MRS (MEM DLL reset) CL=4, BL=4

ldrr1, =0x00000542

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 PALL

ldrr1, =0x01000000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 REFA

ldrr1, =0x05000000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 REFA

ldrr1, =0x05000000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 MRS (MEM DLL unreset)

ldrr1, =0x00000442

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 EMRS1 (OCD default)

ldrr1, =0x00010780

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip0 EMRS1 (OCD exit)

ldrr1, =0x00010400

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 Deselect

ldrr1, =0x07100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 PALL

ldrr1, =0x01100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS2

ldrr1, =0x00120000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS3

ldrr1, =0x00130000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS1 (MEM DLL on, DQS# disable)

ldrr1, =0x00110400

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 MRS (MEM DLL reset) CL=4, BL=4

ldrr1, =0x00100542

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 PALL

ldrr1, =0x01100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 REFA

ldrr1, =0x05100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 REFA

ldrr1, =0x05100000

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 MRS (MEM DLL unreset)

ldrr1, =0x00100442

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS1 (OCD default)

ldrr1, =0x00110780

strr1, [r0, #DMC_DIRECTCMD]

//DirectCmdchip1 EMRS1 (OCD exit)

ldrr1, =0x00110400

strr1, [r0, #DMC_DIRECTCMD]

//ConControlauto refresh on

ldrr1, =0x0FF02030

strr1, [r0, #DMC_CONCONTROL]

//PwrdnConfig

ldrr1, =0xFFFF00FF

strr1, [r0, #DMC_PWRDNCONFIG]

//MemControlBL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off

ldrr1, =0x00202400

strr1, [r0, #DMC_MEMCONTROL]

movpc, lr

led_blink.c源码:

#define rGPJ2CON (*((volatile unsigned int *)0xE0200280))

#define rGPJ2DAT (*((volatile unsigned int *)0xE0200284))

void led_blink(void);

void delay(void);

void led_blink(void)

{

rGPJ2CON = 0x00001111;//设置led1--led4为output

rGPJ2DAT = (0<<0 | 0<<1 | 0<<2 | 0<<3);//点亮led1--led4

delay();//延时

rGPJ2DAT = (1<<0 | 1<<1 | 1<<2 | 1<<3);//熄灭led1--led4

delay();

rGPJ2DAT = (0<<0 | 1<<1 | 1<<2 | 1<<3);//点亮led1

delay();

rGPJ2DAT = (1<<0 | 0<<1 | 1<<2 | 1<<3);//点亮led2

delay();

rGPJ2DAT = (1<<0 | 1<<1 | 0<<2 | 1<<3);//点亮led3

delay();

rGPJ2DAT = (1<<0 | 1<<1 | 1<<2 | 0<<3);//点亮led4

delay();

}

void delay(void)

{

volatile unsigned int i = 0x1FFFFF;

while(i--);

}

Makefile:

OBJS += start.o led_blink.o sdram_init.o

CFLAGS += -Wall -O2

LDFLAGS += -Tlink.lds

CROSS_COMPILER := arm-linux-

CC := $(CROSS_COMPILER)gcc

led.bin: $(OBJS)

$(CROSS_COMPILER)ld -Tlink.lds -o led.elf $^

$(CROSS_COMPILER)objcopy -O binary led.elf led.bin

$(CROSS_COMPILER)objdump -D led.elf > led_elf.dis

gcc mkv210_p_w_picpath.c -o mk210

./mk210 led.bin smart210.bin

%.o:%.c

$(CC) $(CFLAGS) -c $^ -o $@

%.o:%.S

$(CC) $(CFLAGS) -c $^ -o $@

.PHONY = clean

clean:

rm -rf *.o *.elf *.bin *.dis mk210

.PHONY = install

install:

DATE = $(shell date --rfc-3339=date)

.PHONY = dist

dist:

tar -cvf $(BIN)-$(DATE).tar.gz $(BIN)

link.lds:

SECTIONS

{

. = 0x20000000;

.text :

{

start.o

* (.text)

}

.data :

{

* (.data)

}

bss_start = .;

.bss :

{

* (.bss)

}

bss_end = .;

}

烧录后运行结果,led正常闪烁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值