打印

STVD自动生成的stm8_interrupt_vector.c中几个疑问

[复制链接]
44773|84
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yewuyi|  楼主 | 2009-11-3 11:26 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
如图:
1、在第一个地方是定义了一个函数还是声明了一个函数?!
2、在第二个地方0x82这个值指什么含义?!
3、NonHandledInterrupt这个字符串在哪里做了定义?!
4、在@far @interrupt void NonHandledInterrupt (void){}中使用了NonHandledInterrupt,但在用户程序中中断函数NonHandledInterrupt会被重新起个名字,这个为什么没有产生错误?!

截图00.jpg (111.58 KB )

截图00.jpg
沙发
yewuyi|  楼主 | 2009-11-3 16:11 | 只看该作者
怎么老是显示管理?!

论坛改成这样了吗?!

使用特权

评论回复
板凳
香水城| | 2009-11-3 16:19 | 只看该作者
1)是定义了一个函数,这个函数的名字就是NonHandledInterrupt。
2)不知道它的含义,你照抄就可以了。
3)请看1),就是在你指示的第一个地方定义。
4)被重新起个名字当然就没有错误了,:D

使用特权

评论回复
地板
yewuyi|  楼主 | 2009-11-3 16:46 | 只看该作者
本帖最后由 yewuyi 于 2009-11-3 16:48 编辑

感觉很失败,完全看不懂stm8_interrupt_vector.c这个文件是怎么‘潜伏工作’的。
第一个看不懂:typedef void @far (*interrupt_handler_t)(void);
看这个typedef有点晕,是把void-->@far (*interrupt_handler_t)(void)还是把void @far -->(*interrupt_handler_t)(void) ?这个typedef有什么意义吗?
第二个看不懂:
struct interrupt_vector {
unsigned char interrupt_instruction;
interrupt_handler_t interrupt_handler;
};
interrupt_instruction好象找不到在哪里用到了?!似乎是个空定义?空定义还定义它干什么?
interrupt_handler_t interrupt_handler;又是什么东西?interrupt_handler_t本身定义就看不到,用它做后面的interrupt_handler类型定义就更加弄不清了。而且interrupt_handler似乎也看不到那用到了,好象也是空白定义。
第三个看不懂:
@far @interrupt void NonHandledInterrupt (void)
{
/* in order to detect unexpected events during development,
    it is recommended to set a breakpoint on the following instruction
*/
return;
}
既然他是定义了一个函数,实际写自己的代码的时候,好象也从来不需要调用这个函数,这个函数内部除了一句return也什么也没有,它有什么用呢?
第四个看不懂:extern void _stext();
从extern看,_stext()是在别的地方定义了,但从哪里可以看到它呢?从注解看,似乎是复位入口有关,可能就是一条跳转指令什么的,但什么也看不到就没必要让我们看嘛。
第五个看不懂:struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)_stext}, /* reset */
{0x82, NonHandledInterrupt}, /* trap  */
{0x82, NonHandledInterrupt}, /* irq0  */
{0x82, NonHandledInterrupt}, /* irq1  */
{0x82, NonHandledInterrupt}, /* irq2  */
{0x82, NonHandledInterrupt}, /* irq3  */
{0x82, NonHandledInterrupt}, /* irq4  */
{0x82, NonHandledInterrupt}, /* irq5  */
{0x82, NonHandledInterrupt}, /* irq6  */
{0x82, NonHandledInterrupt}, /* irq7  */
{0x82, NonHandledInterrupt}, /* irq8  */
{0x82, NonHandledInterrupt}, /* irq9  */
{0x82, NonHandledInterrupt}, /* irq10 */
{0x82, NonHandledInterrupt}, /* irq11 */
{0x82, NonHandledInterrupt}, /* irq12 */
{0x82, NonHandledInterrupt}, /* irq13 */
{0x82, NonHandledInterrupt}, /* irq14 */
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, NonHandledInterrupt}, /* irq17 */
{0x82, NonHandledInterrupt}, /* irq18 */
{0x82, NonHandledInterrupt}, /* irq19 */
{0x82, NonHandledInterrupt}, /* irq20 */
{0x82, NonHandledInterrupt}, /* irq21 */
{0x82, NonHandledInterrupt}, /* irq22 */
{0x82, NonHandledInterrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};
0x82也不知道是什么天外来物?(interrupt_handler_t)_stext指的是何含义?NonHandledInterrupt又是什么的干活?
第六个不懂:从这个文件到底如何去理解STM8的中断是如何定位和工作的?!这些问题零零碎碎的,到底怎么把它系统性的弄清楚?!

