您尚未登录。

#1 Re: 全志 SOC » MangoPi-MQ 麻雀D1s && D1 Nezha 裸机实验 && rtos实验 » 2022-03-22 20:24:37

@bigmagic
您好,请问RT中的C906文件夹的内容是哪里来的啊?我在RT官网没找到啊

#3 Re: 全志 SOC » 在D1裸机的基础上,加入freertos,请问进入“Load access fault”异常的原因是什么啊?以及线程卡死,是否与其有关系呢? » 2021-11-01 21:26:10

由于C906并没有将Mtime映射出来,所以要修改vPortSetupTimerInterrupt函数,如下:

void vPortSetupTimerInterrupt( void )
	{
	volatile uint32_t ulHartId;
	
		__asm volatile( "csrr %0, mhartid" : "=r"( ulHartId ) );
		pullMachineTimerCompareRegister  = ( volatile uint64_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) );
		ullNextTime = counter();
		ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick;
		*pullMachineTimerCompareRegister = ullNextTime;
		
		/* Prepare the time to use after the next tick interrupt. */
		ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick;
	}

static inline uint64_t counter(void)
{
	uint64_t cnt;
	 __asm__ __volatile__("csrr %0, time\n" : "=r"(cnt) :: "memory");
	return cnt;
}

现在线程不会进入“Load access fault”异常了,但是还是会卡死。

#4 全志 SOC » 在D1裸机的基础上,加入freertos,请问进入“Load access fault”异常的原因是什么啊?以及线程卡死,是否与其有关系呢? » 2021-10-26 22:21:02

March
回复: 5

