
 
                        最近在研究riscv的底层,包括riscv的bkpv扩展,riscv工具链,riscv的qemu,看到D1的硬件性能还不错,结合自己的研究方向,在实际的芯片上做实验更加有效果。加上平头哥的C906已经开源了,这确实是一个选择底层研究riscv不错的硬件平台。
之前研究过一段时间的树莓派baremeta,觉得d1-nezha也是完全可以研究baremetal的
https://github.com/bigmagic123/d1-nezha-baremeta
实验基于全志的soc,目前已经实现了clint,plint等中断系统,还有riscv system timer, soft interrupt等实验,拿到MangoPi-MQ后,也进行led的点灯实验。后期也会逐渐完善i2c,spi, sdio 等等,还有精力的话实现更加高级的外设。
1.startup
2.vector_example
3.uart
4.soft_intrrupt
5.timer
6.plint
7.led
8.input
另外,也适配了rt-thread系统,当前rt-thread是系统运行在riscv machine mode下,因为是实验平台,实现最新版本的rt-thread的适配,后期会结合baremetal做更多有趣的应用。
离线

离线
期待补上些针对MQ的实验记录,然后私信我有惊喜。
RTT-smart那边说本月会释放个新版本适配了MQ。
歪朵拉开源硬件: https://widora.cn
淘宝:  https://widora.taobao.com/
离线
D1s跑rtt就强大了,64M内存完全够用
离线
离线

芒果派-D1S怎么搭建RTT平台-点灯,大佬出个教程呗
离线

当前d1s的gpio驱动已经对接到rt-thread的驱动框架上了。
现在描述一下在麻雀派上的点灯操作以及原理分析。
LED对应的引脚是PD22

这时对接rt-thread的pin框架,可以按照下面的方式进行
首先需要实现rt-thread pin 框架的ops
static const struct rt_pin_ops ops =
{
    d1s_pin_mode,
    d1s_pin_write,
    d1s_pin_read,
    d1s_pin_attach_irq,
    d1s_pin_detach_irq,
    d1s_pin_irq_enable,
    d1s_pin_get,
};实现上述的几个函数的功能,然后将上述的结构体注册进去
rt_device_pin_register("gpio", &ops, RT_NULL);当前只实现了读,写操作,关于中断的操作目前还没有实现。
在操作的代码中,可以通过下面的操作进行
int main(void)
{
    printf("Hello RISC-V!\n");
    int led_pin = rt_pin_get("PD.22");
    rt_pin_mode(led_pin, PIN_MODE_OUTPUT);
    while(1)
    {
        rt_pin_write(led_pin, 1);
        rt_thread_mdelay(500);
        rt_pin_write(led_pin, 0);
        rt_thread_mdelay(500);
    }
    return 0;
}最后就可以实现点灯操作。
离线

关键点在于设置VS标志位

VS位于MSTATUS寄存器的23到24位。但是需要注意的是,当使用RVV时,需要开启浮点寄存器(FS),不然会报错。
同时在编译选项中添加
-march=rv64gcvxtheadc -mabi=lp64d -mtune=c906关于测试的例子,可以参考
https://github.com/T-head-Semi/csi-nn2这是平头哥开源的神经网络库,里面又有一些操作函数,只简单测试一下性能

测试结果可以看出,浮点加法,乘法性能还是可以的,但是memcpy还是newlib中优化的较好。
代码可以参考
https://github.com/bigmagic123/d1-nezha-rtthread/blob/main/bsp/d1-nezha/applications/vector.c
离线

完成了麻雀riscv d1s上的rt-thread 适配lvgl功能
刷新率还算可以,通过demo上测试的平均帧率在38fps,当然这个不是很可信,基本还算流畅吧。应该还有优化空间,现在开源,起到抛砖引玉的作用。
开源代码
https://github.com/bigmagic123/d1-nezha-rtthread
打开env功能
输入
C:\work\work\d1\d1-nezha-rtthread\bsp\d1-nezha
> pkgs --update
==============================>  LVGL update done
==============================>  lv_music_demo update done
Operation completed successfully.然后输入scons开始编译
最后通过fex工具下载固件到d1s的板子上就可以看到了。
当前gt911触摸驱动已经ok,还没完全适配到lvgl上
离线