截图00.jpg (122.75 KB )

截图00.jpg

使用特权

评论回复
5
roalychen| | 2009-11-3 17:24 | 只看该作者
一:typedef void @far (*interrupt_handler_t)(void);
我觉得是void @far -->(*interrupt_handler_t)(void)

二:
struct interrupt_vector {
unsigned char interrupt_instruction;
interrupt_handler_t interrupt_handler;
};
这个struct定义中断向量表_vectab, _vectab的使用看编译后的汇编,开Dissambly窗口来看

三:
@far @interrupt void NonHandledInterrupt (void)
{
/* in order to detect unexpected events during development,
    it is recommended to set a breakpoint on the following instruction
*/
return;
}
就是啥也不干,因为不是希望发生的中断.
调试的时候也可以在里面设个断点,侦测非预期的中断(注释说的)

四:extern void _stext();
看disassambly,估计是中断向量表如此,所以要写出来看看

五:struct interrupt_vector const _vectab[]
0x82---可能是什么指令的机器码?

六:_vectab这个Table装到了0x8000开始的中断向量表的位置,中断发生时就查这个表去执行对应的ISR

不知道这样理解对不对

使用特权

评论回复
6
mohanwei| | 2009-11-3 18:09 | 只看该作者
看来C标准都没人鸟的……呵呵
每个编译器厂家都喜欢搞自己的一套。想上手快一点就买个开发板,找里面的所谓“工程模板”改改……以后慢慢的读手册了

使用特权

评论回复
7
香水城| | 2009-11-3 18:37 | 只看该作者
哈哈,叶兄的这些问题统统都是C语言本身的问题,与楼上所说的“每个编译器厂家都喜欢搞自己的一套”完全没有关系。

等我明天有时间再回来说说你的问题吧,现在肚子饿了,要先回家吃饭了:P。

使用特权

评论回复
8
yewuyi|  楼主 | 2009-11-4 08:26 | 只看该作者
这些应该是C本身的东西,呵呵,主要是象俺这样的,没接受过完整的严格的C语言教育,基本属于C盲,所以每次换个编译器都有一大堆看不懂。

不过ST的这个C编译器和其它一些通用编译器,例如IAR、KEIL、HITECH等确实有比较大的差异,结果就晕掉了。

使用特权

评论回复
9
yewuyi|  楼主 | 2009-11-4 09:17 | 只看该作者
看汇编代码,main被作为一个普通函数调用,那调用时应该会自动把PC指针等压栈的把?main本身是一个永远也不退出的函数,这是否意味着白白浪费了一些堆栈空间?!

截图00.jpg (100.03 KB )

截图00.jpg

使用特权

评论回复
10
香水城| | 2009-11-4 12:18 | 只看该作者
现在让我们逐一看看4楼的问题:

1)typedef是C的标准关键字,用于定义新的数据类型,比如常见的:
typedef unsigned char uchar;
typedef unsigned int uint;

这样定义后,每次使用uchar 或 uint定义变量时将十分方便
uchar cvar;    相当于  unsigned char cvar;
uint icvar;    相当于  unsigned int icvar;

