文章下方附学习资源,自助领取 摘要:最近,朋友送了块小板子,板子上的MCU是个很有意思的东西并行多线程处理器MC3172。通俗地说,这颗MCU的内部实现了类似RTOS多线程的功能。但是MC3172编程与RTOS编程的最大区别就是:MC3172多线程绝对并行运行,没有切换抖动及开销。MC3172无线程优先级、优先级反转、死锁等概念。MC3172所有中断都可以安排专门线程处理,没有中断嵌套和延迟。MC3172各线程同步并行运行,互不阻塞,互不干扰。MC3172线程响应的确定性相对于RTOS更为精确。MC3172简介 MC3172是厦门感芯科技的一款32位RISC并行多线程实时处理器。基于RISCVRV32IMC指令集,100单周期指令,最高200MHz主频,3。37coremarkMHz。可以代替实时操作系统,实现程序的模块化与复用性。 相关资料可在感芯官网下载。链接:http:www。gxchip。cn MC3172特性: MC3172实践 MC3172的开发环境使用的是国产软件MounRiverStudio。 MounRiverStudio下载链接:http:www。mounriver。comdownload 我们简单看一下MC3172的demo工程: 1、MC3172文件夹 MC3172存放MC3172编程核心文件。 线程配置工具可对各线程进行配置: 可以配置线程时钟源、频率、栈空间、存储器分配等信息。 MC3172支持64路线程同步并行运行,其中分为4个线程组,每个线程组16线程,每个线程组里的线程编号如上图所示。其中,不使用的线程可以设置为空闲线程,空闲线程完全不运行,不产生功耗。 嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去! 无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。 点击这里找小助理0元领取:嵌入式物联网学习资料(头条) 每个线程都有自己独立的栈空间,在数据空间允许范围内可随意分配,但需要确保所有非空闲线程所占的数据空间不超过数据空间的大小。 MC3172。h存放外设地址相关宏定义及其配置宏,如: 类似于ST的stm32fxxx。h。 threadconfig。h为线程配置文件,由线程配置工具生成: MC3172。lds为链接脚本,由线程配置工具生成 threadstart。c为启动线程相关的源文件:ifndefTHREADSTARTCdefineTHREADSTARTCinclude。MC3172。hinclude。threadconfig。hvoidthread1initial(void){ifdefROTHDTHREAD1VALIDexternvoidthread1main(void);rothdsetspconst(ROTHDTHREAD1STACKCFGVALUE0x20000000);thread1main();endif}voidthread2initial(void){ifdefROTHDTHREAD2VALIDexternvoidthread2main(void);rothdsetspconst(ROTHDTHREAD2STACKCFGVALUE0x20000000);thread2main();endif}省略部分代码。。。。。。void(threadinitialpointer〔64〕)(void){thread0initial,thread1initial,thread2initial省略部分代码。。。。。。}voidthreadstart(void){(threadinitialpointer〔THREADID〕)();} 程序运行的入口函数为:threadstart,从链接脚本里可以知道: threadstart里的THREADID为线程ID值,直接从0x50000000地址中读出:defineTHREADID((volatileu8)(0x50000000)) 猜测:0x50000000地址里的ID值会不断变化,通过某种机制跳转,遍历执行threadinitialpointer函数指针数组里的各个线程函数。 threadxinitial里初始化线程栈,并执行线程主体,如voidthreadend(void){while(1);}voidthread1main(void){while(1){usercodesection}threadend();} 这是用户代码,我们可以在各个线程主体函数里边编写我们的应用代码。2、Release文件夹 Release文件夹里存放的是编译生成的固件程序,通过开发板程序下载工具可进行下载: 3、USERCODE文件夹 USERCODE文件夹存放用户代码: MC3172是一颗并行并行多线程实时处理器,我们下面来看看其多线程并行执行的特性。 我们编写两个线程,线程进行相同的配置,两个线程分别对两个IO进行翻转,测试代码如:voidLED0GPIOAPIN0TEST(void){启动GPIOA并设置特权组及时钟频率INTDEVSETCLKRST(GPIOABASEADDR,(INTDEVRUNINTDEVISGROUP0INTDEVCLKISCORECLKDIV2));使能GPIOAPIN0引脚GPIOSETOUTPUTENVALUE(GPIOABASEADDR,GPIOPIN0,GPIOSETENABLE);while(1){GPIOAPIN0输出1GPIOSETOUTPUTPINTO1(GPIOABASEADDR,GPIOPIN0);延时for(u32var0;var5000;var){NOP();}GPIOAPIN0输出0GPIOSETOUTPUTPINTO0(GPIOABASEADDR,GPIOPIN0);延时for(u32var0;var5000;var){NOP();}}}voidLED1GPIOAPIN1TEST(void){启动GPIOA并设置特权组及时钟频率INTDEVSETCLKRST(GPIOABASEADDR,(INTDEVRUNINTDEVISGROUP0INTDEVCLKISCORECLKDIV2));使能GPIOAPIN1引脚GPIOSETOUTPUTENVALUE(GPIOABASEADDR,GPIOPIN1,GPIOSETENABLE);while(1){GPIOAPIN1输出1GPIOSETOUTPUTPINTO1(GPIOABASEADDR,GPIOPIN1);延时for(u32var0;var5000;var){NOP();}GPIOAPIN1输出0GPIOSETOUTPUTPINTO0(GPIOABASEADDR,GPIOPIN1);延时for(u32var0;var5000;var){NOP();}}}voidthreadend(void){while(1);}voidthread0main(void){while(1){usercodesection}threadend();}voidthread1main(void){while(1){usercodesectionLED0GPIOAPIN0TEST();}threadend();}voidthread2main(void){while(1){usercodesectionLED1GPIOAPIN1TEST();}threadend();} 烧录程序,使用逻辑分析仪抓取GPIOAPIN0及GPIOAPIN1引脚电平变化如: 可见,这两个波形是完全同步的,CPU同时在干两件事情,实现了与RTOS多线程同样的效果。心得与总结 嵌入式开发,是软件硬件结合,两者互补。如果硬件功能很强大,则软件可能可以设计得比较简单;如果硬件功能有限,则软件方面可能得考虑比较多的方面。 比如:一些软件算法,需要多传感器数据输入进行融合,则功能实现可能比较简单,但实际可能为了降成本,减少一些传感器,这时候需要实现稳定可靠的功能,则软件算法上得下更大的功夫。对于一些不太复杂的数字信号处理,在通用的MCU上就可以处理,但对于一些比较复杂的数字信号处理,则可能使用一些带有DSP处理器的MCU。 特别的,对于芯片内部IC电路来说,如果内部有相关模块可以实现某些功能的话,则对应的软件编程会简单很多,而且硬件实现的比软件实现的效率要高。 硬件实现的多线程编程确实优于RTOS编程,但实际开发中产品软硬件架构需要考虑多个方面,比如芯片的稳定性以及软件生态等方面。 并行多线程实时处理器是个好东西,但目前并行多线程实时处理器还处于起步阶段,还有很多东西需要完善,需要我们多支持与传播,只有生态起来了,将来我们才有机会用得上。文章来源于嵌入式大杂烩,作者杂烩君 本文转载自果果小师弟,如有侵权,请联系删除 原文链接:并行多线程的MCUMC3172,你见过吗? 版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。