学习一个新的MCU也好,MPU、FPGA或DSP也好,个人觉得能快速入门的大概有3个方面:
1)、开发环境的安装与熟悉;
2)、芯片的系统架构;
3)、芯片的时钟系统;
通过以上3方面的了解后,再进行各个模块的细节学习,就能够从整体到细节更深入的了解各个子模块了。
其中开发环境的安装与熟悉在之前已经完成了,其他坛友的分享也很详细,接下来详细讲解一下系统框图和时钟系统。
1、HPM5361系统框图
HPM5361的系统框图如下图所示。
只能看到个大概,比如整个芯片有哪些模块、各模块属于的域等。看不到各个模块之间、CPU和模块间、总线的互联情况,这方面国外主流厂商,如ST、NXP等,或国内某些MCU厂家相比还是略显不足,如雅特力等。下图分别为ST和雅特力的系统框图。
HPM5361这样简单的系统框图不太利于对各个模块的时钟链、数据链的理解和梳理,增加了对SDK中代码理解的难度。
2、HPM5361时钟详解
时钟信号为芯片内部系统提供准确的、稳定的时序信号以确保芯片系统内部各个电路的同步操作,以实现正确的功能,其重要性不言而喻了,所以个人认为需要一个芯片的时钟系统不仅很重要,也有助于快速入门一个新的芯片的开发工作。
HPM5361用户手册中描述其时钟系统是有时钟源和功能时钟组成,如下图所示。
可以从上图中看到HPM5361对其时钟系统的描述还是非常简单,需要特别注意的是选用外部时钟源时,可以是振荡器(无源晶振)或者是谐振器(有源晶振)。
相对于其他ARM Cortex-M内核芯片厂商时钟框图如下图所示,HPM5361的就略显简单,即使对照这代码都一些地方都不是太理解。
2.1、锁相环PLL
HPM5361内置2个PLL用以生成系统需要的各种频率的时钟,其中PLL0有3路,PLL1有4路独立分频输出,这种配置给先楫半导体点个赞。因为在大部分ARM Cortex-M内核的芯片上,锁相环的输出路数较少,经常会造成想要跑满主频而某些功能用不了,如USB,这种情况就会非常尴尬,不能发挥芯片的最大性能,而先楫半导体就完美的规避了这种情况。
锁相环的配置主要是配置PLL的参考时钟、工作频率、扩频功能、输出分频,且支持运行时修改。
PLL参考时钟选择有XTAL或RC24M两个选项,PLL的压控振荡器输出频率
*Fvco * = *Fref * ×( *MFI * +( *MFN * ÷ MFD )),其中MFD不支持运行时修改,如果需要修改,则在PLL关闭再打开后生效。
PLL分频器的输出 *Fout * = *Fvco * ÷ (1 + 0.2 × DIV ),其中DIV支持工作是修改。
2.2、功能时钟
HPM5361的每一个功能时钟都有8个时钟源选择,通过8选1的多路选择器实现,并且每个功能时钟都可单独设置其分配系数,对其选择的时钟源进行分配,分频系数范围从1到256的任意整数,其时钟源和功能模块的时钟源选择/分频系数分别见下图所示。
HPM5361功能时钟的时钟源的灵活选择再加上较大的时钟分频系数,给整个系统设计带来了极大的便利,特别是需要多个特殊外设同时工作或需要兼顾性能及功耗平衡的需求的情况下,这种设计能最大程度上满足这些特殊的需求,以达到设计的多样性和特殊性。
HPM5361会有一部分特殊的功能模块,该类功能模块没有使用功能时钟而是直接使用时钟源,包括电源管理域的全部模块,部分系统电源域的计时模块,如下图所示。
此外HPM5361功能模块的分频系数和时钟源选择都是支持运行中(on-the-fly)修改的,这种设计也对于需要做功耗管理是非常有帮助的,可以在不影响系统当前功能的前提下完成动态修改是很符合实际应用的。
2.3、低功耗
低功耗的实现一般有两个维度的处理:1)、关闭特定域电源;2)、关闭特定模块的时钟或降低时钟频率;
这里主要是着重将对时钟的处理。不同的内核和芯片的设计,芯片最终的工作模式可以有多种,但至少会有3种,一般包括运行模式、停机模式、休眠模式。而HPM5361有5种工作模式分别为:运行模式、等待模式、停止模式、休眠模式、关机模式,如下图所示。
3、HPM5361 时钟配置相关代码
大致看一下HPM5361的启动流程,以GCC为例,在start.S汇编文件中的_start函数,前面很长一段都是在设置相应的环境,然后通过reset_handler函数调用时钟初始化、进入main函数等功能,如下图所示。
可以从先楫半导体提供的SDK中的代码看到HPM系列的时钟配置都是在board.c源文件中的board_init函数完成的。所以想要修改系统上电初始化的时钟配置只需在board.c中完成修改即可。
下面是board_init_clock中用的时钟相关函数。
clock_get_frequency:获取对应时钟名的频率;
pllctlv2_xtal_set_rampup_time:设置外部晶振斜升时间;
sysctl_clock_set_preset:选择时钟设置预设,没太清楚具体作用;
clock_add_to_group:添加某个时钟到时钟组;
clock_connect_group_to_cpu:连接时钟组到CPU;
pcfg_dcdc_set_voltage:设置DCDC的输出电压;
sysctl_config_cpu0_domain_clock:设置CPU0域的时钟;
pllctlv2_set_postdiv:设置锁相环某一路输出分频系数;
pllctlv2_init_pll_with_freq:设置锁相环Fvco的输出频率;
clock_update_core_clock:更新CPU核的时钟频率;
clock_set_source_divider:设置功能模块的时钟源和分频系数;
4、小结
在这之前本人使用的芯片大部分都是ARM内核的,刚开始是ST,接着是TI的,再到后来的NXP,最近几年切了几家国产。由于有使用ST的经验,而且国产ARM Cortex-M内核的芯片的库基于都是按照ST的标准库来写的,所有上手其来会比较快,有的国产甚至敢宣传不改软件直接烧录。
我相信大部分坛友和我相似,之前接触到的RISC-V内核的芯片比较少或比较浅显,在切换到先楫半导体HPM系列时会花费多一些的力气。总体感觉上,先楫半导体的RISC-V半导体相对国内其他家的RISC-V芯片上手难易程度还偏高一些,如沁恒微电子的整体风格偏ST的标准库,所以大部分开发者上手的速度会加快和难度会降低一些。
虽然现在国内各家RISC-V内核芯片差异较大,还存在编译出来的代码密度没有ARM内核高,但其免费的内核带来的高性价比和无限的潜能是足够吸引足够多的开发者和芯片厂商参与进来,推动其发展壮大。
同时也希望以先楫半导体为代表的高性能RISC-V内核的MCU厂家后续进一步完善用户手册和提供更多的应用手册,提供更完善的生态,不仅做到高性能MCU的国产替代,还做到好用、易用。呼吁大家一起为RISC-V贡献一份微薄之力。