S5PV210
| Bare-metal assembly LED
running water lamp experiment
Article directory
- `S5PV210` | Bare metal assembly `LED` water lamp experiment
Development board:
1. Schematic
POWER
In the figure above, when the button is pressed , the sum andVDD_5V
the voltageVDD_IO
will be generated . There is no need to control it, and it is always on, which is what we call the power indicator light. The corresponding ports are as follows:5V
3.3V
D26
GPIO
D[22:25]
GPIO
LED indicator | GPIO port | serial number | action |
---|---|---|---|
D22 | GPJ_3 | LED1 | 1: Off, 0: On |
D23 | GPJ0_4 | LED2 | 1: Off, 0: On |
D24 | GPJ0_5 | LED3 | 1: Off, 0: On |
D25 | GPD0_1 | LED4 | 1: Off, 0: On |
The corresponding
GPIO
port outputs a low level and lights upLED
; otherwise, turns offLED
the light;
2. Datasheet related
1.S5PV210 RISC微处理器用户手册:
S5PV210_UM_REV1.1.pdf
获取方式:可在CSDN搜索下载,也可以@大飞歌获取
2.应用手册(内部ROM启动):
S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf
获取方式:可网路搜索下载,也可以@大飞歌获取
中文文档地址:https://blog.csdn.net/I_feige/article/details/104848609
3.底板电路原理图:
x210bv3s.pdf
下载链接:https://download.csdn.net/download/i_feige/11877902
Please refer to the following chapters ( ) for the details of the control LED GPIO
register settings S5PV210_UM_REV1.1.pdf
:
V210_ Book cover
errata
section 01_ overview
section 02_ system
section 03_ bus
section 04_ interupt
section 05_ memory
section 06_ dma
section 07_ timer
section 08_ connectivity _ storage
section 09_ mutimedia
section 10_ audio _ etc
section 11_ securty
section 12_ etc
2.2.7 PORT GROUP GPD0 CONTROL REGISTER
2.2.7.1 Port Group GPD0 Control Register ( GPD0CON , R / W , Address 0xE020_00A0)
2.2.7.2 Port Group GPD0 Control Register ( GPD0DAT , R / W , Address 0xE020_00A4)
2.2.7.3 Port Group GPD0 Control Register ( GPD0PUD , R / W , Address 0xE020_00A8)
2.2.7.4 Port Group GPD0 Control Register ( GPD0DRV , R / W , Address 0xE020_00AC)
2.2.7.5 Port Group GPD0 Control Register ( GPD0CONPDN , R / W , Address 0xE020_00B0)
2.2.7.6 Port Group GPD0 Control Register ( GPD0PUDPDN , R / W , Address 0xE020_00B4)
2.2.20 PORT GROUP GPJ0 CONTROL REGISTER
2.2.20.1 Port Group GPJ0 Control Register ( GPJ0CON , R / W , Address 0xE020_0240)
2.2.20.2 Port Group GPJ0 Control Register ( GPJ0DAT , R / W , Address 0xE020_0244)
2.2.20.3 Port Group GPJ0 Control Register ( GPJ0PUD , R / W , Address 0xE020_0248)
2.2.20.4 Port Group GPJ0 Control Register ( GPJ0DRV , R / W , Address 0xE020_024C)
2.2.20.5 Port Group GPJ0 Control Register ( GPJ0CONPDN , R / W , Address 0xE020_0250)
2.2.20.6 Port Group GPJ0 Control Register ( GPJ0PUDPDN , R / W , Address 0xE020_0254)
GPD0
Relevant information of the control register group (some excerpts are as follows):
2.2.7 PORT GROUP GPD0 CONTROL REGISTER
There are six control registers, which are GPD0CON
, GPD0DAT
, GPD0PUD
, GPD0DRV
, GPD0CONPDN
and
port group GPD0
control registers GPD0PUDPDN
.
2.2.7.1 Port Group GPD0
Control Registers ( GPD0CON
, R/W, Address = 0xE020_00A0
)
GPD0CON | Bit | Description | Initial State |
---|---|---|---|
GPD0CON[3] | [15:12] | 0000 = Input 0001 = Output 0010 = TOUT_3 0011 ~ 1110 = Reserved 1111 = GPD0_INT[3] | 0000 |
GPD0CON[2] | [11:8] | 0000 = Input 0001 = Output 0010 = TOUT_2 0011 ~ 1110 = Reserved 1111 = GPD0_INT[2] | 0000 |
GPD0CON[1] | [7:4] | 0000 = Input 0001 = Output 0010 = TOUT_1 0011 ~ 1110 = Reserved 1111 = GPD0_INT[1] | 0000 |
GPD0CON[0] | [3:0] | 0000 = Input 0001 = Output 0010 = TOUT_0 0011 ~ 1110 = Reserved 1111 = GPD0_INT[0] | 0000 |
2.2.7.2 Port Group GPD0
Data Mapping Registers ( GPD0DAT
, R/W, Address = 0xE020_00A4
)
GPD0DAT | Bit | Description | Initial State |
---|---|---|---|
GPD0DAT[3:0] | [3:0] | When a port is configured as an input port, the corresponding bit is the pin state. When the port is configured as an output port, the pin state is the same as the corresponding bit. When the port is configured as a function pin, an undefined value will be read. | 0000 |
2.2.7.3 Port group GPD0
pull-up and pull-down configuration registers ( GPD0PUD
, R/W, Address = 0xE020_00A8
)
GPD0PUD | Bit | Description | Initial State |
---|---|---|---|
GPD0PUD[n] | [2n+1:2n] n=0~3 | 00 = pull-up/pull-down disabled 01 = pull-down enabled 10 = pull-up enabled 11 = reserved | 0x0055 |
2.2.7.4 Port Group GPD0
Drive Strength Configuration Register ( GPD0DRV
, R/W, Address = 0xE020_00AC
)
GPD0DRV | Bit | Description | Initial State |
---|---|---|---|
GPD0DRV[n] | [2n+1:2n] n=0~3 | 00 = 1x 10 = 2x 01 = 3x 11 = 4x | 0x0000 |
2.2.7.5 Port Group GPD0
Low Power Mode Configuration Register ( GPD0CONPDN
, R/W, Address = 0xE020_00B0
)
GPD0CONPDN | Bit | Description | Initial State |
---|---|---|---|
GPD0[n] | [2n+1:2n] n=0~3 | 00 = Output 0 01 = Output 1 10 = Input 11 = Previous state | 0x00 |
2.2.7.6 Port Group GPD0
Low Power Mode Pull-Up/Pull-Down Register ( GPD0PUDPDN
, R/W, Address = 0xE020_00B4
)
GPD0PUDPDN | Bit | Description | Initial State |
---|---|---|---|
GPD0[n] | [2n+1:2n] n=0~3 | 00 = pull-up/pull-down disabled 01 = pull-down enabled 10 = pull-up enabled 11 = reserved | 0x00 |
For example, set GPD0_1
IO
the port to output mode, pull it up or pull it down (assembled language implementation):
#define GPD0CON 0xE02000A0
#define GPD0DAT 0xE02000A4
/* 初始化GPIO口(配置为输出模式),下面是比较规范的一种写法,也可参考代码实现(流水灯)相关部分 */
ldr r0,=GPD0CON //r0=0xE02000A0
ldr r1,[r0] //将r0地址处的数据读出,保存到r1中(零偏移)
orr r1,r1,#0x0010 //设置r1的第4位(置1),其他位保持不变[7:4]->0001=Output
str r1,[r0] //将r1中的内容传输到r0中数指定的地址内存中去
/* 点亮LED4,GPIO口输出低电平 */
ldr r0,=GPD0DAT //r0=0xE02000A4
ldr r1,[r0] //将r0地址处的数据读出,保存到r1中(零偏移)
bic r1,r1,#0x0002 //清除r1的第1位(置0),其他位保持不变[1]
str r1,[r0] //将r1中的内容传输到r0中数指定的地址内存中去
/* 熄灭LED4,GPIO口输出高电平 */
ldr r0,=GPD0DAT //r0=0xE02000A4
ldr r1,[r0] //将r0地址处的数据读出,保存到r1中(零偏移)
orr r1,r1,#0x0002 //设置r1的第1位(置1),其他位保持不变[1]
str r1,[r0] //将r1中的内容传输到r0中数指定的地址内存中去
3. Code
3-1. Code implementation (water lamp, just for demonstration)
/*******************************************************
* > File Name: start.S
* > Author: fly
* > Create Time: 2020年07月17日 星期五 07时56分19秒
******************************************************/
/*=====================================================
* 汇编点亮led灯:对应GPIO口输出低电平,点亮LED
* D22->GPJ0_3
* D23->GPJ0_4
* D24->GPJ0_5
* D25->PWMOUT1/GPD0_1
*====================================================*/
#define GPD0CON 0xE02000A0
#define GPD0DAT 0xE02000A4
#define GPD0PUD 0xE02000A8
#define GPJ0CON 0xE0200240
#define GPJ0DAT 0xE0200244
#define GPJ0PUD 0xE0200248
#define PS_HOLD_CONTORL 0xE010E81C
#define WTCON 0xE2700000
#define SVC_STACK 0xD0037D80
//#define CONFIG_SYS_ICACHE_OFF 1
.global _start
_start:
//给5v电源置锁
//LDR指令:从内存中将1个32位的字读取到目标寄存器中
//STR指令:将1个32位的字数据写入到指令中指定的内存单元中
//ORR指令:逻辑或操作指令
//BIC指令:位清除指令
//MOV指令:数据传送
ldr r0,=PS_HOLD_CONTORL //r0=0xE010E81C
ldr r1,[r0] //将r0地址处的数据读出,保存到r1中(零偏移)
orr r1,r1,#0x300 //设置r1的第8、9位,其他位保持不变
orr r1,r1,#0x1 //设置r1的第1位,其他位保持不变
str r1,[r0] //将r1中的内容传输到r0中数指定的地址内存中去
//关看门狗
ldr r0, =WTCON
mov r1, #0 //将立即数0传输到r1处
str r1, [r0]
//开/关iCache
// MRC指令:从协处理器寄存器传数据到ARM寄存器
// MCR指令:从ARM寄存器传数据到协处理器寄存器
mrc p15, 0, r0, c1, c0, 0
#ifdef CONFIG_SYS_ICACHE_OFF
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-Cache
#else
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
#endif
mcr p15, 0, r0, c1, c0, 0
//设置栈,以便调用c函数
ldr sp, =SVC_STACK
led_init:
/* LED初始化 */
//把GPIO设置输出模式
ldr r0,=0x11111111
ldr r1,=GPJ0CON
str r0, [r1] //把GPJ0所有的IO设置为输出模式
ldr r0,=0x00000010
ldr r1,=GPD0CON
str r0,[r1] //把GPD0_1设置为输出模式
led_run:
/* LED流水灯 */
// 第1步:点亮LED1,其他熄灭
ldr r0, =~(1<<3) //r0=0xFFFFFFF7
ldr r1, =GPJ0DAT //r1=0xE0200244
str r0, [r1]
//熄灭LED4
ldr r0, =~(0<<1) //r0=0xFFFFFFFF
ldr r1, = GPD0DAT
str r0, [r1]
bl delay
// 第2步:点亮LED2,其他熄灭
ldr r0, =~(1<<4) //r0=0xFFFFFFEF
ldr r1, =GPJ0DAT
str r0, [r1]
bl delay
// 第3步:点亮LED3,其他熄灭
ldr r0, =~(1<<5) //r0=0xFFFFFFDF
ldr r1, =GPJ0DAT
str r0, [r1]
bl delay
//熄灭LED3/4/5,点亮LED4
ldr r0, = ((1<<3)|(1<<4)|(1<<5))
ldr r1, =GPJ0DAT
str r0, [r1]
ldr r0, =~(1<<1) //r0=0xFFFFFFFD
ldr r1, = GPD0DAT
str r0, [r1]
bl delay
bl led_run
half:
b half
/* 延时函数:delay*/
delay:
ldr r2,=9000000
ldr r3,=0x0
delay_loop:
//SUB指令:从寄存器Rn中减去shifter_operand表示的数值,
//并将结果保存在目标寄存器Rd中,并根据指令的执行结果
//设置CPSR中的相应标志位
//SUB {<cond>} {s} <Rd>,<Rn>,<shifter_operand>
sub r2,r2,#1 //r2 = r2 - 1
//CMP指令:使用寄存器Rn的值减去shifter_operand的值,
//根据操作的结果更新CPSR中相应的条件标志位,以便后面
//的指令根据相应的条件标志位来判断是否执行
//CMP {<cond>} <Rn>,<shifter_operand>
cmp r2, r3
bne delay_loop
mov pc,lr
Supporting compiled Makefile
files:
# 将所有的.o文件链接成.elf文件,“-Ttext 0x0”
# 表示程序的运行地址是0x0,由于目前编写的是位置
# 无关码,可以在任一地址运行
# 将elf文件抽取为可在开发板上运行的bin文件
# 将elf文件反汇编保存在dis文件中,调试程序会用
# 添加文件头
# 编译器版本:arm-2009q3
.PHONY: all clean tools
CROSS ?= arm-linux-
NAME := LED
LD := $(CROSS)ld
OC := $(CROSS)objcopy
OD := $(CROSS)objdump
CC := $(CROSS)gcc
MK := ../../tools/mk_image/mkv210_image
all:$(NAME).bin
$(NAME).bin : start.o
$(LD) -Ttext 0x0 -o $(NAME).elf $^
$(OC) -O binary $(NAME).elf $(NAME).bin
$(OD) -D $(NAME).elf > $(NAME)_elf.dis
$(MK) $(NAME).bin
# 将当前目录下存在的汇编文件及C文件编译成.o文件
%.o : %.S
$(CC) -o $@ $< -c
%.o : %.c
$(CC) -o $@ $< -c
clean:
$(RM) *.o *.elf *.bin *.dis *.sd
tools:
make -C ../../tools/mk_image/
arm-linux-ld
--help
: A linker tool, its main function is to link multiple compiled binary files into an executable binary file. There are many options for this command. You can use options to view specific options when you use them. usage.
arm-linux-ld -Ttext 0x0 -o led.elf
$^
: This sentence is to connect all dependent files intoELF
a format file. During the connection process,-Ttext 0x0
this option tells the linker that this program needs to be loaded and executed atRAM
the0x00000000
address. So when connecting, the connection address of the first statement is0x00000000
, and the second statement follows it. Many people are talking about the connection address and the running address. The running address can be equal to the connection address, and it can also be considered that the running address ispc
the address pointed by the pointer, that is, the address where the instruction is being executed. Just understand the concept.
arm-linux-objcopy
: It is used to copy the content of an object file to another file. This option can perform format conversion. In actual programming, the most used isConvert
ELF
an executable file of the format to a binary file
arm-linux-objdump
: Commonly used to display binary file information, often used to view disassembly code
Compile:
fly@fly-vm:01-led_s$ make clean
rm -f *.o *.elf *.bin *.dis *.sd *.BIN
fly@fly-vm:01-led_s$ ls
Makefile start.S
fly@fly-vm:01-led_s$ make
arm-linux-gcc -o start.o start.S -c
arm-linux-ld -Ttext 0x0 -o LED.elf start.o
arm-linux-objcopy -O binary LED.elf LED.bin
arm-linux-objdump -D LED.elf > LED_elf.dis
../../tools/mk_image/mkv210_image LED.bin
the checksum 0x000060EB for 228bytes, output: LED.bin.SD.BIN
fly@fly-vm:01-led_s$ ls
LED.bin LED.bin.SD.BIN LED.elf LED_elf.dis Makefile start.o start.S
3-2. Tool mkv210_image
code
/*******************************************************************
* > File Name: mkv210_image.c
* > Author: fly
* > Create Time: 2021-06-17 4/24 12:03:22 +0800
* > Note: 将USB启动时使用的BIN文件制作得到SD启动的Image
* 计算校验和,添加16字节文件头,校验和写入第8字节处
*================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define ERR_STR strerror(errno)
#define SPL_HEADER_SIZE (16)
#define SPL_HEADER "@S5PV210$$$$****"
#define IMG_SIZE (16*1204)
#define FILE_PATH_LEN_MAX (256)
char *mk_getCheckSumFile(char *binName)
{
static char checkSumFileName[FILE_PATH_LEN_MAX] = {
0};
//snprintf(checkSumFileName, FILE_PATH_LEN_MAX, "%s%s", "sd.", binName);
snprintf(checkSumFileName, FILE_PATH_LEN_MAX, "%s%s", binName, ".SD.BIN");
return (char*)checkSumFileName;
}
long mk_getFileLen(FILE* fp)
{
static long fileLen = 0;
fseek(fp, 0L, SEEK_END);
fileLen = ftell(fp);
fseek(fp, 0L, SEEK_SET);
return fileLen;
}
int main(int argc, char* argv[])
{
FILE* fps, *fpd;
long nbytes, fileLen;
unsigned int checksum, count;
char *BUF = NULL, *pBUF = NULL;
int i;
if(argc != 2){
printf("Usage: %s <bin-file>\n", argv[0]);exit(EXIT_FAILURE);
}
/* 打开源BIN文件 */
fps = fopen(argv[1], "rb");
if (fps == NULL){
printf("fopen %s err: %s\n", argv[1], ERR_STR);
exit(EXIT_FAILURE);
}
/* 创建目标BIN文件 */
fpd = fopen(mk_getCheckSumFile(argv[1]), "w+b");
if (fpd == NULL){
printf("fopen %s err: %s\n", mk_getCheckSumFile(argv[1]), ERR_STR);
fclose(fps);exit(EXIT_FAILURE);
}
/* 获取源文件大小 */
fileLen = mk_getFileLen(fps);
if(fileLen < (IMG_SIZE - SPL_HEADER_SIZE)){
count = fileLen;
}else{
count = IMG_SIZE - SPL_HEADER_SIZE;
}
BUF = (char *)malloc(IMG_SIZE);/* malloc 16KB BUF */
if (BUF == NULL){
printf("malloc err: %s\n", ERR_STR);
fclose(fps);fclose(fpd);
exit(EXIT_FAILURE);
}
memcpy(&BUF[0], SPL_HEADER, SPL_HEADER_SIZE);
nbytes = fread(BUF+SPL_HEADER_SIZE, 1, count, fps);
/* 计算文件检验和 */
pBUF = BUF + SPL_HEADER_SIZE;
for(i = 0, checksum = 0; i< IMG_SIZE - SPL_HEADER_SIZE; i++)
{
checksum += (0x000000FF) & *pBUF++;
}
pBUF = BUF + 8;
*((unsigned int *)pBUF) = checksum;
/* 将校验和源文件写入目标文件 */
fwrite(BUF, 1, IMG_SIZE, fpd);
printf("the checksum 0x%08X for %ldbytes, output: %s\n", \
checksum, fileLen, mk_getCheckSumFile(argv[1]));
free(BUF);
fclose(fps);
fclose(fpd);
return 0;
}
Supporting Makefile
.PHONY: all clean
CC = gcc
SRC = ${wildcard *.c}
BIN = ${patsubst %.c, %, $(SRC)}
CFLAGS = -g -Wall
RM = rm -rf
PRJ_PATH= $(shell pwd)
all:$(BIN)
$(BIN):%:%.c
@echo [CC] $@
@$(CC) -o $@ $^ $(CFALGS) -D_PRJ_PATH_='"$(PRJ_PATH)"'
clean:
$(RM) a.out $(BIN) .*.*.sw? *.sd
test:
@echo $(PRJ_PATH)
.PHONY: clean test
4. run
SD card boot
1. Turn the OM5 switch to the lower side of the development board (select the startup method):
2. Download the BIN file to SD card
2-1. Use x210_Fusing_Tool.exe to download under Windows (note to use administrator mode to open)
Clean up
x210_Fusing_Tool.exe
the file list, enter the directory:C:\Users\fly\AppData\Roaming\SDFusing
, and delete the fileconfig.ini
;
2-2.Linux download BIN file to SD card script command:
#!/bin/sh
#命令行参数检测
if [ -n "$1" ];then
echo "Source file: $1"
else
echo "Usage:$0 <source_file>"
exit -1
fi
#使用超级用户权限把210.bin读取进来,经过处理再输出到设备sdb上,
#跳过该设备的第一个block(每个block的大小为512B)
sudo dd iflag=dsync oflag=dsync if=$1 of=/dev/sdb seek=1
Another more specific way of writing the script:
###########################################################
# File Name: s5pv210-irom-sd.sh
# Author: fly
# Created Time: 2021-06-27 0/25 14:51:59 +0800
###########################################################
#!/bin/bash
# s5pv210 irom sd boot fusing tool
# display usage message
USAGE()
{
echo Usage: $(basename "$0") '<device> <bootloader>'
echo ' device = disk device name of for SD card.'
echo ' bootloader = /path/to/*.bin.sd'
echo 'e.g. '$(basename "$0")' /dev/sdb boot.bin.sd'
}
[ `id -u` == 0 ] || {
echo "you must be root user"; exit 1;}
[ -z "$1" -o -z "$2" ] && {
USAGE; exit 1; }
dev="$1"
xboot="$2"
# validate parameters
[ -b "${dev}" ] || {
echo "${dev} is not a valid block device"; exit 1; }
[ X"${dev}" = X"${dev%%[0-9]}" ] || {
echo "${dev} is a partition, please use device, perhaps ${dev%%[0-9]}"; exit 1; }
[ -f ${xboot} ] || {
echo "${xboot} is not a bootloader binary file."; exit 1; }
# copy the full bootloader image to block device
dd if="${xboot}" of="${dev}" bs=512 seek=1 conv=sync
sync;
sync;
sync;
echo "^_^ The image is fused successfully"
3. Insert the SD card into the SD2 channel, and then power on to check the running status of the program
Turn on the power,
POWER
press and hold the key ; you can use the serial port tool to connectUART2
, and there will be print debugging information output;
5. Reference
1. Book: ARM Embedded Architecture and Interface Technology (Cortex-A8 Edition) (ARM Embedded Architecture and Interface Technology)
2. Book: C Language Programming of Embedded Linux
3. Cross compiler 1 used: https://sourcery.mentor.com/public/gnu_toolchain/arm-none-linux-gnueabi/arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux -gnu.tar.bz2
4. Compiler download address 2 (CSDN): https://download.csdn.net/download/qq_37363920/12333876?utm_medium=distribute.pc_relevant_t0.none-task-download-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.baidujs&depth_1 -utm_source=distribute.pc_relevant_t0.none-task-download-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.baidujs
5. Project address: https://gitee.com/x210bv3s/s5pv210-noos-dev
6.S5PV210_UM_REV1.1.pdf:https://download.csdn.net/download/han1202012/8342745?utm_source=iteye_new
7.S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf:https://download.csdn.net/download/q171884957/8561553
8. S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf (Chinese version): https://blog.csdn.net/I_feige/article/details/104848609
9.x210_Fusing_Tool.exe download address: https://download.csdn.net/download/i_feige/11937635