在这个定义语句中,typedef void @far (*interrupt_handler_t)(void); 它定义了一个函数指针类型,这个函数没有调用参数,也没有返回参数,这是一个指针长指针。这个指针类型的名字是interrupt_handler_t。

这里唯一一个非标准C语言的元素是@far。在STM8中,指定地址的长度可以有3种方式,@tiny使用1个字节表示地址,只能寻址地址范围0x00~0xFF;@near使用2个字节表示地址,只能寻址地址范围0x0000~0xFFFF;@far使用3个字节表示地址,寻址地址范围0x000000~0xFFFFFF。

待续。。。。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
zk09041004 + 1 很给力!
11
yewuyi|  楼主 | 2009-11-4 13:24 | 只看该作者
本帖最后由 yewuyi 于 2009-11-4 13:27 编辑

又认真看了看,大意已经明白了一点:
1、typedef void @far (*interrupt_handler_t)(void); 定义了一个函数指针的别名。
2、用interrupt_handler_t给interrupt_handler做类型限制,并定义了一个结构名interrupt_vector
3、用interrupt_vector和const做_vectab[]的类型限制,定义了一个元素为常量的数组.
4、数组的某一个元素:0x82, NonHandledInterrupt,0X82相当于unsigned char interrupt_instruction=0x82;从interrupt_instruction字面意思看似乎是中断指令,但为什么是0X82还是没弄明白。
5、@far @interrupt void NonHandledInterrupt (void)的意思:
   所有未用到的中断,其名字在中断向量数组内的名字都是NonHandledInterrupt,如果执行时PC异常跳到这个地址后,都会去执行NonHandledInterrupt这个函数而自动退出。
6、_vectab[]是否为编译器内部已经规定好的一个关键字,否则它如何正确的指向到中断的地址空间?
7、_stext的定义还是没查到在哪里有?!
8、现在最主要的是还是没有明白vectab[]里面数值是如何和正确跳转到中断入口联系起来。

使用特权

评论回复
12
yewuyi|  楼主 | 2009-11-4 13:26 | 只看该作者
mods0这个文件有什么作用?!在这个文件中的定义也没看到在哪里需要用到?!

#pragma space () @near
#pragma space [] @tiny
#pragma space auto [] @near
#pragma space * @near
#pragma space * () @near
#pragma space const @near
#define __MODS0__        1

使用特权

评论回复
13
IJK| | 2009-11-4 14:44 | 只看该作者
0x82是某个特别指令(CALL或者JUMP)的操作码

_vectab[]不是编译器内部规定好的一个关键字,需要在链接文件里把它链接到 中断向量的区域(0x8080还是0x8000)

_stext是编译器内部规定好的一个关键字

使用特权

评论回复
14
yewuyi|  楼主 | 2009-11-4 15:31 | 只看该作者

RE

本帖最后由 yewuyi 于 2009-11-4 15:35 编辑

1、生成的这个项目根目录下,看不到连接文件,在C:\Program Files\STMicroelectronics\st_toolset也没找到连接文件的影子,仅在H:\STdemo\demo\Debug和H:\STdemo\demo\Release下看到了demo.lkf这个问家,虽然lkf后缀和其它编译器的连接文件不一样,但打开文件看,这应该是一个编译需要的连接文件。在使用IAR等的时候,连接文件都是根据不同的CHIP单独编写,并在编译器设置中定位到对应目录下的,但这个demo.lkf似乎是在建立项目时自动生成的,这个连接文件是由STVD还是由COSMIC生成的呢?!打开这个demo.lkf文件,也没有看到有关_vectab[]关联定位信息。
2、另外有关CALL XXX的操作码的问题,CALL的指令长度是多长的?!如果是16BIT的,那么0X82是操作码占用了8个BIT,后面的8个BIT就是操作地址了把?那16BIT长度时就只能调用256BYTE程序空间的函数,如果是24BIT或者32BIT的,就可以调用0xffff或者0xfffff长度的函数,据说STM8最大的ROM空间达到了16Mbyte,那么CALL指令长度就应该要达到32BIT才刚好16M,也就是说CALL的指令格式为0x82+24BIT地址,这个理解对不对?

