0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【感芯科技64线程MC3172开发板免费试用体验】这个芯片不一样,硬件多线程MCU体验

开发板试用精选 来源:开发板试用 作者:电子发烧友论坛 2022-10-13 11:22 次阅读

本文来源电子发烧友社区,作者:李先生, 帖子地址:https://bbs.elecfans.com/jishu_2306123_1_1.html



前言

对于RTOS开发我们知道,线程调度不能太频繁,因为软件进行上下文切换需要时间,调度太频繁则调度时间占的比例会越来越大,实际运行用户代码的时间就会很少效率降低。可不可以减少这个调度时间呢,可以,感芯的MC3172就用硬件去实现了这个上下文切换个调度,使得实时性更高,用户也不需要考虑这个软件调度切换花掉的时间了。

MC3172这个芯片是一个非常大的创新,我们下面实际来体验下。

资料

http://www.gxchip.cn/down/show-70.html

https://whycan.com/f_57.html

https://gitee.com/gxchip

概述

CPU:MC3172,32 位RISC 处理器,个64线程同步并行运行。最高200MHz主频,3.37coremark/MHz。

数据段与代码段共享128K字节SRAM可配置为

96KCODE+32KDATA

64KCODE+64KDATA

32KCODE+96KDATA

开发环境

http://www.mounriver.com/download

下载MounRiver_Studio_Setup_V181.zip

安装没有什么特别的,过程略。

在http://www.gxchip.cn/down/show-70.html下下载

MC3172资料合集_v1.12.zip

分析

配置

时钟

MC3172 拥有4 个时钟源,

  • 0 内嵌 200MHz 高速RC 振荡器 默认配置。
  • 1 内嵌 8MHz 低速RC 振荡器
  • 2 外部支持 4MHz~40MHz 高速振荡器(无源)
  • 3 外部支持最高133MHz 输入时钟(有源)

线程配置工具_V1.exe工具中如下
image.png

对应的代码位于thread_start.c

**#if** ROTHD_COLCK_SOURCE_SEL==0

(*(**volatile** u32*)(0x50050108))=0x00200003;

(*(**volatile** u32*)(0x50050108))=0x00200007;

(*(**volatile** u32*)(0x50050108))=0x0020000f;

(*(**volatile** u32*)(0x50050108))=0x0020010f;

**#endif**

**#if** ROTHD_COLCK_SOURCE_SEL==1

(*(**volatile** u32*)(0x50050108))=0x00300003;

(*(**volatile** u32*)(0x50050108))=0x00300007;

(*(**volatile** u32*)(0x50050108))=0x0030000f;

(*(**volatile** u32*)(0x50050108))=0x0030010f;


**#endif**

**#if** ROTHD_COLCK_SOURCE_SEL==2

(*(**volatile** u32*)(0x50050088))=0x1d00;

(*(**volatile** u32*)(0x50050090))=0xff000000;

(*(**volatile** u32*)(0x50050098))=0x00000000;

(*(**volatile** u32*)(0x50050108))=0x00000003;

(*(**volatile** u32*)(0x50050108))=0x00000007;

(*(**volatile** u32*)(0x50050108))=0x0000000f;

(*(**volatile** u32*)(0x50050108))=0x0000010f;

**for** (u8 var = 0;  var < 64; ++ var)

{

(*(**volatile** u32*)(0x50050090))=0xff000000+var;

(*(**volatile** u32*)(0x50050098))=0x00000001;

(*(**volatile** u32*)(0x50050098))=0x00000203;

**while** ((((*(**volatile** u8*)(0x500500ca)))&0x80)==0);

**while** ((((*(**volatile** u8*)(0x500500ca)))&0x80)!=0);

**if** ((((*(**volatile** u16*)(0x500500c8))))>16380){ **break** ;}


}


**#endif**

**#if** ROTHD_COLCK_SOURCE_SEL==3

(*(**volatile** u32*)(0x50050108))=0x00100003;

(*(**volatile** u32*)(0x50050108))=0x00100007;