d1s 上的运行rt-thread 上的lvgl 触摸功能也正常了,现在实现的gt911触摸驱动比较粗糙,没有按下移动事件,这里基本对接到lvgl的indev设备,后续有需求再完善功能。
离线

关于平头哥开源的DSP RVV intrinsic
似乎很久没有维护了,其自带的编译器中是,就拿官网上下载的riscv gcc来看
riscv64-elf-mingw\lib\gcc\riscv64-unknown-elf\8.4.0\include

其gcc的版本为8.4.0,平头哥开源出来的gcc版本为10.2.
https://github.com/T-head-Semi/xuantie-gnu-toolchain
其版本号不一样,而且riscv-vector.h和riscv-dsp.h的intrinsic也不一样。这样就有可能平头哥内部维护一个版本的gcc,而开源的又是另外一个版本。
这两个版本的intrinsic应该都不会被gcc上游接纳,所以编译模型也会非常奇怪,感觉这部分不会被启用了。
不过这个也没办法,做芯片相关gcc都会这样搞,就像当年苹果维护gcc一样。后续感觉平头哥对维护自己的开源的xuantie-gnu-toolchain,也会显得有心无力啊。
离线

d1上的向量自动化
由于d1支持rvv扩展,如果写汇编比较麻烦,用intrinsic比较简单,但是问题是也需要查手册,而且平头哥rvv0.71版本并不在上游支持的范围了。
如果直接写c函数,编译器能够自动优化并且自动向量化,这样才是最智能的方式。
首先需要开启rvv的扩展,并且在gcc编译器中使能rvv支持。这部分可以看我移植的rtt的代码实现。
直接看效果。
#include <riscv-vector.h>
vuint8m8_t test_auto_vand(vuint8m8_t a, vuint8m8_t b) 
{
    return a & b;
}
int main(void)
{
    vuint8m8_t aa = {0};
    vuint8m8_t bb = {0};
    test_auto_vand(aa,bb);
}通过反汇编可以看到已经自动向量化了

一次性可以将一个数组的变量进行and操作。
这是一个很好的优化特性,如果做代码优化和速度优化,将会很实用。但是需要注意的是,硬件也应该开启rvv支持,否则编译器做了优化,而应该没有开启,会导致系统崩溃。
离线
@bigmagic 
大佬能否研究一下f133的mpu,现在我有个问题解决不了,在跑lvgl或者awtk的时候,特别是动画的时候,比如指针旋转,那么指针会无规律的出现毛刺,应该是dcache引起的,我把dcache关闭就正常了,但是帧率惨不忍睹,开了dcache就发现这个毛刺问题,理论上我也没有用到dma,不知道为什么会导致dcache不一致的,能否指点一下该怎么去操作
离线

@smiletiger 
如果是cache问题,那么就flush fb那一块的cache,帧率上不去,就用双缓冲buffer。cache一致性问题不一定是使用了dma。经过研究,在c906中,特别开启了O2优化,很多函数写法都会引起编译器自动优化调用thead自定义指令,虽然可以提高系统性能和速度,但是最好还是注意一下cache问题,另外就是内存不经过分配直接使用,可能会多出ebreak的指令操作。O0优化基本没这个问题,但是性能有所下降,你自己做取舍。
最近编辑记录 bigmagic (2022-01-27 10:07:56)
离线

riscv编译器中,不同的选项组合对于系统性能的影响非常严重。我们往往会通过优化来进行code size和性能的提升,这里不仅仅涉及到内存访问速度,更多是底层算数或者逻辑操作的优化,这一点点优化空间对于系统的影响是非常大的。下面列出几个例子。以下测试都是基于开启O2优化后进行的测试。
https://github.com/bigmagic123/d1-nezha-rtthread/blob/main/bsp/d1-nezha/rtconfig.py
   DEVICE  = ' -march=rv64gcvxtheadc  -mabi=lp64d -mtune=c906 -fno-omit-frame-pointer '
   CFLAGS  = DEVICE + '  -ffreestanding -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields '-fno-omit-frame-pointer
