找回密码
 立即注册
楼主: 王昱顺

解决编译器【REMOVEUNUSED选项】,可能错误移除问题,现象是感觉复位了

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2218

回帖

5450

积分

版主

积分
5450
发表于 2025-3-13 12:24:53 | 显示全部楼层
大*** 发表于 2025-3-13 12:01
因为平时主要玩的是OLED屏幕,当时遇到的情况是USB下载和REMOVEUNUSED同时用会重启。
现象总结起来就是

我现在尝试同时添加USB-CDC库和使用乘除法(添加MDU32LIB情况下),得到程序是正常使用的
可以帮忙测试一下原来有问题工程中,添加官网刚更新的MDU32LIB库,看看是否能正常使用?

点评

刚试完你就问到了  详情 回复 发表于 2025-3-13 12:26
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2218

回帖

5450

积分

版主

积分
5450
发表于 2025-3-13 12:26:19 | 显示全部楼层
大*** 发表于 2025-3-13 12:24
试了一下在LIB方式USB下载的有问题的工程里,添加楼主的MDU32_SIDIV.LIB,
重新编译之后果然不会重启了

目前此程序分支已经合并进入官网的MDU32库中
截图202503131226011156.jpg
可以直接使用官网的LIB库来解决了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:392
  • 最近打卡:2025-05-01 15:00:39

24

主题

305

回帖

2556

积分

荣誉版主

积分
2556
发表于 2025-3-13 12:26:24 | 显示全部楼层
王*** 发表于 2025-3-13 12:24
我现在尝试同时添加USB-CDC库和使用乘除法(添加MDU32LIB情况下),得到程序是正常使用的
可以帮忙测试一 ...

刚试完你就问到了
能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2025-04-30 14:38:57

25

主题

977

回帖

3599

积分

超级版主

积分
3599
发表于 2025-3-13 12:57:01 | 显示全部楼层
关于在C251环境下使用USB的库函数时,如果加上REMOVEUNUSED链接指令后
Keil编译器会错误的移除部分Keil的内部库函数
目前发现错误的移除的库包括:
1、浮点加、减、乘、除、取负数函数
2、所有三角函数和反三角函数
3、楼主发现的整型有符号除法SIDIV函数

如下图,函数移除后,编译器会默认将原函数的地址设置为0000H,导致程序复位

截图202503131213476729.jpg


直接去掉REMOVEUNUSED链接指令,可以解决上的问题
但去掉REMOVEUNUSED后,Keil会将USB库中所有模块全部链接到目标文件中
从而会导致相当一部分的程序空间和RAM空间被浪费

建议的解决办法:
如果需要使用USB的库,请同时将STC32G对应的MDU32的库和
FPMU浮点库也一同加入到项目中,如下图:

截图202503131217149761.jpg

另外还需要注意一点,由于USB.LIB 库+REMOVEUNUSEDKeil C251 会无条件移除全部的Keil内部的浮点库
所以如果您的代码中浮点运算并没有在STC32G的FPMU库中支持,依然会出现复位的情况
如上图中的asin函数,STC32G的FPMU库没有支持,依然会LCALL 0000H的地址
所以您需要特别注意STC32G的MDU32和FPMU库所支持的函数

MDU32支持的函数如下:
长整型乘法运算(包含有符号和无符号)
整型乘法运算(包含有符号和无符号)
无符号长整型除法运算
无符号长整型除以无符号整型运算
有符号长整型除法运算
有符号整型除法运算

FPMU指定的函数如下:
浮点数加法运算
浮点数减法运算
浮点数乘法法运算
浮点数除法运算
开方运算
浮点数比较
浮点数取负数运算
浮点数取绝对值运算
浮点数与整数之间的转换函数
正弦三角函数
余弦三角函数
正切三角函数
反正切三角函数

如果您的程序使用了USB库,且需要使用REMOVEUNUSED,
则注意不能使用上面函数之外其他数学函数

点评

目前通过调试定位到,原因是有其他程序文件使用了stdio.h的内的任意函数后(例如printf、scanf),如果main函数没有调用这些函数,那么使用REMOVEUNUSED就会出现LCALL 0x0000异常。 最快的解决方案就是在程序开头加上  详情 回复 发表于 2025-3-17 13:32
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:452
  • 最近打卡:2025-05-01 06:20:50
已绑定手机

13

主题

1257

回帖

2971

积分

金牌会员

积分
2971
发表于 2025-3-13 15:07:15 | 显示全部楼层
zh*** 发表于 2025-3-13 12:57
关于在C251环境下使用USB的库函数时,如果加上REMOVEUNUSED链接指令后
Keil编译器会错误的移除部分Keil的内 ...