(*(**volatile** u32*)(0x50050108))=0x0010000f;

(*(**volatile** u32*)(0x50050108))=0x0010010f;

**#endif**

线程频率

64 个线程每个线程最高可以运行在主频的1/4,最低是主频的1/1024,

不使用的线程可设置为空闲,空闲线程完全不运行,也不产生功耗。64 个线程分属4 个线

程组,每个线程组的最高主频份额不能超过主频的1/4。

实际上可以理解为64个线程去共享主频分时执行。

线程配置工具_V1.exe工具中如下
image.png

对应的代码位于thread_start.c

**#ifdef** ROTHD_THREAD1_VALID

    *( **int** *)(THD_TS_ADDR+8)=ROTHD_THREAD1_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD2_VALID

    *( **int** *)(THD_TS_ADDR+16)=ROTHD_THREAD2_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD3_VALID

    *( **int** *)(THD_TS_ADDR+24)=ROTHD_THREAD3_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD5_VALID

    *( **int** *)(THD_TS_ADDR+40)=ROTHD_THREAD5_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD6_VALID

    *( **int** *)(THD_TS_ADDR+48)=ROTHD_THREAD6_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD7_VALID

    *( **int** *)(THD_TS_ADDR+56)=ROTHD_THREAD7_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD9_VALID

    *( **int** *)(THD_TS_ADDR+72)=ROTHD_THREAD9_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD10_VALID

    *( **int** *)(THD_TS_ADDR+80)=ROTHD_THREAD10_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD11_VALID

    *( **int** *)(THD_TS_ADDR+88)=ROTHD_THREAD11_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD13_VALID

    *( **int** *)(THD_TS_ADDR+104)=ROTHD_THREAD13_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD14_VALID

    *( **int** *)(THD_TS_ADDR+112)=ROTHD_THREAD14_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD15_VALID

    *( **int** *)(THD_TS_ADDR+120)=ROTHD_THREAD15_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD17_VALID

    *( **int** *)(THD_TS_ADDR+136)=ROTHD_THREAD17_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD18_VALID

    *( **int** *)(THD_TS_ADDR+144)=ROTHD_THREAD18_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD19_VALID

    *( **int** *)(THD_TS_ADDR+152)=ROTHD_THREAD19_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD21_VALID

    *( **int** *)(THD_TS_ADDR+168)=ROTHD_THREAD21_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD22_VALID

    *( **int** *)(THD_TS_ADDR+176)=ROTHD_THREAD22_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD23_VALID

    *( **int** *)(THD_TS_ADDR+184)=ROTHD_THREAD23_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD25_VALID

    *( **int** *)(THD_TS_ADDR+200)=ROTHD_THREAD25_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD26_VALID

    *( **int** *)(THD_TS_ADDR+208)=ROTHD_THREAD26_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD27_VALID

    *( **int** *)(THD_TS_ADDR+216)=ROTHD_THREAD27_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD29_VALID

    *( **int** *)(THD_TS_ADDR+232)=ROTHD_THREAD29_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD30_VALID

    *( **int** *)(THD_TS_ADDR+240)=ROTHD_THREAD30_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD31_VALID

    *( **int** *)(THD_TS_ADDR+248)=ROTHD_THREAD31_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD33_VALID

    *( **int** *)(THD_TS_ADDR+264)=ROTHD_THREAD33_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD34_VALID

    *( **int** *)(THD_TS_ADDR+272)=ROTHD_THREAD34_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD35_VALID

    *( **int** *)(THD_TS_ADDR+280)=ROTHD_THREAD35_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD37_VALID

    *( **int** *)(THD_TS_ADDR+296)=ROTHD_THREAD37_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD38_VALID

    *( **int** *)(THD_TS_ADDR+304)=ROTHD_THREAD38_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD39_VALID

    *( **int** *)(THD_TS_ADDR+312)=ROTHD_THREAD39_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD41_VALID

    *( **int** *)(THD_TS_ADDR+328)=ROTHD_THREAD41_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD42_VALID

    *( **int** *)(THD_TS_ADDR+336)=ROTHD_THREAD42_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD43_VALID

    *( **int** *)(THD_TS_ADDR+344)=ROTHD_THREAD43_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD45_VALID

    *( **int** *)(THD_TS_ADDR+360)=ROTHD_THREAD45_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD46_VALID

    *( **int** *)(THD_TS_ADDR+368)=ROTHD_THREAD46_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD47_VALID

    *( **int** *)(THD_TS_ADDR+376)=ROTHD_THREAD47_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD49_VALID

    *( **int** *)(THD_TS_ADDR+392)=ROTHD_THREAD49_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD50_VALID

    *( **int** *)(THD_TS_ADDR+400)=ROTHD_THREAD50_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD51_VALID

    *( **int** *)(THD_TS_ADDR+408)=ROTHD_THREAD51_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD53_VALID

    *( **int** *)(THD_TS_ADDR+424)=ROTHD_THREAD53_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD54_VALID

    *( **int** *)(THD_TS_ADDR+432)=ROTHD_THREAD54_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD55_VALID

    *( **int** *)(THD_TS_ADDR+440)=ROTHD_THREAD55_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD57_VALID

    *( **int** *)(THD_TS_ADDR+456)=ROTHD_THREAD57_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD58_VALID

    *( **int** *)(THD_TS_ADDR+464)=ROTHD_THREAD58_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD59_VALID

    *( **int** *)(THD_TS_ADDR+472)=ROTHD_THREAD59_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD61_VALID

    *( **int** *)(THD_TS_ADDR+488)=ROTHD_THREAD61_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD62_VALID

    *( **int** *)(THD_TS_ADDR+496)=ROTHD_THREAD62_FREQCFG_VALUE;