看到全志的论坛上,有大佬移植了freertos到D1哪吒开发板上( https://bbs.aw-ol.com/topic/231/freertos-10-4-3%E5%9C%A8riscv-t-head-c906-%E5%B9%B3%E5%8F%B0%E4%B8%8A%E7%A7%BB%E6%A4%8D%E8%BF%87%E7%A8%8B?_=1635232850765 ),想在之前xboot大佬弄的D1的裸机的基础上( https://whycan.com/t_6683.html ),加入freertos。先说说我移植的过程,再说现在还存在的问题。(这里没有sbi,整个FreeRTOS系统运行在M模式,且使用的是windows版的交叉编译工具链)
移植过程:
1.移植框架
引用大佬的图:
1_20211026-2044.png
需要重点关注portASM.S、start.S、FreeRTOSConfig.h以及freertos_risc_v_chip_specific_extensions.h这几个文件。
portASM.S:主要用于上下文切换;start.S:启动文件;FreeRTOSConfig.h:配置文件,主要是一些宏的定义;freertos_risc_v_chip_specific_extensions.h:RISC-V 端口还需要一个额外的头文件,额外的头文件描述了芯片特定的细节。
2.FreeRTOSConfig.h的设置
FreeRTOSConfig.h其实是一个backup,这里面的的选项在 ./FreeRTOS/Source/include/FreeRTOS.h文件里面都有默认的配置,这里选用.\FreeRTOSv202107.00\FreeRTOS\Demo\RISC-V_RV32M1_Vega_GCC_Eclipse\projects\RTOSDemo_ri5cy文件加下的FreeRTOSConfig.h,修改相关宏,以适应D1.
主要修改如下:
(1)设置mtime寄存器信息

#define configMTIME_BASE_ADDRESS 	 ( 0x1400BFF8 )     //MTIME基地址
#define configMTIMECMP_BASE_ADDRESS   ( 0x14004000 )     //MTIME比较寄存器基地址

若无mtime,则将上面的宏定义均设为0。
注:在全志论坛上,有问过MTIME的基地址,想知道具体内容请看https://bbs.aw-ol.com/topic/231/freertos-10-4-3%E5%9C%A8riscv-t-head-c906-%E5%B9%B3%E5%8F%B0%E4%B8%8A%E7%A7%BB%E6%A4%8D%E8%BF%87%E7%A8%8B?_=1635232850765
(2)设置cpu频率和时间滴答的频率

#define configCPU_CLOCK_HZ				24000000   
#define configTICK_RATE_HZ				( ( TickType_t ) 1000 )  

(3)设置最小栈大小限制和堆的总大小

#define configMINIMAL_STACK_SIZE		   ( ( unsigned short ) 130 ) 
#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 100 * 1024 ) )

完整FreeRTOSConfig.h如下:
FreeRTOSConfig.rar
3.选择freertos_risc_v_chip_specific_extensions.h文件
官方提供了两类freertos_risc_v_chip_specific_extensions.h供我们选择,一类是拥有CLINT,但没有其他寄存器扩展,另一类是没有CLINT,但有额外的寄存器扩展,这里选择前者,感兴趣的同学可以分别看看这两类文件分别干了些啥,这里就不多赘述了。
4.中断堆栈设置
(1)使用静态分配的数组作为中断堆栈
在FreeRTOSConfig.h 中定义 configISR_STACK_SIZE_WORDS为要分配的中断堆栈的大小。注意,大小是按字定义的,而不是字节。

#define configISR_STACK_SIZE_WORDS (500)

(2)或在链接文件中定义中断堆栈
如:

.stack : ALIGN(0x10)
  {
    __stack_bottom = .;
    . += STACK_SIZE;
    __stack_top = .;
    __freertos_irq_stack_top= .; /* ADDED THIS LINE. */
  } > ram

5.设置外部中断处理程序
假设外部中断处理程序为handle_trap,在makefile中增加如下编译参数:-DportasmHANDLE_INTERRUPT=handle_trap
6.install freertos_risc_v_trap_handler()
freertos_risc_v_trap_handler()并且是所有中断和异常的中央入口点,若有CLINT,则会自动install freertos_risc_v_trap_handler(),代码实现在portASM.S文件中,若无CLINT,则需要手install freertos_risc_v_trap_handler()
7.宏定义 __riscv_xlen 指定指令长度

CFLAGS      += -D__riscv_xlen=64 -D__riscv64

8.时基
选择mtime作为时基(若没有mtime,则可自己选择一个定时器),在mtime初始化之前(初始化在函数vPortSetupTimerInterrupt()中实现),需要开启mtime。

void clint_timer_init(void)
{
  csr_clear(mie, MIE_MTIE | MIE_MSIE);
  write32(CLINT + 0x4000, + 24000000);
  write32(CLINT + 0x4004, 0);
  csr_set(mie,  MIE_MTIE); 
}

注:在启动文件中,已完成时钟的配置,用24M驱动mtime,外部中断也已在启动文件中开启。
9.start.S

#include <my_linkage.h>
#include <riscv64.h>

	.global _start
_start:
	/* Boot head information for BROM */
	.long 0x0300006f
	.byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0'
	.long 0x12345678				/* checksum */
	.long __spl_size				/* spl size */
	.long 0x30						/* boot header size */
	.long 0x30303033				/* boot header version */
	.long 0x00020000				/* return value */
	.long 0x00020000				/* run address */
	.long 0x0						/* eGON version */
	.byte 0x00, 0x00, 0x00, 0x00	/* platform information - 8byte */
	.byte 0x34, 0x2e, 0x30, 0x00

/*
 * The actual reset code
 */
reset:
	/* Mask all interrupts */
	csrw mideleg, zero
	csrw medeleg, zero
	csrw mie, zero
	csrw mip, zero

	/* Setup exception vectors */
	 la t1, _image_start
	 LREG t1, (t1)
	 la t2, _start
	 sub t0, t1, t2
	 la a0, vectors
	 add a0, a0, t0
	 csrw mtvec, a0

	/* Enable FPU and accelerator if present */
	li t0, MSTATUS_FS | MSTATUS_XS
	csrs mstatus, t0

	/* Enable theadisaee */
	li t1, 0x1 << 22
	.word 0x7c032073	/* csrs mxstatus, t1 */

	/* Invaild icache/dcache/btb/bht */
	li t1, 0x30013
	.word 0x7c232073	/* csrs mcor, t1 */

	/* Check processor id and initialized */
	csrr t0, mhartid
	bnez t0, _avoid
	la t0, _start
	la t1, _image_start
	LREG t1, (t1)
	beq t0, t1, _avoid

	/* Initial system jtag, uart and clock */
	/*call sys_jtag_init*/
	call sys_uart_init
	call sys_clock_init

	/* Copy ddr bin to 0x00030000 */
	la t1, _ddr_bin_start
	LREG t1, (t1)
	la t2, _ddr_bin_end
	LREG t2, (t2)
	sub a2, t2, t1
	la t1, _image_start
	LREG t1, (t1)
	la t2, _ddr_bin_start
	LREG t2, (t2)
	sub t0, t2, t1
	la a1, _start
	add a1, a1, t0
	li a0, 0x00030000
	call my_memcpy

	/* Initial ddr controller */
	call sys_dram_init
_avoid:
	nop

	/* Initialize global pointer */
.option push
.option norelax
	la t0, _global_pointer$
	LREG gp, (t0)
.option pop

	/* Initialize stacks */
	la t1, _stack_start
	LREG t1, (t1)
	la t2, _stack_end
	LREG t2, (t2)
	sub t0, t2, t1
	csrr t3, mhartid
	li t4, 1
	div t0, t0, t4
	mul t0, t0, t3
	sub sp, t2, t0

	/* Check processor id, and startup slave cores */
	csrr a0, mhartid
	beqz a0, 2f
1:	nop
	j 1b
2:	nop

	/* Copyself to link address */
	la t0, _start
	la t1, _image_start
	LREG t1, (t1)
	beq t0, t1, 1f
	call sys_copyself
1:	nop

	/* Clear bss section */
	 la a0, _bss_start
	 LREG a0, (a0)
	 la a2, _bss_end
	 LREG a2, (a2)
	 sub a2, a2, a0
	 li a1, 0
	 call my_memset

	li t0,0x800
	csrs mie,t0     //开全局中断

	li t0, 0x88    /* 加载立即数0x88到t0中*/
    csrs mstatus, t0  /* 开机器模式中断*/

	/* Call _main */
	la t1, _image_start
	LREG t1, (t1)
	la t2, _start
	sub t0, t1, t2
	la a0, _main
	add a0, a0, t0
	jr a0
_main:
	call main
/*
 * Exception vectors.
 */
	.align 4
	.globl vectors
vectors:
	addi sp, sp, -(32 * REGSZ)

	SREG x1, 1 * REGSZ(sp)
	SREG x2, 2 * REGSZ(sp)
	SREG x3, 3 * REGSZ(sp)
	SREG x4, 4 * REGSZ(sp)
	SREG x5, 5 * REGSZ(sp)
	SREG x6, 6 * REGSZ(sp)
	SREG x7, 7 * REGSZ(sp)
	SREG x8, 8 * REGSZ(sp)
	SREG x9, 9 * REGSZ(sp)
	SREG x10, 10 * REGSZ(sp)
	SREG x11, 11 * REGSZ(sp)
	SREG x12, 12 * REGSZ(sp)
	SREG x13, 13 * REGSZ(sp)
	SREG x14, 14 * REGSZ(sp)
	SREG x15, 15 * REGSZ(sp)
	SREG x16, 16 * REGSZ(sp)
	SREG x17, 17 * REGSZ(sp)
	SREG x18, 18 * REGSZ(sp)
	SREG x19, 19 * REGSZ(sp)
	SREG x20, 20 * REGSZ(sp)
	SREG x21, 21 * REGSZ(sp)
	SREG x22, 22 * REGSZ(sp)
	SREG x23, 23 * REGSZ(sp)
	SREG x24, 24 * REGSZ(sp)
	SREG x25, 25 * REGSZ(sp)
	SREG x26, 26 * REGSZ(sp)
	SREG x27, 27 * REGSZ(sp)
	SREG x28, 28 * REGSZ(sp)
	SREG x29, 29 * REGSZ(sp)
	SREG x30, 30 * REGSZ(sp)
	SREG x31, 31 * REGSZ(sp)

	csrr a0, mcause
     csrr a1, mepc
      mv a2, sp
     call handle_trap
      csrw mepc, a0

	LREG x1, 1 * REGSZ(sp)
	LREG x2, 2 * REGSZ(sp)
	LREG x3, 3 * REGSZ(sp)
	LREG x4, 4 * REGSZ(sp)
	LREG x5, 5 * REGSZ(sp)
	LREG x6, 6 * REGSZ(sp)
	LREG x7, 7 * REGSZ(sp)
	LREG x8, 8 * REGSZ(sp)
	LREG x9, 9 * REGSZ(sp)
	LREG x10, 10 * REGSZ(sp)
	LREG x11, 11 * REGSZ(sp)
	LREG x12, 12 * REGSZ(sp)
	LREG x13, 13 * REGSZ(sp)
	LREG x14, 14 * REGSZ(sp)
	LREG x15, 15 * REGSZ(sp)
	LREG x16, 16 * REGSZ(sp)
	LREG x17, 17 * REGSZ(sp)
	LREG x18, 18 * REGSZ(sp)
	LREG x19, 19 * REGSZ(sp)
	LREG x20, 20 * REGSZ(sp)
	LREG x21, 21 * REGSZ(sp)
	LREG x22, 22 * REGSZ(sp)
	LREG x23, 23 * REGSZ(sp)
	LREG x24, 24 * REGSZ(sp)
	LREG x25, 25 * REGSZ(sp)
	LREG x26, 26 * REGSZ(sp)
	LREG x27, 27 * REGSZ(sp)
	LREG x28, 28 * REGSZ(sp)
	LREG x29, 29 * REGSZ(sp)
	LREG x30, 30 * REGSZ(sp)
	LREG x31, 31 * REGSZ(sp)
	
	addi sp, sp, (32 * REGSZ)
	mret


.weak handle_trap
handle_trap:
1:
  j 1b


/*
 * The location of section
 */
	.align 3
_image_start:
	RVPTR __image_start
_image_end:
	RVPTR __image_end
_global_pointer$:
	RVPTR __global_pointer$
_data_start:
	RVPTR __data_start
_data_end:
	RVPTR __data_end
_bss_start:
	RVPTR __bss_start
_bss_end:
	RVPTR __bss_end
_stack_start:
	RVPTR __stack_start
_stack_end:
	RVPTR __stack_end
_ddr_bin_start:
	RVPTR __ddr_bin_start
_ddr_bin_end:
	RVPTR __ddr_bin_end

10.handle_trap实现

void defaultProgarm(void);
uint64_t handle_trap(uint64_t Mcause,uint64_t epc)
{
	if(Mcause & (1UL << 63))
	{
		printf("enter if\n");
		unsigned long cause = Mcause & ~(1UL << 63);
		unsigned long pending = csr_read(mip) & (1 << cause);
		switch(cause)
		{
		case 0:		/* User software interrupt */
		case 1:		/* Supervisor software interrupt */
		case 2:		/* Hypervisor software interrupt */
		case 3:		/* Machine software interrupt */
		case 4:		/* User timer interrupt */
		case 5:		/* Supervisor timer interrupt */
		case 6:		/* Hypervisor timer interrupt */
		case 7:		/* Machine timer interrupt */
			csr_clear(mip, pending);
			defaultProgarm();
			break;
		case 8:		/* User external interrupt */
		case 9:		/* Supervisor external interrupt */
		case 10:	/* Hypervisor external interrupt */
		case 11:	/* Machine external interrupt */
			csr_clear(mip, pending);
			system_irqhandler();
			break;
		default:
			break;
		}
	}
	else
	{
		printf("Mcause=%x\n",Mcause);
		switch(Mcause)
		{
		case 0x0:	/* Misaligned fetch */
		case 0x1:	/* Fetch access */
		case 0x2:	/* Illegal instruction */
		case 0x3:	/* Breakpoint */
			defaultProgarm();
			break;
		case 0x4:	/* Misaligned load */
			defaultProgarm();
			break;
		case 0x5:	/* Load acces */
			defaultProgarm();
			break;
		case 0x6:	/* Misaligned store */
			defaultProgarm();
			break;
		case 0x7:	/* Store accesss */
		case 0x8:	/* User ecall */
		case 0x9:	/* Supervisor ecall */
		case 0xa:	/* Hypervisor ecall */
		case 0xb:	/* Machine ecall */
			defaultProgarm();
			break;
		default:
			defaultProgarm();
			break;
		}
	}
	return epc;
}


void defaultProgarm(void)
{
	printf("defaultProgarm\n");
}

11.创建线程,开启调度
创建三个线程,分别是红灯(1s反转)、LD(3s反转)、绿灯线程(2s反转),然后开启调度。

int main(void)
{
    app_init();
}

void app_init(void)
{
	//(1)【根据实际需要增删】声明主函数使用的变量(声明时不准赋值)
	//(2)初始化全局变量和关总中断
	DISABLE_INTERRUPTS;
	//(3)【根据实际需要增删】 初始化外设模块
	int_init(); //PLIC初始化
	clint_timer_init(); //mtime初始化
	gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF);
	gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF);
	gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);
	//(4)【根据实际需要增删】 给有关变量赋初值
	//(5)【根据实际需要增删】 使能模块中断
	//(6)【不变】开总中断
	ENABLE_INTERRUPTS;
	//(7)【根据实际需要增删】线程创建,不能放在步骤1-6之间
	TaskHandle_t thd_redlight = NULL;
	TaskHandle_t thd_greenlight = NULL;
	TaskHandle_t thd_bluelight = NULL;
	xTaskCreate((void *)thread_redlight, "redlight",128, NULL,1, &thd_redlight);  //线程栈128*4=512b
	xTaskCreate((void *)thread_greenlight, "greenlight",128, NULL,1, &thd_greenlight);
	xTaskCreate((void *)thread_bluelight, "bluelight",128, NULL,1, &thd_bluelight);
	vTaskStartScheduler();   //启动调度器,开始执行任务
	for( ;; )
	{
		printf("不应该到此处\n");
	}
}

