OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2837|回复: 6

如何规避定时器服务中断函数的返回值与清除标识位之间的矛盾

[复制链接]

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2016-11-11
在线时间
12 小时
发表于 2017-12-19 14:03:49 | 显示全部楼层 |阅读模式
1金钱
我的程序大概是定时器扫描采集adc,在定时器服务函数里实现:adc数据给中间变量后return给服务函数,在主函数里调用服务函数进行相关处理。但是问题是,这样处理后没有数据返回,用led灯验证了各个数据,发现是在清除标志位那丢失的,也就是说,这个语句return adcx;没有用到,大概是这两个语句都会使程序跳出服务函数,所以是矛盾的(我把两个语句调过来也是一样的结果),请问各位大佬怎么做?我想到的办法就是用全局变量,这涉及到全局变量的用法,我还没有细看,如果这个方法可行,能不能告知一二,谢谢。
程序如下
u16 TIM3_IRQHandler()
{
        u16 adcx;
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //òç3öÖD¶Ï
        {
                adcx=Get_Adc_Average(ADC_Channel_5,20);
        }
       
                TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //Çå3yÖD¶Ï±ê־λ
//                                if(adcx<1)
//                        {LED1=!LED1;
//                        }
        return adcx;
}

最佳答案

查看完整内容[请看2#楼]

Cortex M3 权威指南(中文).PDF 169页 可能有你需要的 [mw_shl_code=c,true]// 使用C写成的SVC服务例程,接受一个指针参数( pwdSF):堆栈栈的起始地址。 // pwdSF[0] = R0 , pwdSF[1] = R1 // pwdSF[2] = R2 , pwdSF[3] = R3 // pwdSF[4] = R12, pwdSF[5] = LR // pwdSF[6] = 返回地址(入栈的PC) // pwdSF[7] = xPSR unsigned long svc_handler(unsigned int* pwdSF) { unsigned int svc_number; unsigned int s ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-12-19 14:03:50 | 显示全部楼层
Cortex M3 权威指南(中文).PDF   169页  可能有你需要的
[mw_shl_code=c,true]// 使用C写成的SVC服务例程,接受一个指针参数( pwdSF):堆栈栈的起始地址。
// pwdSF[0] = R0 , pwdSF[1] = R1
// pwdSF[2] = R2 , pwdSF[3] = R3
// pwdSF[4] = R12, pwdSF[5] = LR
// pwdSF[6] = 返回地址(入栈的PC)
// pwdSF[7] = xPSR
unsigned long svc_handler(unsigned int* pwdSF)
{
unsigned int svc_number;
unsigned int svc_r0;
unsigned int svc_r1;
unsigned int svc_r2;
unsigned int svc_r3;
int retVal; //用于存储返回值
svc_number = ((char *) pwdSF[6])[-2]; // 没想到吧, C的数组能用得这么绝!
svc_r0 = ((unsigned long) pwdSF[0]);
svc_r1 = ((unsigned long) pwdSF[1]);
svc_r2 = ((unsigned long) pwdSF[2]);
svc_r3 = ((unsigned long) pwdSF[3]);
printf (“SVC number = %xn”, svc_number);
printf (“SVC parameter 0 = %x\n”, svc_r0);
printf (“SVC parameter 1 = %x\n”, svc_r1);
printf (“SVC parameter 2 = %x\n”, svc_r2);
printf (“SVC parameter 3 = %x\n”, svc_r3);
//做一些工作,并且把返回值存储到retVal中
pwdSF[0]=retVal;
return 0;
}
注意,这个函数返回的其实不是0!进一步地,灰色的文字只是用于哄编译器开心的—
—让它认为这个函数是个有返回值的函数,而且确实返回一个数值了,于是不再吵闹着说有
错或警告什么的。那返回的是啥?当然是retVal啦!有点迷糊么?往下看就知道了。
原来, SVC服务例程不能像普通的C函数那样——通过把原型声明为”unsigned int func()”,
再在末尾来一句”return xx;”来返回。因为这种常规的作法在所有的ARM中其实是把返回值
放到R0里。但是别忘了,这个函数可是异常服务例程,它的返回可是享受“异常返回”的待
遇的——伴随着一个硬件控制的自动出栈行为,这会从堆栈中重建R0的值,从而覆盖“ return”
指定的值。因此,它必须把返回值写到堆栈中R0的位置,才能借自动出栈之机返回自己的值
( pwdSF[0]=retVal)。
这下可真相大白了!虽然内部暗流汹涌,但是从应用程序的表面上看还是风平浪静——
对于系统服务函数来说,这种独特的返回方式与普通的return xx效果是相同的,依然可以用
普通的形式接收返回值。怎么样,这招够狠吧!其实,在写系统软件时,这根本算不上耍狠,
只不过是寻常的基本功罢了,要不然怎么说C是“低级高级语言”呢。而病毒/木马所采用的
“堆栈/缓冲区溢出攻击”,那才算真正的狠招呢,但是它们原理是同根的。可见,对底层
理解得深刻,能让我们写出更好,更强大的程序来。[/mw_shl_code]
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-12-19 14:23:29 | 显示全部楼层
中断函数不可以有返回值.
这个是不可以有的.
回复

使用道具 举报

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2016-11-11
在线时间
12 小时
 楼主| 发表于 2017-12-19 14:27:58 | 显示全部楼层
操作系统 发表于 2017-12-19 14:23
中断函数不可以有返回值.
这个是不可以有的.

那换个思路,定时器中断函数里我用标志位,然后在主函数里判断标志位,在进行采集数据可否?
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-12-19 14:37:08 | 显示全部楼层
淡定 发表于 2017-12-19 14:27
那换个思路,定时器中断函数里我用标志位,然后在主函数里判断标志位,在进行采集数据可否?

当然可以,正确得 不能再正确了.
回复

使用道具 举报

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2016-11-11
在线时间
12 小时
 楼主| 发表于 2017-12-19 15:52:05 | 显示全部楼层
操作系统 发表于 2017-12-19 14:37
当然可以,正确得 不能再正确了.

嗯,当时考虑在服务函数里做会很方便,但没想到会出现这样的问题。谢谢指导
回复

使用道具 举报

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2016-11-11
在线时间
12 小时
 楼主| 发表于 2017-12-19 16:10:09 | 显示全部楼层
wxjhby 发表于 2017-12-19 14:42
Cortex M3 权威指南(中文).PDF   169页  可能有你需要的
[mw_shl_code=c,true]// 使用C写成的SVC服务例 ...

谢谢大佬分享,我仔细看了文档,不过我的知识体系太薄弱,有很多地方看不太懂,大致了解了我的问题是可以由底层操作来完成,再次感谢。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-23 18:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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