**#endif**

 

**#ifdef** ROTHD_THREAD63_VALID

    *( **int** *)(THD_TS_ADDR+504)=ROTHD_THREAD63_FREQCFG_VALUE;

**#endif**

程序/DATA空间

128KB RAM可以划分3种配置

线程配置工具_V1.exe工具中如下
image.png

对应的代码位于thread_start.c

实际就是写DATA_RAM_RATIO寄存器,用于指定DATA的大小(32KBx1,32KBx2,32KBx3),

剩下的就是CODE区域。

**#if** ROTHD_DATA_RAM_VALUE==32768*3

    DATA_RAM_RATIO=0x60;

**#endif**

**#if** ROTHD_DATA_RAM_VALUE==32768*2

    DATA_RAM_RATIO=0x40;

**#endif**

**#if** ROTHD_DATA_RAM_VALUE==32768

    DATA_RAM_RATIO=0x20;

**#endif**

栈空间

程序/DATA空间分配好后,再从DATA空间中分配栈空间

64 个线程,每个线程都有自己独立的栈空间,且在数据空间允许的范

围内随意分配,只要所有非空闲线程的栈空间总和不超过数据空间的大小即可(数据空间有

192 字节的保留区不可使用),栈空间大小需要是4 字节的整数倍

线程配置工具_V1.exe工具中如下
image.png

对应的代码位于thread_start.c

比如线程1,通过rothd_set_sp_const设置SP寄存器

**void**  **thread1_initial** ( **void** )

{

**#ifdef** ROTHD_THREAD1_VALID

**extern** **void**  **thread1_main** ( **void** );

    rothd_set_sp_const(ROTHD_THREAD1_STACKCFG_VALUE|0x20000000);

    thread1_main();

**#endif**

}

其他线程类似

资源共享

各个线程之间共享全局变量实现通讯

执行过程分析

连接脚本

看程序的运行过程一般都是从连接脚本入手,先找入口点

再看MEMMAP等。

MC3172.lds

可以看到入口点

ENTRY(thread_start)

空间分配

MEMORY