开启这个选项,可以增加fp的功能,也就具备栈回溯的功能。
https://pdos.csail.mit.edu/6.828/2019/lec/l-riscv.txt
其栈的分布如下:
Stack
                   .
                   .
      +->          .
      |   +-----------------+   |
      |   | return address  |   |
      |   |   previous fp ------+
      |   | saved registers |
      |   | local variables |
      |   |       ...       | <-+
      |   +-----------------+   |
      |   | return address  |   |
      +------ previous fp   |   |
          | saved registers |   |
          | local variables |   |
      +-> |       ...       |   |
      |   +-----------------+   |
      |   | return address  |   |
      |   |   previous fp ------+
      |   | saved registers |
      |   | local variables |
      |   |       ...       | <-+
      |   +-----------------+   |
      |   | return address  |   |
      +------ previous fp   |   |
          | saved registers |   |
          | local variables |   |
  $fp --> |       ...       |   |
          +-----------------+   |
          | return address  |   |
          |   previous fp ------+
          | saved registers |
  $sp --> | local variables |
          +-----------------+同样写一个函数
unsigned long test_addsl(unsigned long b,unsigned long c)
{
  unsigned long a;
  a = b + (c << 2);
  return a;
}当带有fno-omit-frame-pointer时,其生成的汇编如下:
00000000400000f0 <test_addsl>:
    400000f0:	1141                	addi	sp,sp,-16
    400000f2:	e422                	sd	s0,8(sp)
    400000f4:	0800                	addi	s0,sp,16
    400000f6:	6422                	ld	s0,8(sp)
    400000f8:	04b5150b          	addsl	a0,a0,a1,2
    400000fc:	0141                	addi	sp,sp,16
    400000fe:	8082                	ret
	...如果不需要栈回溯,则不添加该指令
00000000400000d0 <test_addsl>:
    400000d0:	04b5150b          	addsl	a0,a0,a1,2
    400000d4:	8082                	ret
	...可以看到优化很多,条指令,减少了内存读写次数。可见其优化的力度还是很大的。有时候费尽心力的去优化驱动提高性能,而再编译器层面,却一个选项就可以让性能提高非常大。
-ffunction-sections -fdata-sections
减少code size的选项,如果gcc选项中添加这个,将会让代码函数进行调用优化,如果没使用到的函数则不会被链接进去。并且函数的链接形式也会发生一些改变。
也就是说可能通过objdump再也通过函数名字找到某些函数的反汇编代码了。
离线

想要发挥出riscv极致的性能特性,少不了对riscv指令的扩展,这里除了通用的bkpv指令的扩展外,c906也自己定义了自己的指令实现。这部分可以参考《玄铁C906_R1S0用户手册》,但是这部分的优化,要想使用的好,必须对gcc有一定的了解,由于平头哥、全志对这部分的资料如何使用,放出来的并不多,完全没法将其性能发挥到极致。作为gcc的开发者和研究者,对这部分可以做一个简单的说明。
文档说扩展指令必须在mxstatus.theadisaee==1时才能够执行,半精度指令在mstatus.fs!=2'00时才能正常执行,否则会产生非法指令的异常。这是硬件的限制,下面来看一下算数运算指令。
在编译器选项的优化中,需要开启O2优化,此时才能让编译器去优化特定的操作,例如
ADDSL
寄存器位移
rd <- rs1+rs2 << imm2
unsigned long test_addsl(unsigned long b,unsigned long c)
{
  unsigned long a;
  a = b + (c << 2);
  return a;
}这个是一个很典型的位移后再加的操作。
如果不开启O2优化,采用O0优化,则生成汇编代码如下
000000004000c5a0 <test_addsl>:
    4000c5a0:	7179                	addi	sp,sp,-48
    4000c5a2:	f422                	sd	s0,40(sp)
    4000c5a4:	1800                	addi	s0,sp,48
    4000c5a6:	fca43c23          	sd	a0,-40(s0)
    4000c5aa:	fcb43823          	sd	a1,-48(s0)
    4000c5ae:	fd043783          	ld	a5,-48(s0)
    4000c5b2:	078a                	slli	a5,a5,0x2
    4000c5b4:	fd843703          	ld	a4,-40(s0)
    4000c5b8:	97ba                	add	a5,a5,a4
    4000c5ba:	fef43423          	sd	a5,-24(s0)
    4000c5be:	fe843783          	ld	a5,-24(s0)
    4000c5c2:	853e                	mv	a0,a5
    4000c5c4:	7422                	ld	s0,40(sp)
    4000c5c6:	6145                	addi	sp,sp,48
    4000c5c8:	8082                	ret开启O2优化后,则gcc会对指令进行优化,采用平头哥自定义指令。
