之前拿到了一本书《ARM Helium技术指南 cortex-M系列处理器的矢量运算扩展》,由于缺乏平台验证,导致阅读效率贼低,因为书的内容全是枯燥的汇编指令怎么调用,对应的功能是什么样的。
后来瑞萨官宣发布M85核MCU,随后发布了和野火合作制作的板卡CPKCOR_RA8D1B板卡,便一直想拿这个板卡看看那号称媲美ARM NEON加速的Helium到底有多牛。
在此,非常感谢EEPW提供了这次机会,让我有一个目前市面上不多的arm v8.1m核(安谋也出了个STAR-MC2核,但通用流通的芯片还没见到)去详细了解helium技术。
资料准备
在得知可以拿到这块板卡学习后,第一时间做的就是收集资料,由于业余时间把玩的比较多的就是瑞萨和NXP的芯片,因此资料找起来也不算特别难,其中最关键的资料有:
FSP:renesas/fsp: Flexible Software Package (FSP) for Renesas RA MCU Family
Keil pack:Arm Keil | Renesas RA_DFP
cpkcor_example: renesas/cpk_examples: CPK板样例代码 Sample Codes China Promotion Kits
datesheet等:Arm Keil | Renesas RA_DFP
搭建实验平台
硬件分析
CPKCOR_RA8D1B板卡上的板载MCU为R7FA8D1BHECBD,通过查阅瑞萨官方资料,发现这颗芯片属于除RA8T系列以外的最强系列,拥有板载的2MB存储和1MB的RAM。
除了MCU外,板卡还搭载了一系列的外设,如TF卡座,USB HS接口,16MB的flash,32MB的SDRAM,两个Key(Reset Key和 User Key)。除此以外,板卡还将未使用到的管脚通过2.0PIN金针和BTB公座引出,以便扩展至底板做更多功能的使用。
另外,板卡还搭载了由RA4M2制作的全功能Jlink,方便在线调试。
从原理图上可以发现,板载的调试接口是支持串口的jlink,而jlink所接的串口是P408和P409这一组,因此创建初始环境,仅需要建立工程,并把串口打印打通即可。
软件配置
环境安装
可以参考瑞萨的板级配置工具FSP安装及界面简要介绍-电子产品世界论坛,唯一需要注意的是,FSP的版本不再是4.4,而是5.1版及以上的版本,原因是只有5.1版以后的版本才有RA8D1的配置信息。
基础工程搭建
启用Renesas RA Smart Configurator后,选择工程名和工程保存路径后点击Next
在弹出的界面后依次选择模板,芯片以及编译器选项,选择完毕后点击Next
选择Flat(Non-TrustZone) Project后点击Next
选择No RTOS后点击Next
在弹出的界面中点击Finish,此时基础工程就已经建立起来了。
针对板卡修改
晶振主频更换
由于板载晶振是24M主频,而RASC生成的基础工程默认是20M,因此在创建基础工程后,需要对应的把主频信息更改为24M,并对应的微调报错的时钟配置。
这部分选完,clock部分的报错就没有了。
串口配置
通过图形界面查看P408和P409的串口分组可以发现,P408和P409属于UART3分组,因此我们配置是按照UART3配置便可打通串口。
具体查询方法如下:
具体配置步骤
熟悉RASC配置的人加外设,都会直接从Stacks上开始往下配置,原因是Stacks是所有片上外设的入口(除了不需要依赖片上外设框架的pin),因此我们的串口配置也是从这里开始配置。
此时会报错,提示SCISPICLK/SCICLK未启用,此时需要回到CLocks页面,把该时钟启用
之后回到Stacks界面,继续配置串口
添加RX RX的DTC驱动
这样,串口配置也配置完毕了
生成代码
点击Generate Project Content生成工程后关闭RASC
编写代码
串口配置修改完成后,就需要编写串口打印代码了,具体修改如下:
增加串口打印模块
bsp_debug_uart.c
此文件主要做了两件事,一件是printf重定向,另一件是对接FSP框架,实现串口通信。
#include "bsp_debug_uart.h" #define DEBUG_UART_CTL g_uart3_ctrl #define DEBUG_UART_CFG g_uart3_cfg void Debug_UART_Init(void) { fsp_err_t err = FSP_SUCCESS; err = R_SCI_B_UART_Open (&DEBUG_UART_CTL, &DEBUG_UART_CFG); assert(FSP_SUCCESS == err); } volatile bool uart_send_complete_flag = false; void debug_uart_callback (uart_callback_args_t * p_args) { switch (p_args->event) { case UART_EVENT_RX_CHAR: { break; } case UART_EVENT_TX_COMPLETE: { uart_send_complete_flag = true; break; } default: break; } } /* redirect printf */ #if defined __GNUC__ && !defined __clang__ int _write(int fd, char *pBuffer, int size) { (void)fd; R_SCI_B_UART_Write(&DEBUG_UART_CTL, (uint8_t *)pBuffer, (uint32_t)size); while(uart_send_complete_flag == false); uart_send_complete_flag = false; return size; } #else int fputc(int ch, FILE *f) { (void)f; R_SCI_B_UART_Write(&DEBUG_UART_CTL, (uint8_t *)&ch, 1); while(uart_send_complete_flag == false); uart_send_complete_flag = false; return ch; } #endif
bsp_debug_uart.h
此文件用于在hal_entry.c中初始化调试串口
#ifndef __BSP_DEBUG_UART_H #define __BSP_DEBUG_UART_H #include "hal_data.h" #include "stdio.h" void Debug_UART_Init(void); #endif
hal_entry.c
此文件的修改主要是添加串口初始化,以及增加打印信息,以便确认串口调试调通
...... #include "bsp_debug_uart.h" ...... /*******************************************************************************************************************//** * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function * is called by main() when no RTOS is used. **********************************************************************************************************************/ void hal_entry(void) { /* TODO: add your own code here */ Debug_UART_Init(); printf("debug uart init OK\n\r"); ...... while(1) { ; } } ......
代码编译下载
编译没啥好说的,和其他平台一样,点击build按钮就可以编译了,这里主要讲的是下载部分。
此界面中的器件,务必更换后再更换回来再保存,否则下载时会报flash分区异常,应该是RASC的bug。
以上部分修改完毕后就可以下载代码了。
效果验证
在烧录完软件后,串口收到如下打印信息,表示调试串口已经调通。