RCSN

个性签名:

1084534438 欢迎交流  [加油,一切皆有可能]

  • 2024-06-15
  • 发表了主题帖: 《RISC-V 开放架构设计之道》- RISC-V开放架构设计简读

    一、前言 感谢eeworld电子工程世界提供《RISC-V开放架构设计之道》书籍测评,书中并没有过多繁琐介绍riscv的概念,也没有过多强调riscv的好处,更多介绍的是riscv的简洁、免费、开放的思想。 如同书中一位大佬推荐所说的:这本方便的小书轻松地总结了RISC-V指令集架构所有的基本要素,是学生和从业者的完美参考指南。 RISC-V,是比较大体、宽泛的概念,但是书中内容很简短,内容插入了不少插图以及RISCV的参考卡,说是参考指南一点也不过分;加之目录介绍很清晰,从riscv32的基础整数指令集RV32I、乘法和除法指令集M扩展、原子指令集A扩展、单双精度浮点数指令集RV32F/RV32D、压缩指令RV32C、以及汇编语言和向量RV32V。以及后续的RV64介绍。 而刚好先楫的处理器作为典型标准的RISCV处理器,当然也支持上述的指令集,并且还有所扩充。以实际的硬件进行书籍分享是最好不过的思路了。比如先楫的HPM5300系列。   本系列文章更多是讲一些基础只知识,利用HPM5300EVK配合SEGGER Embedded Studio这个IDE通过查看机器码和汇编来分析RISCV的一些指令集,以此能对riscv有一定的了解兴趣。 本书内容目录比较多,系列文章定期分享RISCV的每个指令集基础。 二、导读 如果想要接触riscv,那么典型的reference card(参考卡)不可或缺,你会发现相比其他的指令集架构,riscv真的相对简洁了不少(基础的就只有两页),而且操作码7位,相当可自由扩充127个扩展指令,这也是riscv的开放自由思想。这里截图一小部分,需要了解的可以搜下riscv cheat sheet。 链接:https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdf   (一)RV32I指令格式   如书中描述,RV32I 基础指令集的一页图形表示。 对于每幅图, 将有下划线的字母从左到右连接起来,即可组成完整的 RV32I 指令集。对于每一个图,集合标志{}内列举了指令的所有变体,变体用加下划线的字母或下划线字符_表示。特别的,下划线字符_表示对于此指令变体不需用字符表示。 例如,下图表示了这四个 RV32I 指令: slt, slti, sltu, sltiu:   书中展示了6种基本指令格式,分别是用于寄存器-寄存器操作的 R 类型指令,用于短立即数和访存 load 操作的 I 型指令,用于访存 store 操作的 S 型指令,用于条件跳转操作的 B 类型指令,用于长立即数的 U 型指令和用于无条件跳转的 J 型指令。   这里使用最简单的U类型种的lui指令,配合利用HPM5300EVK配合SEGGER Embedded Studio来进行说明上述所说的指令格式是什么意思。 随便打开hpm_sdk一个例子,从左边的汇编窗口找到lui的汇编,比如以下: 可以看到,ses这个IDE对于汇编和机器码呈现还是是否直观的,对于不熟悉gdb调试又想查看汇编的开发者是十分友好的。 对于左边的8000452a指的是存储到flash的机器码的flash地址,中间的E40007B7就是机器码,最右边就是汇编部分。 hpm单片机支持压缩指令集RV32C,所以机器码有些会是16位,这对于固件空间的缩小利用是有一定帮助的。   可以分析下E40007B7这个机器码对应的Lui指令格式,如下图可看到 E40007B7的低7位代表操作码opcode,也就是lui的操作码(0b0110111),7到11bit是5位目的寄存器(0b01111),这很奇妙,5bit宽度刚好是32,对应的就是寄存器的长度(32bit),换成十六进制就是15,对应的通用寄存器就是X15,也就是别名a5寄存器。 高11位就是立即数,对应的十六进制就是0xE4000,最终根据该机器码可以反汇编得到: 把一个20位的立即数0xE4000加载到a5寄存器,对应的汇编指令就是:lui a5, 0xE4000,刚好可以对上ses IDE的汇编显示。   (二)RISCV通用寄存器 无论是RISCV32还是RISCV64,他的通用寄存器的数量都是32个,分别是x0~x31,当然为了方便汇编编写,每个寄存器也有别名,在参考卡中如下:   RISC-V 有足够多的寄存器来达到两全其美的结果:既能将操作数存放在寄存器中,同时也能减少保存和恢复寄存器的次数。其中的关键在于,在函数调用的过程中不保留部分寄存器存储的值,称它们为临时寄存器;另一些寄存器则对应地称为保存寄存器。不再调用其它函数的函数称为叶函数。当一个叶函数只有少量的参数和局部变量时,它们可以都被存储在寄存器中,而不会“溢出(spilling)”到内存中。但如果函数参数和局部变量很多,程序还是需要把寄存器的值保存在内存中,不过这种情况并不多见。 这里说明下caller是调用者,调用(或执行)一个函数的代码段或者函数,是主动发起函数调用的一方,可以理解是"甲方"。 callee是被调用者,被调用的函数本身,是被动接收函数调用并且执行对应操作的一方,可以理解是"乙方"。 从上面的表格知道,从通用寄存器上看,X0到X31,调用者需要保存的通用寄存器16个,剩下的是被调用者需要保存的寄存器。 这里可以从函数调用阶段来进行说明通用寄存器的作用,配合利用HPM5300EVK配合SEGGER Embedded Studio,使用helloworld例子来说明。 函数调用基本分为以下几个阶段,在书中也提到:   1、进入到被调用者函数的开始位置(caller需要保存的)   2、将函数传参存储到指定寄存器上 这里就是上图的x10~x17,相比其他指令集架构参数依赖于内存,也就是需要保存在栈中,riscv反而可以通过寄存器保存参数,最多可以存储8个参数,当然超过的也会存储到内存中。一般应用还是推荐不要多余8个参数传参。 那么我们进入到board_timer_create API中,传参是300和board_led_toggle函数指针。那么将会存储在x10和x11这两个寄存器上。     可以看到,x10现在是300,是符合预期的,对于x11是0x8000669e,我们可以在SES IDE中的汇编窗口查到该函数地址。 0x8000669e对应的就是board_led_toggle,这也是符合预期的。   3、获取函数局部资源变量保存在寄存器,并执行函数中的指令,可以看到寄存器窗口会发生不同的赋值变化 4、执行完毕之后将返回值存储到调用者能够访问的位置(X10寄存器),恢复寄存器,出栈释放局部资源 5、返回进行下一个调用函数位置。 在ses IDE中也展示了main调用者主函数调用被调用者函数的一些汇编代码过程。   三、总结 1、riscv的书籍众多,RISC-V开放架构设计之道这本书籍值得阅读,书中内容简洁但又不缺完整,而且丰富的参考卡可作为riscv的日常参考指南所用 2、对于技术书籍,需要有一个实操机会可以加深印象,先楫的处理器内核遵守risv规范,具有多种扩展指令集,而其配套的SEGGER Embedded Studio这个IDE通过查看机器码和汇编,让一些不熟悉gdb调试的开发者,是一个值得推荐的实操平台。

  • 2024-06-04
  • 回复了主题帖: 先楫开发板HPM6360EVK下载,GDB连接失败 Connecting ‘GDB Server’ using ‘local...

    估计Openocd在后台运行,杀掉这个后台吧,任务管理器打开找下用户的运行后台,找到openocd.exe,点结束任务。

  • 2024-05-24
  • 回复了主题帖: 共读入围:《RISC-V开放架构设计之道》

    个人信息无误

  • 2024-02-27
  • 回复了主题帖: 【先楫HPM6750EVK2测评】求教SGGER Embeded Studio中jlink如何配置

    lugl4313820 发表于 2024-2-27 14:19   连接是成功的,但是go了以后就提示这个。 请用start_gui工具生成,不要用ses本身的csp生成,入门不合适。

  • 回复了主题帖: 【先楫HPM6750EVK2测评】求教SGGER Embeded Studio中jlink如何配置

     

  • 2024-02-22
  • 发表了主题帖: 《RT-Thread设备驱动开发指南》进阶篇--动手驱动先楫LCD外设

    一、概述 经过上一篇的《《RT-Thread设备驱动开发指南》基础篇--以先楫bsp的hwtimer设备为例》阐述,可以大致了解到RT-thread设备驱动开发的方法步骤,开发指南中的进阶篇外设主要是比基础篇外设复杂点的外设设备,分别是SDIO、Touch、LCD、sensor、MTD nor、MTD nand、脉冲编码器、加解密设备、PM设备。 对于进阶篇的外设,本文不对先楫已经支持的进阶外设进行阐述,而是进行一次动手实践驱动一个先楫尚未适配的驱动外设-LCD,来更加深入开发RT-thread的设备驱动。   二、开发方法 (一)RT-thread的LCD驱动框架介绍 LCD驱动,跟其他外设也类似,无非就是IO设备管理框架-->LCD设备驱动框架->LCD设备驱动。 IO设备管理层主要为设备框架提供统一的操作接口,包括rt_device_read/write/open/close/control等。而做好一个外设驱动,最终的目标就是应用上使用这些统一操作接口,无需理会底层操作。 LCD设备驱动框架层是RT-thread对LCD基本功能的抽象,是一层通用的软件层,和硬件平台无关,抽象了LCD设备的类型定义和具体的操作方法,其框架源码在rtdef.h中 LCD的信息结构 rt_device_graphic_info,定义了像素格式,位宽,宽高、显存地址等。   LCD的操作接口rt_device_graphic_ops,定义了LCD的绘图操作,比如像素点、画线等操作。   LCD的控制命令,比如更新显存、开关LCD、获取信息、等待VSYNC等。   LCD的像素格式   可见,RT-thread对于LCD的抽象操作还是比较直观,完成以上的操作,再借助IO设备管理层提供的注册接口rt_device_register进行注册,即可使用IO设备管理接口操作LCD。 (二)先楫LCDC外设介绍 对于先楫的LCDC外设硬件控制器 在HPM6750上有RGB控制器,支持24位的RGB显示接口   在HPM6800上,支持2 个 4 Lane MIPI-DSI/LVDS-Tx 显示接口   对于在RT-thread上,也支持了hpm_sdk的panel组件,涵盖了hpm6750和hpm6800的显示适配。   对于hpm_sdk的panel组件介绍,可以参考文章《[hpm_application]选先楫!爽跑1080P or 720Pmipi屏的单片机》 对于使用LCD硬件控制器(RGB,MIPI DSI)通信的屏幕,LCD设备驱动只需要实现LCD设备的操作方法struct rt_device_ops即可,比如control接口里更新硬件控制器的缓存区即可控制屏幕绘图。 如此一来,配合先楫适配好的RT-thread BSP,可以很顺手得适配好LCD的驱动,按先楫BSP的driver照葫芦画瓢个drv_lcd。   (三)创建LCD设备 下面来创建先楫的LCD设备。LCD设备模型从struct rt_device结构体中派生,并添加自己的私有数据。 成员主要有LCD的基地址,中断号,互斥锁,LCD名称等。   实例化一个lcd的设备数组,可以存在多个lcd设备,里面包含设备的初始化参数。   (四)实现LCD设备的操作方法 按照以上的定义,已经实例化了一个hpm_lcd_ops结构体,然后需要实现对应的操作函数,也就是LCD设备定义操作方法。对于LCD设备来说,只有其中的init和control操作方法才有意义,而本文实现的也是这两个接口,分别是hpm_lcd_init、hpm_lcd_control。 1、init:初始化LCD设备 对于该操作方法,先楫的LCD驱动代码不需要执行任何操作,只需要在注册初始化LCD即可。   2、control:控制LCD设备 应用程序也可以对LCD设备进行控制,通过control方法完成。原型如下:   其中参数cmd包含了控制LCD的方式,通用设备命令可取以下宏定义:   当然在最新的rtthread 5.0.2当中也更新了几个命令   本文在这里主要实现以下几个命令 (1)RTGRAPHIC_CTRL_RECT_UPDATE 更新显存 对于显存的更新,可以使用控制器自身定义的显存也可以使用传入的显存地址,在先楫的手册中有提到影子寄存器加载使能功能,也就是显存会在下一个VSYNC到达加载,这样可以做到显示的完整更新。   而在hpmicro的驱动中也提供了该API:lcdc_layer_set_next_buffer,这里适配的驱动使用第一层layer。 故可以下实现:   (2)RTGRAPHIC_CTRL_WAIT_VSYNC 等待帧完成 为了保证传输的高效和防撕裂,这里使用中断方式传输一帧,再下一帧更新之前等待VSYNC完毕。   (3)RTGRAPHIC_CTRL_GET_INFO 获取LCD信息 主要获取LCD的像素格式、宽高等,传递给args参数   (4)RTGRAPHIC_CTRL_POWERON 和RTGRAPHIC_CTRL_POWEROFF 亮屏和息屏 调用hpm_sdk的panel组件接口即可。   (五)注册LCD设备 使用IO设备框架的rt_device_register完成注册,主要关注设备操作方法的赋值部分,以及保存lcd设备示例赋值给lcd的user_data成员。   (六)驱动配置 在board的Kconfig中使能LCD,该宏控制LCD驱动相关代码是否添加到工程中   另外添加panel组件,该宏先楫已经实现,这里使用的是hpm6750,故只有RGB接口。   在驱动drivers的SConscript文件添加LCD驱动的判断选项,如果使能,drv_lcd.c则会被添加到工程中。   (七)驱动验证 注册设备之后,LCD设备将会在IO设备管理器中出现,我们使用hpm6750evkmini的wifi_web_camera_demo这个官方示例作为验证,烧录验证,使用list device命令查看到注册的设备已经包含了LCD设备。   在wifi_web_camera_demo的示例上,在获取camera图像的接口中,添加lcd的设备操作,把图像显示到LCD上,只需要先打开lcd,然后进行control,两条语句就可以实现显示,特别方便操作。   最终可以实现使用简单的IO设备即可操作LCD    

  • 2024-02-19
  • 发表了主题帖: 《RT-Thread设备驱动开发指南》基础篇--以先楫bsp的hwtimer设备说起

    一、概述 (一)RT-Thread设备驱动     《RT-Thread设备驱动开发指南》书籍是RT-thread官方出品撰写,系统讲解RT-thread IO设备驱动开发方法,从三方面进行讲解。     基础篇:对RT-thread以及设备框架进行介绍,再分别介绍基于IO框架中常用的外设设备,分别是UART、PIN、SPI/QSPI、HWTIMER、PWM、RTC、ADC、DAC、WDT。     进阶篇:介绍基于IO框架中稍比基础篇复杂的外设设备,分别是SDIO、Touch、LCD、sensor、MTD nor、MTD nand、脉冲编码器、加解密设备、PM设备。     高级篇:介绍更为复杂的外设设备,分别是WLAN、ETH、audio mic、audio sound、USB、CAN。   (二)先楫hpmicro bsp     为了深入了解本书的内容,得有一个单片机平台进行案例剖析,除了本书籍以STM32的arm平台进行介绍,还可以以先楫hpmicro单片机系列的riscv平台进行讲解。     刚好先楫在rtthread的bsp贡献上,也是十分丰富。无论是在rtthread studio的bsp包上,还是rtthread仓库的bsp支持上,都有提供了对应的支持。     rtthread studio的SDK支持,包括了先楫目前所有的MCU系列。            而在RT-thread上,bsp包的驱动支持上,也包括了rtthread大部分设备驱动。         二、开发方法 (一)层级结构     RT-Thread 提供了一套简单的 I/O 设备模型框架,如下图所示,它位于硬件和应用程序之间,共分成三层,从上到下分别是 I/O 设备管理层、设备驱动框架层、设备驱动层。            而作为单片机的定时器外设hwtimer功能,要对接到该IO设备框架,需要实现hwtimer设备的操作方法、设备的注册、以及驱动的配置和驱动验证。本文也是基于该开发方法进行阐述。     上述对应的三层驱动层,在源码上,可以device->hwtimer->drv_hwtimer,其中drv_hwtimer是先楫官方实现的对接框架的驱动层。            而设备驱动框架层,提供了ops操作接口,分别以下的接口需要驱动开发者实现注册。   (二)创建hwtimer设备     对hwtimer设备来说,在驱动开发时,需要先从rt_hwtimer_t结构中派生出新的hwtimer设备模型,然后根据自己的设备类型定义私有数据域。     同样先楫的hwtimer drivers也定义了自己的由rt_hwtimer_t派生出来的hwtimer设备。       当然一个MCU也支持多个hwtimer,一个hwtimer驱动可以支持多个hwtimer设备,可以通过使能BSP_USING_GPTMRx进行开启   (三)实现hwtimer设备的操作方法     该操作方法就是上述所说的ops操作结构,属于驱动共用部分,也就是多个hwtimer设备可以共用一个ops操作。同样先楫也实现了该操作方法,并且注册到自身的hwtimer的父类hwtimer的ops中。         简单举例个操作方法的实现,比如获取设备当前值count_get,原型如下:     rt_uint32_t (*count_get)(struct rt_hwtimer_device *timer);     而先楫实现的count_get是以上的hpm_hwtimer_count_get,可以看到,内部是先从timer获取厂家自身定义的hwtimer设备,再从里面获取硬件定时器的基地址控制句柄,然后使用先楫自身的驱动API获取定时器的计数值进行返回。   (四)注册hwtimer设备     注册hwtimer设备,rtthread的IO设备框架提供了一个API:rt_device_hwtimer_register       从传参句柄可知道,注册时需要提供设备句柄timer,设备名称name,用户自定义data作为传参。     在先楫的drv_hwtimer的驱动中,创建了个全局的hwtimer设备数组,里面包含了hwtimer的所有信息,包括设备名称。然后在注册初始化当中,轮询该数组使能的定时器设备依次注册到rtthread的hwtimer设备当中。       在开发指南当中,特别提到了一个注意点,hwtimer设备句柄需要实现rt_hwtimer_info,定义硬件定时器的特征信息,如计数的最大最小频率,最大计数值以及计数方向,而先楫也同样进行了实现。   (五)hwtimer设备中断处理     在开发指南中,该部分也需要实现,目的是将定时时间导致的中断事件通知到hwtimer设备驱动框架,让驱动框架完成后续的处理并通知应用层。而该通知事件API则是rt_device_hwtimer_isr,该函数由rtthread的hwtimer设备驱动框架提供。       MCU下的hwtimer驱动,需要在中断处理函数调用rt_device_hwtimer_isr函数,以便通知hwtimer设备驱动框架对应中断的发生。     在先楫的hwtimer驱动中也是基于这个实现通知事件。       从以上代码可知,hpmicro实现的hwtimer设备驱动接管了定时器的通用中断服务函数hpm_hwtmr_isr,然后内部调用了rtthread的hwtimer设备驱动框架提供的rt_device_hwtimer_isr中断处理函数,通知设备框架对应的定时器定时时间到达。 (六)驱动配置     1、Kconfig配置     驱动配置主要通过Kconfig实现,这里使用hpm6750evk2的bsp V1.4.1作为说明。     在board文件夹中,有个Kconfig配置了hpm6750evk2的板载驱动信息。对于定时器驱动的相关选项如下:       RT_USING_HWTIMER:RT-thread的hwtimer设备驱动框架下的代码对应的宏定义,控制hwtimer的驱动框架的相关代码是否会添加到工程中     BSP_USING_GPTMR:先楫的hwtimer驱动下的代码对应的宏定义,控制先楫的hwtimer驱动是否会添加到工程中     BSP_USING_GPTMR1: 使用先楫的定时器1     2、SConscript配置         libraries/drivers/SConscript文件为hwtimer驱动添加判断选项,如果定义了BSP_USING_GPTMR,则对应的驱动文件drv_hwtimer就会被添加到工程的源文件中。     三、驱动验证     使用hpm6750evk2的bsp V1.4.1作为说明,新建timer_demo的示例工程。       编译烧录代码,使用list_device查看设备,可以看到注册的设备已经包含了hwtimer这个设备。       运行自带的shell命令hwtimer_sample,该命令会运行5s的定时,查看readme文档       四、总结     1、基础篇包含UART、PIN、SPI/QSPI、HWTIMER、PWM、RTC、ADC、DAC、WDT这些外设,本文以先楫适配的HWTIMER驱动进行说明,能感受到先楫对于rtthread驱动适配的完整性。     2、除了本文阐述的外设,其他基础外设同样适配完整。  

  • 2024-02-04
  • 回复了主题帖: 【先楫HPM6750EVK2测评】Jlink下载出错

    检查下线吧

  • 2024-02-01
  • 回复了主题帖: HPM6750 rt-thread SPI ST7796S 驱动分享(2) __关于挂载 SPI 设备函数的提问

        默认的SPI总线使能了硬件CS,对应的cs引脚可以看pinmux.c中的init_spi_pins 这个API。     SPI device是在spi bus总线上的,可以多个spi device对应多个cs_pin。     所以无论你的SPI device设备是否开启cs_pin,对应的硬件cs都会存在。     而你的spi device设备开不开cs_pin由你自己决定。     1、如果你开了cs_pin,你都IO去操作这个cs pin。那么SPI总线上就存在硬件CS和你自己的cs_pin     2、如果你不开,那么这个SPI总线上就只存在硬件CS那个引脚。

  • 回复了主题帖: HPM6750 rt-thread SPI ST7796S 驱动分享(1)

    上月底先楫发布了rtthread bsp1.4了,支持了GET_PIN。可以考虑升级下。  

  • 2024-01-31
  • 回复了主题帖: 【年终总结颁奖】2024,让我们保持热爱,奔赴下一场山海!

    已确认个人信息无误

  • 2024-01-30
  • 发表了主题帖: 《年终总结》我的2023

    本帖最后由 RCSN 于 2024-1-30 16:28 编辑   翻了下,好像2022和2019没做总结,看了下以往的总结,感觉感慨万千,感谢eeworld从2015年毕业陪伴到现在,还有eeworld的各位大佬。 【再见2021,你好2022】2022一起践行:回首2021,展望2022 - 聊聊、笑笑、闹闹 - 电子工程世界-论坛 (eeworld.com.cn) 【2021一起践行】回首2020,展望2021 - 聊聊、笑笑、闹闹 - 电子工程世界-论坛 (eeworld.com.cn) 回首2018,展望2019 - 聊聊、笑笑、闹闹 - 电子工程世界-论坛 (eeworld.com.cn) 难忘2017-徘徊的一年 - 聊聊、笑笑、闹闹 - 电子工程世界-论坛 (eeworld.com.cn) 年终总结--充满收获,有得有失的一年 - 聊聊、笑笑、闹闹 - 电子工程世界-论坛 (eeworld.com.cn)   2015年到2022年,生活上从毕业生存、开始有存款、结婚、欠债还款之路、又开始存款。工作上,每一次的新环境,对着未来的憧憬和期待,是让我前进的动力之一。   2023年,生活多了一个小情人,让自己的生活变得更加美好,也对未来充满着希望。虽然这段时间是有点累,但是看来小情人每天的新变化,也足够开心满足。我媳妇,从一个少女变成母亲,同样很伟大,经历了产前产后的煎熬、痛苦、劳累,真心感觉媳妇很不容易。   2024年,一家三口,点点滴滴,懂得情趣,充满乐趣,不失志趣。一切安好,身体健康,万事如意。   2023年,工作上,换了个新环境,很喜欢现在的工作环境,切合自己的兴趣爱好,我想,这是我理想中的工作,很开心,我拥有了这份理想。   感谢eeworld的测评机会,我相信,认真对待每次测评,机会都在身边。   2024年,努力朝着自己的目标前进---"多记录,多折腾。"

  • 2024-01-26
  • 回复了主题帖: HPM6750驱动问题

    尹小舟 发表于 2024-1-26 10:23 我的SDK就是1.4的,就是最新的 驱动全部卸载了,再重新安装,你这驱动看起来就是老的。按照最新的env的tools来

  • 回复了主题帖: HPM6750驱动问题

    请用最新的sdk_env里面的tools驱动。如果找不到可以访问 sdk_env: hpm sdk env (gitee.com)

统计信息

已有1720人来访过

  • 芯积分:418
  • 好友:30
  • 主题:179
  • 回复:1187

留言

你需要登录后才可以留言 登录 | 注册


arkcz 2021-11-5
楼主您好,请问 还有多的硬件吗,能转让一套给我吗?
STM32F407简单视觉小板(识别二维码,数据矩阵码,apriltags,圆方形状检测) 
wml 2018-8-29
楼主,利用mjpg-streamer实现摄像头监控,我用其他电脑登录不了这个网址界面,进不去怎么回事
查看全部