0000000040000500 <test_addsl>:
    40000500:	04b5150b          	addsl	a0,a0,a1,2
    40000504:	8082                	ret
	...肉眼可见其优化力度了,这个目前在标准的riscv指令中就是B扩展,相信随着B扩展的稳定,在性能和code size上一定可以超过arm指令。
类似的还有
MULA
乘法累加
MULS
乘法累减
左移右移操作,FF快速查找等等。
这些并不需要使用者去写汇编指令,只需要开启编译选项,编译器会自动优化,这对于程序的执行效率将会非常大的影响。
需要注意的是,想要使用平头哥自定义的扩展指令,必须开启MXSTATUS的THEADISAEE位。

离线
@bigmagic 
f133跑rtt经常会出现这报错
Unhandled Exception 1:Instruction Access Fault
mcause:0x0000000000000001,mtval:0x000000004002fb1c,mepc:0x000000004002fb1c
--------------Dump Registers-----------------
Function Registers:
    ra(x1) = 0xb16411401d4de880()
)
    gp(x3) = 0x1c0c1d1609056001()
    tp(x4) = 0xa0a01b0458959944()
Temporary Registers:
    t0(x5) = 0xc99409841cb40d84()
    t1(x6) = 0x2811084e1d836415()
    t2(x7) = 0x0cc50cc545445525()
    t3(x28) = 0x186652b424602c04()
    t4(x29) = 0x178059000044cbd5()
    t5(x30) = 0xa08009f10d111d83()
    t6(x31) = 0x4d0111251891050f()
Saved Registers:
    s0/fp(x8) = 0x352819511da41060()
    s1(x9) = 0x94141d4501140380()
    s2(x18) = 0x14521c57bd3d0b81()
    s3(x19) = 0x0581828d1d111d01()
    s4(x20) = 0x18b5050121a419b5()
    s5(x21) = 0x5c1589ccb0915961()
    s6(x22) = 0x0507154311050020()
    s7(x23) = 0x9dae00191f100410()
    s8(x24) = 0x09959cb008eccd35()
    s9(x25) = 0x1c859d2110801085()
    s10(x26) = 0x0905d40019538d87()
    s11(x27) = 0x511d051890d513e7()
Function Arguments Registers:
    a0(x10) = 0x1dc6450144144980()
    a
1(x11) = 0x1d91093038315db3()
    a2(x12) = 0x90a41e3d808b4c96()
    a3(x13) = 0x0d28148c99e02c85()
    a4(x14) = 0x0590238b0f1401b9()
    a5(x15) = 0x7d091d155b0c4100()
    a6(x16) = 0x0c87182739a51a11()
    a7(x17) = 0x2d03208419851495()
sstatus = 0x0000000a00b00080
    Supervisor Interrupt Disabled
    Last Time Supervisor Interrupt Disabled
    Last Privilege is User Mode
    Not Permit to Access User Page
    Not Permit to Read Executable-only Page
satp = 0x0000000000000000
    Mode = No Address Translation/Protection Mode
-----------------Dump OK---------------------
可能是哪里有问题哦用的o3优化
离线

@smiletiger 
开启优化选项,并且使能了平头哥的扩展指令集或者V扩展指令,就要注意代码的规范了,说不定就优化过度了(插入了一些特殊操作),目前平头哥的riscv gcc目前仍然在编程模型上有着一定的限制,并不会如arm编译器一样稳定,特别是开启优化后,就要十分注意了。可以通过empc地址跟踪一下函数的报错地方,看看反汇编是否正常。
离线

最近研究平头哥开源的gcc编译器,发现其针对MCU系列,也有硬件自动压栈指令

