查看: 45|回复: 0

[经验] 分享在MDK软件中半主机模式几个干货内容

[复制链接]

主题

好友

1万

积分

翰林

  • TA的每日心情
    开心
    2019-11-4 13:48
  • 签到天数: 14 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2020-8-1 13:24:43 |显示全部楼层
    看了原子哥的usart部分printf函数重定向的问题,自己动手试了试,单片机可以通过串口打印信息,printf函数重定向后使用十分方便。
    所谓重定向是指修改printf的底层函数,使printf打印到单片机的外设中。
    还有一个概念是半主机。
    ---参考   RealView 编译工具开发指南   8.1.1. 什么是半主机?
    RealView 编译工具开发指南我已上传,大家可以下载研究研究。


    这里也给出没打开、中c库和c+库的使用规范


    有兴趣的可以看看,内容有点多,看起来不很好理解。

    半主机是用于 ARM 目标的一种机制,可将来自应用程序代码的输入/输出请求传送至运行调试器的主机。 例如,使用此机制可以启用 C 库中的函数,如 printf() 和 scanf(),来使用主机的屏幕和键盘,而不是在目标系统上配备屏幕和键盘。

    这种机制很有用,因为开发时使用的硬件通常没有最终系统的所有输入和输出设备。 半主机可让主机来提供这些设备。

    半主机是通过一组定义好的软件指令(如 SVC)来实现的,这些指令通过程序控制生成异常。 应用程序调用相应的半主机调用,然后调试代理处理该异常。 调试代理提供与主机之间的必需通信。

    半主机接口对 ARM 公司提供的所有调试代理都是通用的。 在无需移植的情况下使用 RealView ARMulator® ISS、指令集系统模型 (ISSM)、实时系统模型 (RTSM)、RealView ICE 或 RealMonitor 时,会执行半主机操作。

    标准库使用半主机模式,半主机是通过一组定义好的软件指令 (如 SVC)SVC 指令 (以前称为 SWI 指令)来实现的,这些指令通过程序控制生成异常。 应用程序调用相应的半主机调用,然后调试代理处理该异常。调试代理(这里的调试代理是仿真器)提供与主机之间的必需通信。也就是说使用半主机模式必须使用仿真器调试。

    ARMv7 之前的 ARM 处理器使用 SVC 指令 (以前称为 SWI 指令)进行半主机调用。 但是,如果要为 ARMv6-M 或 ARMv7-M (如 Cortex™-M1 或 Cortex-M3 处理器)进行编译,请使用 BKPT 指令来实现半主机。

    简单的来说,半主机模式就是通过仿真器实现开发板在电脑上的输入和输出。和半主机模式功能相同的是ITM调试机制。


    上面介绍的半主机和ITM功能相当,他们都是调试机制,开发板均借助仿真器与电脑连接,实现单片机利用主机的屏幕键盘的输入输出。
    这两种机制的运行均需要仿真器,否则无法运行。

    开发式一般单片机需要独立运行,开发者应去掉仿真器,把printf函数通过单片机的外设来实现,例如通过开发板的串口,lcd或者sd卡。

    MDK中通常使用以下两种方法:
    方法1.使用微库,因为使用微库的话,不会使用半主机模式.
    • int fputc(int ch, FILE *f)
    • {
    • while((USART1->SR&0X40)==0);
    •     USART1->DR = (u8) ch;
    • return ch;
    • }

    [color=rgb(51, 102, 153) !important]复制代码


    方法2.仍然使用标准库,在主程序添加下面代码:
    • #pragma import(__use_no_semihosting)
    • ​struct __FILE
    • {
    • int handle;
    • };
    • FILE __stdout;
    • _sys_exit(int x)
    • {
    • x = x;
    • }
    • int fputc(int ch, FILE *f)
    • {
    • while((USART1->SR&0X40)==0);//Ñ»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï
    •     USART1->DR = (u8) ch;
    • return ch;
    • }

    [color=rgb(51, 102, 153) !important]复制代码


    关于 microlib
    microlib 是缺省 C 库的备选库。 它用于必须在极少量内存环境下运行的深层嵌入式应用程序。 这些应用程序不在操作系统中运行。microlib 不会尝试成为符合标准的 ISO C 库。
    microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。某些库函数的运行速度也比较慢,例如,memcpy()

    上面给出了正确的方法,我在测试的过程中发现方法二中注释掉#pragma import(__use_no_semihosting) 程序依然运行正确,这个很让人费解。
    也有使用#pragma import(__use_no_semihosting_swi)的。这几个的区别我没弄懂。
    如果使用微库或者禁用半主机,没有重定义fputc函数,程序可以运行,但不知道结果打印到主机的哪个地方去了。既没有禁用半主机也没有重定义fputc函数,程序将一直停在中断处,如图:

    网上的大部分资料都是禁用了半主机模式,没有使用过半主机模式借助主机的键盘输入参数,看了很多资料,都是讲半主机的,但讲的内容太浅显,
    我没有学会使用半主机,更多的是学会了禁用半主机模式,我们好像忽略了半主机模式的意义。

    另外,我们可以查到的大部分资料讲解的大同小异,它们更多的告诉我们正确的步骤,而不是让我们从源头了解一个问题,当然,大部分人看重的是实用,问题解决了,也就不再去思考背后的原理。

    最有效最直接最权威的资料是mdk官方给出的资料,但是资料内容太多,看起来太多,不易懂,大部分人没有看下去的欲望。我们应该让使用手册看起来更直观,更易懂,更方便查阅,更高效地查阅。

    第一个给出此类问题的解决方法的人,他们以通俗易懂的方式告诉了广大开发者,他们阅读了这些晦涩的手册,他们是真的勇士!
    游客,如果您要查看本帖隐藏内容请回复

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|电路城

    GMT+8, 2020-8-9 01:40 , Processed in 0.065451 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz!

    返回顶部