void main(void)
{
    int volatile x;
    x /= 100;
    while (1)
    {

    }
}


转成ASM后的结果是:
$NOMACRO
$MODSRC
$MODEL(1)
$CASE

;
; 'main.SRC' generated from 'main.c'
; COMPILER INVOKED BY:
;        D:\Software\单片机\编译\C251_V560\C251.EXE main.c SRC
;
                NAME main

        EXTRN         CODE : NEAR (?C?STARTUP)
        EXTRN         CODE : NEAR (?C?SIDIV)

            ?PR?MAIN?MAIN  SEGMENT  CODE  
            ?DT?MAIN?MAIN  SEGMENT  DATA OVERLAYABLE (main)

        RSEG       ?DT?MAIN?MAIN
           x?040:  DSW  1


;--- special function registers and bits:
             ACC  DATA  0E0H
             PSW  DATA  0D0H
             DPL  DATA  082H
             DPH  DATA  083H
               B  DATA  0F0H
              SP  DATA  081H
            PSW1  DATA  0D1H
               Z  BIT   0D1H.1
              EA  BIT   0A8H.7
              OV  BIT   0D0H.2
               P  BIT   0D0H.0
              F0  BIT   0D0H.5
             RS1  BIT   0D0H.4
             RS0  BIT   0D0H.3
              AC  BIT   0D0H.6
;--- end of special function registers and bits.

        PUBLIC        main

; line 1: //#include "stc32g.h"
; line 2:
; line 3:
; line 4:
; line 5: void main(void)

        RSEG       ?PR?MAIN?MAIN
        main PROC
; line 6: {
; line 7:     int volatile x;
; line 8:     x /= 100;
        MOV      WR4,#064H
        MOV      WR6,x?040
        LCALL    ?C?SIDIV
        MOV      x?040,WR6
; line 9:     while (1)
; line 10:     {
; line 11:
; line 12:     }
?C0001:
        SJMP     ?C0001
        ENDP
; line 13: }

        END



并没有生成LCALL 0000H

点评

没有产生LCALL 0000H 是因为首先你没有使用usb的库 其次出现问题是最后的链接阶段 [attachimg]87759[/attachimg]  详情 回复 发表于 2025-3-13 15:36
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2025-04-30 14:38:57

25

主题

977

回帖

3599

积分

超级版主

积分
3599
发表于 2025-3-13 15:36:35 | 显示全部楼层
21cns*** 发表于 2025-3-13 15:07
void main(void)
{
    int volatile x;

没有产生LCALL 0000H
是因为首先你没有使用usb的库
其次出现问题是最后的链接阶段

截图202503131536311071.jpg

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-3-13 23:51:53 | 显示全部楼层
mark,学习
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:452
  • 最近打卡:2025-05-01 06:20:50
已绑定手机

13

主题

1257

回帖

2971

积分

金牌会员

积分
2971
发表于 2025-3-14 00:21:38 | 显示全部楼层
经测试,16位的除法加入MDU32_SIDIV库解决了,但8位除法还是同样的问题,请楼主验证。
代码如下:
    char volatile x;
    x /= 100;

其他类型、其他运算暂未测试。

点评

现已加入了8位的除法部分,包含库以后,Keil编译器会优先使用用户定义的部分 所以可以避免掉Keil编译器本身的BUG 可以先行测试,稍后会同步到官方库中  详情 回复 发表于 2025-3-14 20:27
好的,我们会继续扩大测试并补充进mdu32的lib库中 之后有新的更新会在本帖同步通知  详情 回复 发表于 2025-3-14 04:28
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2218

回帖

5450

积分

版主

积分
5450
发表于 2025-3-14 04:28:48 | 显示全部楼层
21cns*** 发表于 2025-3-14 00:21
经测试,16位的除法加入MDU32_SIDIV库解决了,但8位除法还是同样的问题,请楼主验证。
代码如下:
    char ...

好的,我们会继续扩大测试并补充进mdu32的lib库中
之后有新的更新会在本帖同步通知

点评

凌晨4点回帖,辛苦了!  发表于 2025-3-14 07:45
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-05-01 04:31:49

24

主题

515

回帖

986

积分

荣誉版主

积分
986
发表于 2025-3-14 06:51:41 | 显示全部楼层
STC提供的USB库太臃肿了,最佳解决方案是:STC公司再提供一个精简版的USB库。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 20:14 , Processed in 0.220042 second(s), 122 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表