自动生成ipush和ipop的方式也有意思
匹配条件
-march=*xtheade*,开启O2优化
#include <string.h>
#include <stdio.h>
__attribute__((interrupt)) void func(void)
{
}
void main(void)
{
    func();
}然后编译
riscv64-unknown-elf-gcc -march=rv64gcxtheade -mabi=lp64d -ffreestanding -fno-common applications\test\test_thead.c -o aaa
反汇编该文件
000000000001018e <func>:
   1018e:	0040000b          	ipush
   10192:	1141                	addi	sp,sp,-16
   10194:	e422                	sd	s0,8(sp)
   10196:	1100                	addi	s0,sp,160
   10198:	0001                	nop
   1019a:	6422                	ld	s0,8(sp)
   1019c:	0141                	addi	sp,sp,16
   1019e:	0050000b          	ipop这就意味着,在MCU层面,使用向量中断,不用考虑中断的压栈和出栈问题,大大提高MCU的实时性。该机制非常重要,但是对于D1这种高性能的MPU,并没有这种特性,更多的灵活性在编程者手中。
离线

玄铁C900系列工具链更新了
https://occ.t-head.cn/community/download?id=3996672928124047360
终于更新到10.2版本了
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.0 (Xuantie-900 elf newlib gcc Toolchain V2.2.4 B-20211227)
很显然,平头哥内部还在积极的向上游的riscv gcc保持统一的,这对riscv发展来说是件好事。通过对其关注,发现平头哥确实在riscv gcc的上游rvv上提供了不少的patch。但是并非开放在xuantie gcc中,社区和内部还是有所保留。
https://github.com/riscv-collab/riscv-gcc/issues/320
There is a guy at rivai.ai who claims to be working on gcc rvv 1.0 support for mainline FSF gcc, so maybe in a few months we will have something usable. Rivai is in Shenzhen.如果可能,是不是能够在今年见的完整的商业可用的riscv rvv指令支持呢?期待完成向量支持,这样riscv将会在桌面,AI,高性能上大有可为
离线
嗯 我测试mangopi-mq 可以运行成功 但是屏幕没有显示 屏幕是4.3寸 800x480
ps
thread               pri  status      sp     stack size max used left tick  error
-------------------- ---  ------- ---------- ----------  ------  ---------- ---
gt911                 25  ready   0x00000830 0x00001000    51%   0x00000005 000
tshell                20  running 0x000002f8 0x00002800    19%   0x00000009 000
LVGL                  21  ready   0x000002d8 0x00002000    44%   0x00000006 4294967294
sys_work              23  suspend 0x00000288 0x00001000    15%   0x0000000a 000
mmcsd_detect          22  suspend 0x000002e8 0x00002800    07%   0x00000014 000
tidle0                31  ready   0x00000570 0x00004000    08%   0x0000001a 000
timer                  4  suspend 0x00000278 0x00004000    04%   0x00000009 000
main                  10  suspend 0x000002f8 0x00004000    10%   0x0000000f 000
msh />
msh />
貌似有点问题,CPU 是F133-A,运行linux 可以亮屏
最近编辑记录 9844201@qq.com (2022-02-06 23:25:39)
离线
@bigmagic 
大佬怎么不来更新了,也不去github更新啦 ,想死你了
离线
D1s跑rtt,在配个LVGL应该很溜,正在学习中
离线
scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build
LINK rtthread.elf
riscv64-unknown-elf-objcopy -O binary rtthread.elf rtthread.bin
Error in calling command:riscv64-unknown-elf-objcopy
Exception: Exec format error
scons: *** [rtthread.elf] Error 8
scons: building terminated because of errors.
你好请问这个怎么解决啊
   7 | #include <riscv-vector.h>
      |          ^~~~~~~~~~~~~~~~
compilation terminated.
scons: *** [build\applications\test\auto_rvv.o] Error 1
scons: building terminated because of errors.
离线

