2931|3

659

帖子

1

TA的资源

纯净的硅(中级)

楼主
 

【平头哥Sipeed LicheeRV 86 Panel测评】D1作为单片机裸奔编程点灯——LED-Blinky [复制链接]

 

网上有大牛开发了D1的baremetal裸金属编程,此时D1是一个名副其实的单片机。开源项目在此:https://github.com/bigmagic123/d1-nezha-baremeta

借鉴如此,也学习一下D1内部各个组件的寄存器编程。先从点灯开始——LED-Blinky

 


暂时没有搭建JTAG调试环境,只能采取编译-下载-运行,通过运行效果来确定是否正常工作。下载是采用xfel工具:https://github.com/xboot/xfel/,下载windows版本即可。

需要取下SD卡,或者上电的时候按住核心板上的FEL按钮。才能进入FEL下载模式。

进入FEL模式后,电脑检测到USB设备,通过Zadig安装USB通用驱动,然后才能使用xfel检测是否连接正确并且进入了FEL模式:

xfel version
AWUSBFEX ID=0x00185900(D1/F133) dflag=0x44 dlength=0x08 scratchpad=0x00045000

xfel sid
d20011005c00481448000505093f760b

 


前提确定已经安装好了riscv64工具链,可以采用elf,也可以采用linux-gnu工具链。(本人是在WSL环境下安装,跟虚拟机或者Linux主机应该都一样)

通过查看D1-H_User Mannual.pdf,找到GPIO的文档,然后对照开发板原理图,可以发现,Lichee RV 86Panel的LED是连接在PC1上(86Panel底板的BT_WAKE_AP信号也接在PC1上,但在裸机编程环境下,BT没有启用,可以忽略。不放心可以拔下来,单独运行核心板);

首先通过XFEL的读写命令,来测试操作读写GPIO的寄存器,看看是否能够闪烁LED:

首先读取PC的配置寄存器PC_CFG0(0x02000060),其中PC1应当从上电默认的Disable模式,修改为OUTPUT模式。


// led-blinky: PC1 to output
xfel hexdump 0x02000060 100
xfel write32 0x02000060 0xFFFFFF1F
// Toggle PC1
xfel write32 0x02000070 0x00000002
xfel write32 0x02000070 0x00000000

每次往PC_DAT寄存器的PC1对应的位置写入0/1,则LED相应的熄灭/点亮,因此LED-Blinky程序只需要按照相同的步骤,即可实现;

led-blinky.c

void delay(int);

static int k = 23;

int main(int argc, char argv) {
	int GPIO_BASE_ADDR = 0x02000000;
	int PC_CFG0 = 0x0060;
	int PC_DAT = 0x0070;
	
	unsigned int *PC_CFG0_Addr = (unsigned int *)(GPIO_BASE_ADDR + PC_CFG0);
	unsigned int *PC_DAT_Addr  = (unsigned int *)(GPIO_BASE_ADDR + PC_DAT);
	
        unsigned int PC_CFG0_Value = *PC_CFG0_Addr;
	PC_CFG0_Value &= 0xFFFFFF0F;
	PC_CFG0_Value |= 0x00000010;
	*PC_CFG0_Addr = PC_CFG0_Value;
	

	while(1) {
		delay(1000);
		*PC_DAT_Addr ^= 0x00000002;
	}

	k++;
	
	return k;	
}

void delay(int count)
{
	
	volatile int x = count;
	while(1) {
		volatile int y = 2000;
		for(; y >0; y--)
			__asm__("nop");

		if(x > 0) x--;
		else break;
	}

	return ;
}

led-blinky.ld

OUTPUT_ARCH( "riscv" )
OUTPUT_FORMAT("elf64-littleriscv")
ENTRY( main )
SECTIONS
{
  /* text: test code section */
  . = 0x00020000;
  .text : { *(.text) }
  /* data: Initialized data segment */
  .gnu_build_id : { *(.note.gnu.build-id) }
  .data : { *(.data) }
  .rodata : { *(.rodata) }
  .sdata : { *(.sdata) }
  .debug : { *(.debug) }
  . += 0x8000;
  stack_top = .;

  /* End of uninitalized data segement */
  _end = .;
}

Makefile


PROJECT ?= led-blinky

CROSS_COMPILE ?= riscv64-unknown-linux-gnu

CFLAGS += -fPIC



.PHONY:	${PROJECT}.bin


${PROJECT}.bin:	${PROJECT}.elf
	${CROSS_COMPILE}-objcopy -O binary $< $@

${PROJECT}.elf:	${PROJECT}.o
	${CROSS_COMPILE}-ld -T ${PROJECT}.ld  -o $@ $<

${PROJECT}.o:	${PROJECT}.c
	${CROSS_COMPILE}-gcc ${CFLAGS}  -c -o $@ $<

clean:
	rm *.o *.elf *.bin

 

需要注意的是,链接文件中,指定了0x00020000为起始地址,即D1芯片内部SRAM的地址,之后测试发现,当使用gcc的PIC(位置无关代码)标志后,不管将代码放置到何处,都能正确执行。

 

代码以及.ld, Makefile写好后,make 即可完成编译、连接,并且将elf转为bin文件,(需要确保riscv64-unknown-linux-gnu-gcc位于PATH中)

 

之后使用xfel将生成的bin文件下载到D1芯片的SRAM中,如图;

此时核心板上的LED正常闪烁。

 

最新回复

这个玩法挺好   详情 回复 发表于 2022-4-14 09:32
点赞 关注
 
 

回复
举报

5263

帖子

239

TA的资源

管理员

沙发
 

get一个新名词,裸金属,查了查,指的是没有操作系统的编程

城会玩啊,那是不是很多嵌入式开发,不基于操作系统的,都是裸金属啦

 

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复

7671

帖子

2

TA的资源

五彩晶圆(高级)

板凳
 

pic应该是加载时用的,还是得有个基地址才行吧。

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

337

帖子

2

TA的资源

纯净的硅(初级)

4
 

这个玩法挺好

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表