{

    CODE_SPACE (x)  : ORIGIN = 0x00000010, LENGTH =  65520

    DATA_SPACE (rw) : ORIGIN = 0x20000010, LENGTH =  48672

}

以下可以看到.text.thread_start放在了CODE_SPACE的开始处。后续就是DATA区域分配。所以最开始就是执行thread_start函数。

. = 0x00000010;

  .text           :

  {

    *(.text.thread_start)

    *(.text)

    *(.text.unlikely .text.*_unlikely .text.unlikely.*)

    *(.text.exit .text.exit.*)

    *(.text.startup .text.startup.*)

    *(.text.hot .text.hot.*)

  }

执行过程

thread_start ->

(*thread_initial_pointer[THREAD_ID])()

其中THREAD_ID寄存器指定一个运行的线程,一般是0。

则执行

thread0_initial->

进行时钟源配置,CODE/DATA区域配置,线程频率分配。

thread0_main->

其他线程运行

通过thread_initial_pointer查找到初始化函数

threadx_initial

进行栈配置然后

threadx_main运行

体验

双击打开

MC3172资料合集_v1.12MC3172_TemplateMC3172.wvproj

打开工程浏览器
image.png

右键点击

GPIO_GPCOM_TIMER_Example.c->Properties

按如下操作,将该文件添加到编译。
image.png

取消

thread0_main~thread4_main相关代码注释

菜单栏

Project->Build ALL

生成进行镜像位于

MC3172资料合集_v1.12MC3172_TemplateRelease

双击该目录下开发板程序下载_v1.1.exe

按如下单次下载运行
image.png

image.png

上述下载到RAM中掉电不保存,也可以点击烧录固件到这样可以掉电保存。

从以下可以看出GPCOM8 P2:RXD PC2 GPCOM8 P3:TXD PC3 波特率115200

GPCOM_UART_EXAMPLE(GPCOM8_BASE_ADDR);

 

GPCOM_SET_IN_PORT(gpcom_sel,(GPCOM_RXD_IS_P2));

    GPCOM_SET_OUT_PORT(gpcom_sel,( 

            GPCOM_P0_OUTPUT_DISABLE|GPCOM_P3_OUTPUT_ENABLE|GPCOM_P2_OUTPUT_DISABLE|GPCOM_P1_OUTPUT_DISABLE| 

            GPCOM_P0_IS_HIGH       |GPCOM_P3_IS_TXD       |GPCOM_P2_IS_HIGH       |GPCOM_P1_IS_HIGH 

                      ));

image.png

image.png

按如下接上串口线,使用串口调试助手设置为115200-8-n-1, 上位机发送数据开发板收到后原样返回。

对应代码如下

u8 rx_data_rp=0;

u8 rx_data=0;

rx_data_rp=GPCOM_GET_RX_WP(gpcom_sel);

 while (1) {

      if (rx_data_rp!=(GPCOM_GET_RX_WP(gpcom_sel))){

          rx_data=GPCOM_GET_RX_DATA(gpcom_sel,rx_data_rp);

          GPCOM_PUSH_TX_DATA(gpcom_sel,rx_data);

          rx_data_rp++;

          rx_data_rp&=0x0f;

     }

}

image.png

image.png

总结

  1. 打开线程配置工具_V1.exe时能自动加载当前设置,这样方便做修改,而不需要全部从头配置。

  2. 64个线程共享主频,所以实际并不是并行运行,而是硬件进行分时轮流执行,也就是并没有64个运行环境(寄存器组等),实际是硬件完成了RTOS线程切换的上下文切换等动作,各线程执行的时间占比根据线程主频控制器设置的共享频率进行分配。硬件完成上下文切换时间损失很小,这样在高调度频率的情况就避免了上下文切换时间占比较大导致的效率低的问题,这样比RTOS软件实现实时性效率更高。

  3. 外设模块能提供更详细的编程手册更好。

  4. 总结下从开发环境,配置工具等来看还是比较容易入手的,尤其是硬件实现线程切换调度,减少了RTOS移植,上下文调度切换的时间考虑等问题,编程更简单,使得开发板都效率都更高,运行的实时性也更高。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