存在的问题:
(1)在芯片上电启动后,会开始进入“Load access fault”异常,然后线程会正常调度;
(2)线程能正常运行几分钟左右后,便会卡死。
0b02482f3bef640cc6b1d02d5330a7b.png
请问进入“Load access fault”异常的原因是什么啊?以及线程卡死,是否与其有关系呢?另外,上述的移植过程还有哪里需要完善和改进吗?请大佬指点。

#5 全志 SOC » D1的windows交叉编译 » 2021-07-21 13:39:56

March
回复: 0

Makefile :

#
# Top makefile
#

CROSS		?= riscv64-unknown-elf-
NAME		:= D1

#
# System environment variable.
#
#
# System environment variable.
#

HOSTOS	:= windows

#
# Load default variables.
#
ASFLAGS		:= -g -ggdb -Wall -O3
CFLAGS		:= -g -ggdb -Wall -O3
CXXFLAGS	:= -g -ggdb -Wall -O3
LDFLAGS		:= -T 03_MCU/Linker_file/link.ld -nostdlib
ARFLAGS		:= -rcs
OCFLAGS		:= -v -O binary
ODFLAGS		:=
MCFLAGS		:= -march=rv64gcvxthead -mabi=lp64d -mcmodel=medlow -fno-stack-protector