@zhong 
编译器需要支持V扩展,另外编译器选项-march=rv64gcvxtheadc  -mabi=lp64d,其中的v表示告诉编译器开启v扩展指令
离线
你好,博主,请问这个怎么处理啊
ZWH@DESKTOP-AQD2LI1 G:\cenge\D1S_CODE\d1-nezha-rtthread-main\bsp\d1-nezha
> set RTT_EXEC_PATH=G:\cenge\D1S_CODE\gcc\riscv64-elf-mingw-20210618\riscv64-elf-mingw\bin
ZWH@DESKTOP-AQD2LI1 G:\cenge\D1S_CODE\d1-nezha-rtthread-main\bsp\d1-nezha
>
ZWH@DESKTOP-AQD2LI1 G:\cenge\D1S_CODE\d1-nezha-rtthread-main\bsp\d1-nezha
> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build
CC build\applications\lvgl\lv_demo.o
riscv64-unknown-elf-gcc: error: CreateProcess: No such file or directory
scons: *** [build\applications\lvgl\lv_demo.o] Error 1
scons: building terminated because of errors.
ZWH@DESKTOP-AQD2LI1 G:\cenge\D1S_CODE\d1-nezha-rtthread-main\bsp\d1-nezha
> scons -c
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Cleaning targets ...
Removed cconfig.h
scons: done cleaning targets.
ZWH@DESKTOP-AQD2LI1 G:\cenge\D1S_CODE\d1-nezha-rtthread-main\bsp\d1-nezha
> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build
CC build\applications\lvgl\lv_demo.o
riscv64-unknown-elf-gcc: error: CreateProcess: No such file or directory
scons: *** [build\applications\lvgl\lv_demo.o] Error 1
scons: building terminated because of errors.
离线
ZWH@DESKTOP-AQD2LI1 G:\cenge\D1S_CODE\d1-nezha-rtthread-main\bsp\d1-nezha
> set RTT_EXEC_PATH=G:\cenge\D1S_CODE\gcc\riscv64-elf-mingw-20210618\riscv64-elf-mingw\bin
ZWH@DESKTOP-AQD2LI1 G:\cenge\D1S_CODE\d1-nezha-rtthread-main\bsp\d1-nezha
> set EXEC_PATH=G:\cenge\D1S_CODE\gcc\riscv64-elf-mingw-20210618\riscv64-elf-mingw\bin
ZWH@DESKTOP-AQD2LI1 G:\cenge\D1S_CODE\d1-nezha-rtthread-main\bsp\d1-nezha
> set PATH=G:\cenge\D1S_CODE\gcc\riscv64-elf-mingw-20210618\riscv64-elf-mingw\bin;%PATH%你好,是这样吗
离线
@bigmagic 
可以研究一下怎么烧入flash开机运行吗,现在这个裸机只能在ddr上面调试
离线
超级爱,正想学习准备用D1S呢,又不想上Linux,启动太慢,
离线
@bigmagic 
您好,请问RT中的C906文件夹的内容是哪里来的啊?我在RT官网没找到啊
最近编辑记录 March (2022-03-22 20:24:56)
离线
@bigmagic
您好,请问RT中的C906文件夹的内容是哪里来的啊?我在RT官网没找到啊
大哥你也来了啊,哈哈,freertos 177秒宕机问题找到了吗,我这里测试也是177秒死机....一直在研究
离线
D1S:从机器模式切换到用户模式,怎么执行到mret之后的第一条指令,就报异常1的?mtval,mepc都是mret后的第一条指令地址。是还有哪些寄存器要配置吗?
    csrr  t1, mstatus
    li    t0, ~0x00001800
    and   t1, t1, t0
    csrw  mstatus, t1
    la    t0, 1f
    csrw  mepc, t0
    mret
1:
最近编辑记录 dick2945 (2022-06-08 10:26:56)
离线
March 说:@bigmagic
您好,请问RT中的C906文件夹的内容是哪里来的啊?我在RT官网没找到啊大哥你也来了啊,哈哈,freertos 177秒宕机问题找到了吗,我这里测试也是177秒死机....一直在研究
CLINT计时器中断比较值寄存器 只能用32位指针读写,用64位指针写时高32位是写不进去的。32位无符号整数最大值4294967295/晶振频率24000000=178.957秒。所以到了178.956秒的中断后,会一直进入中断直至0x10000000000000000/24000000=8895999天后才正常。
    *(uint32_t*)CLINT_MTIMECMPL(0) = tick_l;
    *(uint32_t*)CLINT_MTIMECMPH(0) = tick_h;
最近编辑记录 dick2945 (2022-06-14 13:52:52)
离线

兄弟继续啊, 点个屏, 要啥接口的我都可以送你
RGB/LVDS/MIPI
我前阵子想从xboot里面学学, 可是干点别的就放下了
离线
这个板子哪里买的
离线
@dick2945 
应该是没有配置PMP物理内存保护,切换到用户模式后没权限访问内存,导致取指令错误
离线