demo.lkf文件内容。
# LINK COMMAND FILE AUTOMATICALLY GENERATED BY STVD7
# SHOULD NOT BE MANUALLY MODIFIED
#
# Put you segment configuration here
# define the .share segment when using compact or memory models only
#<BEGIN SEGMENT_CONF>
# Segment Code,Constants:
+seg .const -b 0x8080 -m 0x1ff80 -n .const -it
+seg .text -a .const -n .text
# Segment Eeprom:
+seg .eeprom -b 0x4000 -m 0x800 -n .eeprom
# Segment Zero Page:
+seg .bsct -b 0x0 -m 0x100 -n .bsct
+seg .ubsct -a .bsct -n .ubsct
+seg .bit -a .ubsct -n .bit -id
+seg .share -a .bit -n .share -is
# Segment Ram:
+seg .data -b 0x100 -m 0x1300 -n .data
+seg .bss -a .data -n .bss
#<END SEGMENT_CONF>

# Put you startup file here (it depends on the model used)
#<BEGIN STARTUP_FILE>
crtsi0.sm8
#<END STARTUP_FILE>

# Put your object files here (they depend on you application)
#<BEGIN OBJECT_FILES>
Debug\main.o
#<END OBJECT_FILES>

# Put your library name here (it depends on the model used)
#<BEGIN LIBRARY_FILES>
libis0.sm8
libm0.sm8
#<END LIBRARY_FILES>

# Put your interrupt vectors file here if needed
#<BEGIN VECTOR_FILE>
+seg .const -b 0x8000 -k
Debug\stm8_interrupt_vector.o
#<END VECTOR_FILE>
#<BEGIN DEFINED_VARIABLES>
+def [email=__endzp=@.ubsct]__endzp=@.ubsct[/email]   # end of uninitialized zpage
+def [email=__memory=@.bss]__memory=@.bss[/email]    # end of bss segment
+def __stack=0x17ff
#<END DEFINED_VARIABLES>

使用特权

评论回复
15
grant_jx| | 2009-11-4 23:47 | 只看该作者
1、lkf是链接用的命令文件,有STVD自动产生,在STVD路径中可以找到原始文件,但文件仅有框架,内容是由STVD根据所选芯片自动添加的。lkf原始文件在:。。。\STMicroelectronics\st_toolset\stvd\builder\ST7LkfFile.lkf.

2、Stack Short (mods0) global variables are defaulted to short range.
Any global object in long range will have to be accessed explicitly
with the @near modifier unless accessed through a pointer.

3、
CALLF - Extended Direct addressing mode (only for CALLF and JPF)
The address is an extended word, thus allowing 000000 to FFFFFF addressing space, but
requires 3 bytes after the op-code.
    Example:CALLF $123456
    Op: PC← PC + 4
             M(SP--) ← PCL
             M(SP--) ← PCH
             PCH← M(longmem)
             PCL← M(longmem + 1)

CALL    -  Call to Subroutine with address in same section
    Example:CALL [$1234.w]
   Op   PC = PC+lgth
          (SP--) = PCL
          (SP--) = PCH
          PC = dst

CALLR  -  Call Subroutine relative
    The current PC register value is pushed onto the stack, then PC is loaded
with the relative destination addresss. This instruction is used, once a
program is debugged, to shrink the overall program size. The CALLR
destination and the corresponding RET instruction address must be in the
same section, as PCE is not stacked.

老兄要仔细看看PM0044 - STM8 CPU programming manual.pdf  关于汇编指令集的解释啊。

使用特权

评论回复
16
精益求精| | 2009-11-5 09:27 | 只看该作者
mark....

使用特权