LIBDIRS		:=
LIBS 		:=
INCDIRS		:=
SRCDIRS		:=

ifeq ($(strip $(HOSTOS)), linux)
MKSUNXI		:= 00_boot0/tools/linux/mksunxi
endif
ifeq ($(strip $(HOSTOS)), windows)
MKSUNXI		:= 00_boot0/tools/windows/mksunxi
endif



#
# Add external library
#
INCDIRS		+= 00_boot0/include \
			   00_boot0 \
			   02_CPU \
			   03_MCU \
			   03_MCU/MCU_drivers \
			   03_MCU/startup \
			   04_GEC \
			   05_UserBoard \
			   06_SoftComponent \
			   07_APPprg
			   
SRCDIRS		+= 00_boot0 \
			   02_CPU \
			   03_MCU/MCU_drivers \
			   03_MCU/startup \
			   04_GEC \
			   05_UserBoard \
			   06_SoftComponent \
			   07_APPprg
			   

#
# You shouldn't need to change anything below this point.
#
AS			:= $(CROSS)gcc -x assembler-with-cpp
CC			:= $(CROSS)gcc
CXX			:= $(CROSS)g++
LD			:= $(CROSS)ld
AR			:= $(CROSS)ar
OC			:= $(CROSS)objcopy
OD			:= $(CROSS)objdump
MKDIR		:= mkdir
CP			:= cp -af
RM			:= rm -fr
CD			:= cd
FIND		:= find