收藏 人收藏

    评论

    相关推荐

    什么是并行多线程实时处理器?MC3172开发环境开发实践

    板子上的MCU是个很有意思的东西——并行多线程处理器MC3172
    发表于 09-19 11:28 446次阅读
    什么是并行<b class='flag-5'>多线程</b>实时处理器?<b class='flag-5'>MC3172</b><b class='flag-5'>开发</b>环境<b class='flag-5'>开发</b>实践

    科技MC3172开发板体验】多线程串口功能测试

    。 可以看出对应的是GPIOC口。软件初始化端口时按照文档 《并行多线程处理器MC3172开发极简指南(2).pdf》中uart函数进行初始化 代码介绍 初始化完毕后,硬件链接,
    发表于 06-10 14:28

    科技MC3172开发板体验】WS2812音乐灯带

    板子上个月末就拿到手了,由于撞上几门考试耽误了下。现在我要用这块MC3172开发板个我很久之前就想做的音乐流水灯,顾名思义就是灯带会随着音乐变化。 该项目所用的外设有SPI和串口
    发表于 06-09 00:49

    科技MC3172开发板体验】MC3172开箱初体验

    线程并行的MCU。独占整个开发板背面 这里也可以看到用了颗CH32V203G6U6的MCU
    发表于 06-07 14:03

    科技MC3172开发板体验】开机测试

    MC3172开发板64线程同步并行运行,各个线程速度可按需配置,硬件级实时响应,无需中断服
    发表于 06-05 00:08

    科技MC3172开发板体验】+游戏机器人创意设计(1)开源(芯片简介)

    个小的这个单片机里头可以让它同时并行运行64个小程序,64个单片机程序,让它并行处理了。等于这个单片机就是把咱们的效率给提高了。它的型号大家可以上网查查:
    发表于 06-03 07:38

    科技MC3172开发板体验】环境搭建及板载LED驱动

    本帖最后由 notgood 于 2023-5-29 21:37 编辑 1.开箱照首先感谢电子发烧友以及科技,有幸取得了MC3172开发板
    发表于 05-29 21:32

    科技MC3172开发板体验】MC3172初体验

    本帖最后由 james03 于 2023-5-29 10:37 编辑 1、简述MC3172科技推出的款基于RISC-V指令集的64
    发表于 05-29 10:31

    科技MC3172开发板体验】MC3172开发板种便捷的多线程开发新途径

    经过天的捣鼓,总算把MC3172并行多线程实时处理器的开发整明白了。 首先需要准备的开发环境如下:
    发表于 05-28 15:22

    科技MC3172开发板体验】线程配置与外设使用

    是全局数据空间,而不是代码空间。 64K数据空间的大小为65344,而不是65536,有可能还有部分预留给芯片线程调度吧。 这个空间在实
    发表于 05-25 15:11

    科技MC3172开发板体验】测评科技MC3172开发板

    的主角科技MC3172开发板开发板背面主芯片 随感
    发表于 05-25 11:34

    科技MC3172开发板体验】开箱与环境配置

    、概述 首先,感谢感科技与发烧友给予的这次试用机会。 MC3172芯片64
    发表于 05-25 08:47

    科技MC3172开发板体验】初次使用多线程开发板

    以前作设计多是个程序码到底,很少整个OS系统啥的,当然涉及多线程的也很少。这次终于有机会可以好好学习,且有了个较大地跨越,是直接以硬件开发板
    发表于 05-25 00:54

    科技MC3172开发板体验】科技MC3172开发板上手体验

    GCC\\\\bin 三、总结 首先感谢发烧友平台跟科技两方提供的开发板评测体验机会,让我接触到了,新的芯片,有了不一样的体验
    发表于 05-24 16:24

    【RISC-V开发板】并行多线程处理器MC3172开发资料集合

    厦门科技多线程处理器MC3172开发板64线程
    发表于 05-23 11:44