评论回复
17
yewuyi|  楼主 | 2009-11-5 09:43 | 只看该作者
呵呵,grant_jx教育的极是,俺只是查了查手册,上面没有看到汇编指令集就跳过了,呵呵,现在一些新出的芯片都不给看指令集,俺就认为暂时看不看也无所谓了。。。 1、从lkf命令文件中还是看不到_vectab[]的连接定位,只有两处有关const的定位 CODE部分:+seg .const -b 0x8080 -m 0x1ff80 -n .const -it interrupt vectors 部分:+seg .const -b 0x8000 -k 但_vectab[]如何被连接到interrupt vectors中的const部分而不是被连接到CODE中的CONST部分总应该有个指定的方式,例如通过某个系统内部的关键字就默认必须放在interrupt vectors中!!! 2、翻了PM0044文件,CALL、CALLF、CALLR的操作码都不是0x82,而且翻遍了整个指令集,似乎根本就没0x82这个操作码。从interrupt_handler_t interrupt_handler定义中可理解为这个函数指针是可以指向整个CODE空间的任意位置,可以全空间访问,但因为CODE最大可以达到16M,所以,应该执行的最大地址空间调用的CALLF指令,但0x82似乎并不是CALLF的指令。 3、在mods0.h文件中定义#define __MODS0__ 1 ,但我看项目文件的配置窗口有相关的mods0的设置,请问,这两者之间的关联是什么?!
2、以下的宏扩展似乎根本没什么意义?!在STVD中有什么作用?!
#pragma space () @near
#pragma space [] @tiny
#pragma space auto [] @near
#pragma space * @near
#pragma space * () @near
#pragma space const @near

截图00.jpg (59.75 KB )

截图00.jpg

使用特权

评论回复
18
yewuyi|  楼主 | 2009-11-5 16:38 | 只看该作者
现在让我们逐一看看4楼的问题:

1)typedef是C的标准关键字,用于定义新的数据类型,比如常见的:
typedef unsigned char uchar;
typedef unsigned int uint;

这样定义后,每次使用uchar 或 uint定义变量时将十分 ...
香水城 发表于 2009-11-4 12:18


香水城主,你的续集什么时候再有啊?!
哈哈,俺有一大堆问题呢。。。

使用特权

评论回复
19
yewuyi|  楼主 | 2009-11-5 16:43 | 只看该作者
像俺这么爱学的学生不多了啊,俺可准备了《十万个问什么》等着问了哦。。。

呵呵,俺是有真实批量需求的用户啊,俺就等弄清楚了各种问题后评估项目呢。。。

郁闷,10月出差20天,把学习时间都浪费了。。。

使用特权

评论回复
20
香水城| | 2009-11-5 17:10 | 只看该作者
香水城主,你的续集什么时候再有啊?!
哈哈,俺有一大堆问题呢。。。
yewuyi 发表于 2009-11-5 16:38


昨天写到一半被拉去开会见客户,就停手了,回来发现楼主位的问题已经都被回答了。难道还需要我再逐一注解一下楼主位的问题?

使用特权

评论回复
评论
hello_海涛 2018-1-19 11:04 回复TA
香水哥,能不能分享个例程啊 我在用stm8l10x的外部中断,好久没调通。程序老是进入NonHandledInterrupt中断,还在摸索~ 724944311@qq.com 谢谢~ 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:一:我的回帖多数只是猜测/估计/想象,建立在我现有知识结构的理解和分析上,多数都没有动手实际检验过,请斟酌采纳. 二:若对我的技术类主帖或回帖有异议,欢迎讨论,拒绝过激攻击或辱骂,否则全站追杀屏蔽发帖,后果自负. 三:对本人的其它意见,请直接向站长投诉,勿使用站内短信骚扰/挑衅/辱骂,否则将全站追杀屏蔽发帖,后果自负.

1416

主题

20007

帖子

232

粉丝