#
# X variables
#
X_ASFLAGS	:= $(MCFLAGS) $(ASFLAGS)
X_CFLAGS	:= $(MCFLAGS) $(CFLAGS)
X_CXXFLAGS	:= $(MCFLAGS) $(CXXFLAGS)
X_LDFLAGS	:= $(LDFLAGS)
X_OCFLAGS	:= $(OCFLAGS)
X_LIBDIRS	:= $(LIBDIRS)
X_LIBS		:= $(LIBS) -lgcc

X_OUT		:= Debug
X_OBJ       := obj
X_NAME		:= $(patsubst %, $(X_OUT)/%, $(NAME))
X_INCDIRS	:= $(patsubst %, -I %, $(INCDIRS))
X_SRCDIRS	:= $(patsubst %, %, $(SRCDIRS))
X_OBJDIRS	:= $(patsubst %, obj/%, $(X_SRCDIRS))

X_SFILES	:= $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.S))
X_CFILES	:= $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.c))
X_CPPFILES	:= $(foreach dir, $(X_SRCDIRS), $(wildcard $(dir)/*.cpp))

SFILENDIR		:= $(notdir  $(X_SFILES))
CFILENDIR		:= $(notdir  $(X_CFILES))
CPPFILENDIR     := $(notdir  $(X_CPPFILES))



X_SDEPS		:= $(patsubst %, obj/%, $(SFILENDIR:.S=.o.d))
X_CDEPS		:= $(patsubst %, obj/%, $(CFILENDIR:.c=.o.d))
X_CPPDEPS	:= $(patsubst %, obj/%, $(CPPFILENDIR:.cpp=.o.d))
X_DEPS		:= $(X_SDEPS) $(X_CDEPS) $(X_CPPDEPS)

X_SOBJS		:= $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
X_COBJS		:= $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
X_CPPOBJS	:= $(patsubst %, obj/%, $(CPPFILENDIR:.cpp=.o)) 
X_OBJS		:= $(X_SOBJS) $(X_COBJS) $(X_CPPOBJS)

VPATH		:= $(SRCDIRS)



.PHONY:	all clean
all : $(X_NAME)

$(X_NAME) : $(X_OBJS)
	@echo [LD] Linking $@.elf
	@$(CC) $(X_LDFLAGS) $(X_LIBDIRS) -Wl,--cref,-Map=$@.map $^ -o $@.elf $(X_LIBS)
	@echo [OC] Objcopying $@.bin
	@$(OC) $(X_OCFLAGS) $@.elf $@.bin
	@$(OC) $@.elf -O ihex $@.hex
	@$(OD) -D $@.elf > $@.lst
	@echo Make header information for brom booting
	@$(MKSUNXI) $@.bin

$(X_SOBJS) : obj/%.o : %.S
	@echo [AS] $<
	@$(AS) $(X_ASFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c -O0 $< -o $@

$(X_COBJS) : obj/%.o : %.c
	@echo [CC] $<
	@$(CC) $(X_CFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c -O0 $< -o $@

$(X_CPPOBJS) : obj/%.o : %.cpp
	@echo [CXX] $<
	@$(CXX) $(X_CXXFLAGS) -MD -MP -MF $@.d $(X_INCDIRS) -c -O0 $< -o $@

clean:
	@$(RM) obj $(X_OUT)

#
# Include the dependency files, should be place the last of makefile
#
sinclude $(shell $(MKDIR) $(X_OBJ) $(X_OUT)) $(X_DEPS)

安装平头哥官网提供的riscv64 windows版的交叉编译工具链,通过cmd make命令编译工程,出现如下错误:
_20210721-1337.png
Makeflie如下:
Makefile.rar
求大佬解答

#7 Re: 全志 SOC » C语言调汇编的程序跳转问题 » 2021-07-15 15:26:43

__asm("mv a1, a0");测试:
_20210715-1522.png
__asm("li a1, 0x40036000");测试:
_20210715-1523.png
两种情况下的跳转现象:
1.11.png
2.22_20210715-1526.png

#8 全志 SOC » C语言调汇编的程序跳转问题 » 2021-07-15 14:19:53

March
回复: 7

qqq.png
为什么上面这样不可以跳转,而下面这样可以跳转呢?
qqq_20210715-1418.png
参数addr被调用的时候传参是0x40036000

#9 Re: 全志 SOC » 用 MSVC2017 编译 XFEL 项目 » 2021-07-14 16:46:12

xboot 说:

要想全擦除,就创建一个全FF的文件,写进去不就行了

对哦

#10 Re: 全志 SOC » 用 MSVC2017 编译 XFEL 项目 » 2021-07-14 16:29:11

发现xfel工具在烧写.bin文件到nor flash时,并不会擦除整个nor falsh,而只是写多少,就擦除多少,因为某些原因,我需要在烧写.bin文件之前将整个nor flash扇区全部擦除。阅读了xfel的源码,有

spinor_sector_erase_256k、spinor_sector_erase_64k,spinor_sector_erase_32k,
spinor_sector_erase_4k

四个函数可以使用,我在写之前,调用这些函数,发现没有效果,求帮助。

#11 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-07-11 19:34:06

找到问题在哪了,因为该寄存器的有些位是只写的,所以要一次性赋值,如下:
111_20210711-1933.png

#12 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-07-11 19:30:59

关于D1裸机的系统软件复位,在用户手册有如下寄存器描述:
_20210711-1556.png
WDOG_SOFT_RST_REG[31:16]:要想改变WDOG_SOFT_RST_REG[0]的值,需将WDOG_SOFT_RST_REG[31:16]设置为0x16AA,
WDOG_SOFT_RST_REG[0]:写1清零,那我怎么才能将WDOG_SOFT_RST_REG[0]变为1使得复位整个系统呢?
是直接将将WDOG_SOFT_RST_REG[31:16]设置为0x16AA就能使得WDOG_SOFT_RST_REG[0]变为1吗?

#13 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-07-06 10:11:23

在D1裸机程序中的sys_spinor_init函数中:
_20210706095934.png
在用户手册上并未找到SPI_CCR寄存器的相关说明啊,望指点。

#14 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-07-02 16:16:34

xboot 说:

父中段就是一个中断被多个子中段共享,gpio一般是一组对应一个父中断

根据您的意思,6T$Q)F7I[)`279S`)4WCJ6S.png,这个寄存器应该控制着是gpio的子中断_20210702-1614.png,那PLIC_MIE_ REGn是控制着gpio的父中断吗?

#16 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-07-02 11:27:47

xboot 说:

先尝试用定时器做中断源吧,至少这个xboot是验证通过的,而且gpio中断,属于子中断,需要先开启父中断的

定时器确实可以产生中断,我写的gpio中断的流程如下:_20210702-1121.png
timer的处理是类似的,您看我的gpio中断流程哪里有问题啊,不知道您说的父中断指的什么呢?

#18 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-06-29 22:59:27

参考xboot的代码,加了GPIO中断的相关代码,但是触发不了中断,不知道是哪里出了问题,求帮助。d1-baremetal.rar

#19 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-06-28 10:49:27

xboot 说:
March 说:

请问楼主,关于中断向量表这部分的汇编代码,有点不太懂,主要是vectors:csrw mscratch, sp    addi sp, sp, -(37 * REGSZ)     SREG x1, 1 * REGSZ(x2)...这部分。

就是中断现场保护,没什么特别的。

好的,谢谢楼主,请问可以提供一份关于中断的裸机程序吗(如GPIO中断),中断这部分不知道该怎么处理。谢谢。

#21 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-06-26 20:43:09

请问楼主,关于中断向量表这部分的汇编代码,有点不太懂,主要是vectors:csrw mscratch, sp    addi sp, sp, -(37 * REGSZ)     SREG x1, 1 * REGSZ(x2)...这部分。

#22 Re: 全志 SOC » 全志 D1的裸机程序,将用户代码拷贝到DDR中后,却跳转不过去 » 2021-06-23 22:03:31

又有一个问题,当跳转失败是,DDR初始化的输出信息是

_20210623-2202.png

当跳转成功后,DDR的输出信息却是

_20210623-2159.png

为什么少了几句呢?

#23 Re: 全志 SOC » 全志 D1的裸机程序,将用户代码拷贝到DDR中后,却跳转不过去 » 2021-06-23 20:47:14

找到问题在哪了,在拷贝代码到DDR中时,地址弄错了,

这里的address应该等于__image_file_start - __spl_start,

而我之前address是__image_file_start

_20210623-2044.png


这里主要实现的是将Boot0部分链接到了SRAM里,

而其他程序链接到DDR里,在加载程序到DDR时只加载用户代码,

flash使用的是nor flash,使用xboot大佬的xfel工具进行烧写,这里附上代码。

d1_spl_20210623-2047.rar

#24 全志 SOC » 全志 D1的裸机程序,将用户代码拷贝到DDR中后,却跳转不过去 » 2021-06-23 18:02:02

March
回复: 2

参考 https://whycan.com/t_5060.html 以及xboot大佬的D1裸机程序,想自己实现一个裸机程序,功能是Boot0部分链接到了SRAM里,而其他程序链接到DDR里,在加载程序到DDR时只加载用户代码,初始化时钟,串口和DDR已经可以了,但是将用户代码拷贝到DDR中后,却跳转不过去,检查了半天,也不知道哪里出现了错误,望解答。


d1_spl.rar

#25 Re: 全志 SOC » 关于Xboot大佬的D1裸机程序的若干问题 » 2021-06-22 21:54:42

这里的la t1, _image_start不是已经取得_image_start的地址到t1寄存器中了吗?为什么后面还要加LREG t1, (t1)这一句呢?_20210622-2154.png

#26 全志 SOC » 关于Xboot大佬的D1裸机程序的若干问题 » 2021-06-22 21:02:51

March
回复: 4

看了xboot大佬的D1裸机程序,有几处看的很迷糊,由于学艺不精,所以来论坛提问,望解惑。
主要问题是在start.s文件中,有几处汇编代码不是很清楚,

1._20210622-2102.png

此处代码是为了判断当前运行地址是否是链接地址,根据代码:t0中存的是_start的地址,t1中存的是_image_start地址中的内容(8字节),请问是t0中存的链接地址,t1中存的是当前运行地址吗?为啥当前运行地址是存储在_image_start的地址中?


2._20210622-2058.png

此处拷贝ddr的bin文件,用到了函数memcpy,该函数的第三个参数是len,为什么a2是通过计算_ddr_bin_start和_ddr_bin_end地址中的内容的差来得到长度的呢?不应该是_ddr_bin_end的地址-_ddr_bin_start的地址吗?

#30 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-06-21 13:58:49

是d1,应该是焊接好了,spi nor flash的信息如下:
111_20210621-1358.png
用xfel spinor这个命令输出的信息如下_20210621-1357.png

#32 Re: 全志 SOC » 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。 » 2021-06-21 13:16:55

请问楼主,按照您的步骤,利用xfel工具直接在DDR中运行d1-baremetal.bin,串口输出运行信息,但是烧录到spi nor flash后,上电运行,串口并未输出信息,这是怎么回事呢?_20210621-1316.png

#33 Re: 全志 SOC » 关于全志D1的SD/TF卡 的地址“32800” » 2021-06-19 14:57:46

利用spl能跳转到自己的工程了 在自己的工程里实现点亮一盏小灯 ,但是这是利用将spl.bin和my.bin分别烧录到TF卡的8k偏移和32800*512B偏移,因为TF卡的拔插性,不具有便捷性,看到平头哥的调试器cklink,请问这个cklink能烧录.bin文件至spi nand flash或者spi nor flash吗?

#34 全志 SOC » 关于全志D1的SD/TF卡 的地址“32800” » 2021-06-18 14:56:18

March
回复: 4

使用SD卡启动方式,程序会去读取SD卡的32800扇区(一个扇区512)处的toc1数据(64字节),利用官方的SD卡烧录工具,将tina_d1-nezha_uart0.img烧录至SD卡中,在程序中以十六进制输出该数据

_20210618-1446.png


_20210618-1447.png

同时用命令读出512*32800偏移处的数据,如下:



_20210618-1451.png


可以看到数据确实是一致的,但是该64B数据在tina_d1-nezha_uart0.img的地址却是0x12b400,

_20210618-1454.png


但是32800*512=16793600=0x1004000,为啥不是0x1004000这个地址呢?

#35 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-17 21:04:24

哇酷小二 说:
March 说:

这个头部数据是在哪里赋值的呢?是在打包阶段吗?

你看下脚本,里面有 各个.fex怎么生成的,

比如 update_boot0 专门生成 boot0*.fex 文件。

能力有限,还是不知道这个头部数据在哪里生成的。

#36 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-16 20:52:41

这个头部数据是在哪里赋值的呢?是在打包阶段吗?

#37 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-16 20:38:13

现在更改了BT0_head的初始数据,烧录boot0_sdcard_sun20iw1p1.bin至TF卡中,可以初始化DDR和mmc了,结果如下:
37ee5f8a30ce8987e5f894c14aceed0.png
程序连续输出两个“error:bad magic.”错误提示停止了,仔细看了代码,是toc1的头部数据数据不对,而头部数据又是从UBOOT_START_SECTOR_IN_SDMMC=32800处读出来的,利用官方的PhoenixCard工具烧录tina_d1-nezha_uart0.img到TF卡中,输出头部数据,如下:
7213fb8a314056bd5184f053dd36adf.png
_20210616-2037.png
我的问题是:这个头部数据是在什么时候赋值的呢?这个“32800”是指扇区吗?
望大佬指点一下。

#38 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-12 20:38:16

所以这里是将整个64k的启动引导程序划分成立boot0和boot1吗?a3409d4e38348824b3849a2fb9d1aa5.png
这里的spl是boot0,boot1是指哪一个呢?还有spl目录下的fes文件具体是什么作用啊?222.png用于烧录的fes1,是什么意思啊?有点迷糊。

#39 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-12 20:33:29

哇酷小二 说:

out/d1-nezha/image/boot0_sdcard.fex

终于搞清楚了, 这个文件就是 TF卡 8K偏移的数据。


所以, 我们把  boot0_sdcard.bin或者boot0_sdcard_sun20iw1p1.bin 烧录到TF卡需要修改源码里面那个结构体数组。

是BT0_head这个结构体数组吗?_20210612-2033.png

#41 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 20:36:49

@哇酷小二
现象是一样的

#43 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-11 17:44:00

bigmagic 说:

fel 模式下下载boot0代码,ddr初始化不成功,这个感觉像主频不匹配?好想下载到nand或者sd卡中自启动试试,有没有办法操作一下

https://whycan.com/t_6643.html#p64460

#45 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 17:37:07

成功将boot0烧到tf中,和直接用xfel运行boot0现象是一样的。_20210611-1730.png _20210611-1731.png,在初始化DDR停止了。

#47 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 16:31:12

那个boot0的bin文件大小不都接近64G了嘛

#48 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 16:16:01

我先试试烧录到TF卡把,我的TF卡是64G的,还得重买卡,对了 为什么要烧录到TF卡得8K的偏移位置啊

#49 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 15:52:25

哇酷小二 说:
March 说:
哇酷小二 说:

是不是还有一个 SRAM A0?

怎么办呢

感觉那个N-BROM 0x0 - 0xBFFFF  48k 应该是SRAM

不知道里面具体的机制是啥, 猜测这个是brom把boot0加载到这个位置?

这个N-BROM 0x0 - 0xBFFFF不是BROM程序的位置吗?_20210611-1552.png

#50 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 15:37:44

哇酷小二 说:

是不是还有一个 SRAM A0?

怎么办呢

#51 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-11 15:21:27

哇酷小二 说:

@bigmagic
按照全志的惯例, 应该是从 sys_config.fex 的二进制文件读入配置, 再决定初始化哪组串口,

前面应该有读配置(二进制)的过程.

没找到”从 sys_config.fex 的二进制文件读入配置“的过程啊

#52 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 14:33:59

刚找了一下,没找到SRAM A0

#53 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 14:28:02

_20210611-1423.pngD1的sram大小是32K,和boot0相关的.bin文件,大小均超过了32K,111.png

#54 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 12:07:53

请问把 boot0 烧到 tf 卡的 8k 偏移位置,是这样烧写的吗.png

#55 Re: 全志 SOC » D1开发板的裸机程序 » 2021-06-11 10:32:59

请问tf卡的格式和大小有要求吗

#56 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-11 10:03:02

@bigmagic 那这是不是说明只运行boot0,初始化ddr失败了啊?

#57 全志 SOC » D1开发板的裸机程序 » 2021-06-10 14:57:30

March
回复: 28

我想实现D1开发板的裸机程序(即不运行任何操作系统),试着用了xboot大神的xfel工具,但这个工具暂时还不支持将程序烧录至nand中,所以只好寻求别的办法,看了D1的启动流程,主要是芯片内部的bootRoM->spl->opensbi+uboot->linux,因为这里想实现的是裸机程序,所以我的想法是bootROM->spl->自己的工程,请问这个方法有可行性吗?求指点。

#58 Re: 全志 SOC » xfel运行D1的boot0 » 2021-06-10 14:17:08

怎么通过write命令初始化uart呢?

#59 全志 SOC » xfel运行D1的boot0 » 2021-06-09 21:58:38

March
回复: 36

利用xfel将boot0运行起来 输出内容如下:
HELLO! BOOT0 is starting!
BOOT0 commit : 27369ab
...
board init ok
ZQ value = 0x31***********
get_pmu_exist = -1
是不是说明boot0里面初始化ddr的操作失败了啊
求大佬指点
(附:本来想上传图片的,奈何上传半天没上传成功,只能手敲...)

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn