并行多线程处理器MC3172简介与实践

摘要:最近,朋友送了块小板子,板子上的mcu是个很有意思的东西——并行多线程处理器mc3172 。通俗地说,这颗mcu的内部实现了类似rtos多线程的功能。但是mc3172 编程与rtos编程的最大区别就是:
mc3172多线程绝对并行运行,没有切换抖动及开销。
mc3172无线程优先级、优先级反转、死锁等概念。
mc3172所有中断都可以安排专门线程处理,没有中断嵌套和延迟。
mc3172各线程同步并行运行,互不阻塞,互不干扰。
mc3172线程响应的确定性相对于rtos更为精确。
mc3172简介 mc3172 是厦门感芯科技的一款32 位 risc并行多线程实时处理器。基于risc-v rv32imc 指令集, 100%单周期指令,最高200mhz主频,3.37coremark/mhz。可以代替实时操作系统, 实现程序的模块化与复用性。
相关资料可在感芯官网下载。链接:
http://www.gxchip.cn/ mc3172 特性:
mc3172实践 mc3172的开发环境使用的是国产软件——mounriver studio。
mounriver studio下载链接:
http://www.mounriver.com/download 我们简单看一下mc3172的demo工程:
1、mc3172文件夹 mc3172存放mc3172编程核心文件。
线程配置工具可对各线程进行配置:
可以配置线程时钟源、频率、栈空间、存储器分配等信息。
mc3172支持64路线程同步并行运行,  其中分为4个线程组,每个线程组16线程,每个线程组里的线程编号如上图所示。其中,不使用的线程可以设置为空闲线程,空闲线程完全不运行,不产生功耗。
每个线程都有自己独立的栈空间 ,在数据空间允许范围内可随意分配,但需要确保所有非空闲线程所占的数据空间不超过数据空间的大小。
mc3172.h存放外设地址相关宏定义及其配置宏,如:
类似于st的stm32fxxx.h。
thread_config.h为线程配置文件,由线程配置工具生成:
mc3172.lds为链接脚本,由线程配置工具生成
thread_start.c为启动线程相关的源文件:
#ifndef thread_start_c#define thread_start_c#include ./mc3172.h#include ./thread_config.hvoid thread1_initial(void){#ifdef rothd_thread1_validextern void thread1_main(void);    rothd_set_sp_const(rothd_thread1_stackcfg_value|0x20000000);    thread1_main();#endif}void thread2_initial(void){#ifdef rothd_thread2_validextern void thread2_main(void);    rothd_set_sp_const(rothd_thread2_stackcfg_value|0x20000000);    thread2_main();#endif}// 省略部分代码......void (*thread_initial_pointer[64]) (void)={                                               &thread0_initial,                                               &thread1_initial,                                               &thread2_initial// 省略部分代码......}void thread_start(void){    (*thread_initial_pointer[thread_id])();} 程序运行的入口函数为:thread_start ,从链接脚本里可以知道:
thread_start里的thread_id为线程id值,直接从0x50000000地址中读出:
#define thread_id (*(volatile u8*)(0x50000000)) 猜测:0x50000000地址里的id值会不断变化,通过某种机制跳转,遍历执行thread_initial_pointer函数指针数组里的各个线程函数。
threadx_initial里初始化线程栈,并执行线程主体,如
void thread_end(void){    while(1);}void thread1_main(void){    while(1){        //user code section    }    thread_end();} 这是用户代码,我们可以在各个线程主体函数里边编写我们的应用代码。
2、release文件夹 release文件夹里存放的是编译生成的固件程序,通过 开发板程序下载工具 可进行下载:
3、user_code文件夹 user_code文件夹存放用户代码:
mc3172是一颗并行并行多线程实时处理器,我们下面来看看其多线程并行执行的特性。
我们编写两个线程,线程进行相同的配置,两个线程分别对两个io进行翻转,测试代码如:
void led0_gpioa_pin0_test(void){ // 启动gpioa并设置特权组及时钟频率    intdev_set_clk_rst(gpioa_base_addr,(intdev_run|intdev_is_group0|intdev_clk_is_coreclk_div2));    // 使能gpioa pin0引脚    gpio_set_output_en_value(gpioa_base_addr, gpio_pin0, gpio_set_enable);    while(1)    {     // gpioa pin0输出1     gpio_set_output_pin_to_1(gpioa_base_addr, gpio_pin0);     // 延时        for (u32 var = 0; var < 5000; ++var)        {            nop();        }        // gpioa pin0输出0     gpio_set_output_pin_to_0(gpioa_base_addr, gpio_pin0);     // 延时        for (u32 var = 0; var < 5000; ++var)        {            nop();        }    }}void led1_gpioa_pin1_test(void){ // 启动gpioa并设置特权组及时钟频率    intdev_set_clk_rst(gpioa_base_addr,(intdev_run|intdev_is_group0|intdev_clk_is_coreclk_div2));    // 使能gpioa pin1引脚    gpio_set_output_en_value(gpioa_base_addr, gpio_pin1, gpio_set_enable);    while(1)    {     // gpioa pin1输出1     gpio_set_output_pin_to_1(gpioa_base_addr, gpio_pin1);     // 延时        for (u32 var = 0; var < 5000; ++var)        {            nop();        }        // gpioa pin1输出0     gpio_set_output_pin_to_0(gpioa_base_addr, gpio_pin1);     // 延时        for (u32 var = 0; var < 5000; ++var)        {            nop();        }    }}////////////////////////////////////////////////////////////void thread_end(void){    while(1);}////////////////////////////////////////////////////////////void thread0_main(void){    while(1){        //user code section    }    thread_end();}////////////////////////////////////////////////////////////void thread1_main(void){    while(1){        //user code section     led0_gpioa_pin0_test();    }    thread_end();}////////////////////////////////////////////////////////////void thread2_main(void){    while(1){        //user code section     led1_gpioa_pin1_test();    }    thread_end();} 烧录程序,使用逻辑分析仪抓取gpioa_pin0及gpioa_pin1引脚电平变化如:
可见,这两个波形是完全同步的,cpu同时在干两件事情,实现了与rtos多线程同样的效果。
心得与总结 嵌入式开发,是软件+硬件结合,两者互补。如果硬件功能很强大,则软件可能可以设计得比较简单;如果硬件功能有限,则软件方面可能得考虑比较多的方面。
比如:
一些软件算法,需要多传感器数据输入进行融合,则功能实现可能比较简单,但实际可能为了降成本,减少一些传感器,这时候需要实现稳定可靠的功能,则软件算法上得下更大的功夫。
对于一些不太复杂的数字信号处理,在通用的mcu上就可以处理,但对于一些比较复杂的数字信号处理,则可能使用一些带有dsp处理器的mcu。
特别的,对于芯片内部ic电路来说,如果内部有相关模块可以实现某些功能的话,则对应的软件编程会简单很多,而且硬件实现的比软件实现的效率要高。
硬件实现的多线程编程确实优于rtos编程,但实际开发中产品软硬件架构需要考虑多个方面,比如芯片的稳定性以及软件生态等方面。
并行多线程实时处理器是个好东西,但目前并行多线程实时处理器还处于起步阶段,还有很多东西需要完善,需要我们多支持与传播,只有生态起来了,将来我们才有机会用得上。


87N-3000A-8C压力传感器的市场领域
鸿蒙系统手机测试一直进行中,Mate 30准备就绪
售价三万的华为Mate9 Pro保时捷版买不到?Mate9 Pro也很不错
2021年一定要关注的10大技术里程碑
浅析漏水检测短信报警漏水远程监控报警系统
并行多线程处理器MC3172简介与实践
定制大功率电感要注意什么
风向风速监测在环境中的应用是怎样的
MDK-ARM编译器从V5升级到V6需要做哪些工作 ?
典型的线性音频放大器拓扑结构
多灵P8智能门锁评测:首款接入苹果HomeKit的智能门锁
光通信市场现低迷?光传输市场微增1%~3%
CAN总线中循环冗余校验码的原理及其电路实现
回馈式直流负载正负极接反怎么办?
怎么选择性价比高的激光器?
三星计划2021年开始量产QNED面板
沈阳开发区化工园水厂自动控制系统的构建分析
整车厂商和一级供应商应如何保护互联汽车的数据安全
中国信息通信研究院采用罗德与施瓦茨CMX500 OBT和SPEAG设备用于5G SAR以及HAC测试
伺服电动机控制技术与步进电动机的区别