发布于2021-10-16 19:15 阅读(2320) 评论(0) 点赞(25) 收藏(3)
main函数初始化时,关闭CPU的中断使能,清除不断标志,一般都是这么写的:
- IER = 0x0000;
- IFR = 0x0000;
但是,CCS却提示:
Symbol 'IER' could not be resolved
可是呢,编译整个工程时,也不会报错。
<Linking>
Finished building target: "DCDC.out"
"D:/ti/ccs1040/ccs/utils/tiobj2bin/tiobj2bin" "DCDC.out" "DCDC.bin" "D:/ti/ccs1040/ccs/tools/compiler/ti-cgt-c2000_20.2.5.LTS/bin/ofd2000" "D:/ti/ccs1040/ccs/tools/compiler/ti-cgt-c2000_20.2.5.LTS/bin/hex2000" "D:/ti/ccs1040/ccs/utils/tiobj2bin/mkhex4bin"
**** Build Finished ****
那么,IER是什么?为什么IER不能解析呢?这种写法到底是否符合C语言规范呢?
首先,IER是一个寄存器。并且是CPU内核的寄存器。IFR也一样。
与外设寄存器类似,在CCS的编译环境中,都把这类寄存器当作一个全局变量来处理。
比如,要使能PIE中的ADCD1中断,则是直接改变PieCtrlRegs这个全局变量中的某个位。
PieCtrlRegs.PIEIER1.bit.INTx6 = 1; /* PIE Group 1.6, ADCD1_INT*/
C语言规范要求,在使用变量之前,必须先声明,并且要在合适的地方定义这个变量。那么,外设寄存器这一类的全局变量在哪里声明和定义的呢?
在headers\include文件夹中,有各个外设寄存器变量的类型定义,以及全局变量的声明。
比如,在F2837xD_piectrl.h中:
- struct PIE_CTRL_REGS {
- union PIECTRL_REG PIECTRL; // ePIE Control Register
- union PIEACK_REG PIEACK; // Interrupt Acknowledge Register
- union PIEIER1_REG PIEIER1; // Interrupt Group 1 Enable Register
- union PIEIFR1_REG PIEIFR1; // Interrupt Group 1 Flag Register
- union PIEIER2_REG PIEIER2; // Interrupt Group 2 Enable Register
- union PIEIFR2_REG PIEIFR2; // Interrupt Group 2 Flag Register
- union PIEIER3_REG PIEIER3; // Interrupt Group 3 Enable Register
- union PIEIFR3_REG PIEIFR3; // Interrupt Group 3 Flag Register
- union PIEIER4_REG PIEIER4; // Interrupt Group 4 Enable Register
- union PIEIFR4_REG PIEIFR4; // Interrupt Group 4 Flag Register
- union PIEIER5_REG PIEIER5; // Interrupt Group 5 Enable Register
- union PIEIFR5_REG PIEIFR5; // Interrupt Group 5 Flag Register
- union PIEIER6_REG PIEIER6; // Interrupt Group 6 Enable Register
- union PIEIFR6_REG PIEIFR6; // Interrupt Group 6 Flag Register
- union PIEIER7_REG PIEIER7; // Interrupt Group 7 Enable Register
- union PIEIFR7_REG PIEIFR7; // Interrupt Group 7 Flag Register
- union PIEIER8_REG PIEIER8; // Interrupt Group 8 Enable Register
- union PIEIFR8_REG PIEIFR8; // Interrupt Group 8 Flag Register
- union PIEIER9_REG PIEIER9; // Interrupt Group 9 Enable Register
- union PIEIFR9_REG PIEIFR9; // Interrupt Group 9 Flag Register
- union PIEIER10_REG PIEIER10; // Interrupt Group 10 Enable Register
- union PIEIFR10_REG PIEIFR10; // Interrupt Group 10 Flag Register
- union PIEIER11_REG PIEIER11; // Interrupt Group 11 Enable Register
- union PIEIFR11_REG PIEIFR11; // Interrupt Group 11 Flag Register
- union PIEIER12_REG PIEIER12; // Interrupt Group 12 Enable Register
- union PIEIFR12_REG PIEIFR12; // Interrupt Group 12 Flag Register
- };
-
- //---------------------------------------------------------------------------
- // PIECTRL External References & Function Declarations:
- //
-
- extern volatile struct PIE_CTRL_REGS PieCtrlRegs;
前面是PieCtrlRegs这个变量的类型定义:结构体struct PIE_CTRL_REGS;
后面是PieCtrlRegs这个变量的声明:extern volatile struct PIE_CTRL_REGS PieCtrlRegs;
再比如,在f28002x_gpio.h文件中:
-
- struct GPIO_DATA_REGS {
- union GPADAT_REG GPADAT; // GPIO A Data Register (GPIO0 to 31)
- union GPASET_REG GPASET; // GPIO A Data Set Register (GPIO0 to 31)
- union GPACLEAR_REG GPACLEAR; // GPIO A Data Clear Register (GPIO0 to 31)
- union GPATOGGLE_REG GPATOGGLE; // GPIO A Data Toggle Register (GPIO0 to 31)
- union GPBDAT_REG GPBDAT; // GPIO B Data Register (GPIO32 to 63)
- union GPBSET_REG GPBSET; // GPIO B Data Set Register (GPIO32 to 63)
- union GPBCLEAR_REG GPBCLEAR; // GPIO B Data Clear Register (GPIO32 to 63)
- union GPBTOGGLE_REG GPBTOGGLE; // GPIO B Data Toggle Register (GPIO32 to 63)
- Uint16 rsvd1[40]; // Reserved
- union GPHDAT_REG GPHDAT; // GPIO H Data Register (GPIO224 to 255)
- };
-
- struct GPIO_DATA_READ_REGS {
- Uint32 GPADAT_R; // GPIO A Data Read Register
- Uint32 GPBDAT_R; // GPIO B Data Read Register
- Uint16 rsvd1[10]; // Reserved
- Uint32 GPHDAT_R; // GPIO H Data Read Register
- };
-
- //---------------------------------------------------------------------------
- // GPIO External References & Function Declarations:
- //
- extern volatile struct GPIO_CTRL_REGS GpioCtrlRegs;
- extern volatile struct GPIO_DATA_REGS GpioDataRegs;
- extern volatile struct GPIO_DATA_READ_REGS GpioDataReadRegs;
同样的,前面也是寄存器变量的类型定义,后面是全局变量的声明。
变量声明只解决了编译问题,光声明还不够,如果只声明但不定义,则在链接过程中还会报错。那么,一定有一个地方去定义这些变量。答案就在headers\source\f28002x_globalvariabledefs.c文件中。
- //----------------------------------------
- #ifdef __cplusplus
- #pragma DATA_SECTION("GpioCtrlRegsFile")
- #else
- #pragma DATA_SECTION(GpioCtrlRegs,"GpioCtrlRegsFile");
- #endif
- volatile struct GPIO_CTRL_REGS GpioCtrlRegs;
-
- //----------------------------------------
- #ifdef __cplusplus
- #pragma DATA_SECTION("GpioDataReadRegsFile")
- #else
- #pragma DATA_SECTION(GpioDataReadRegs,"GpioDataReadRegsFile");
- #endif
- volatile struct GPIO_DATA_READ_REGS GpioDataReadRegs;
-
- //----------------------------------------
- #ifdef __cplusplus
- #pragma DATA_SECTION("GpioDataRegsFile")
- #else
- #pragma DATA_SECTION(GpioDataRegs,"GpioDataRegsFile");
- #endif
- volatile struct GPIO_DATA_REGS GpioDataRegs;
其中的“volatile struct GPIO_CTRL_REGS GpioCtrlRegs;”没有“extern”关键字,表示这是一个变量的定义。编译器会给该变量分配存储器空间。
特别需要说明的是,这里不光是定义了全局变量,还要与外设寄存器绑定起来。
在每个全局变量的前面,都有类似这样的编译指令:
#pragma DATA_SECTION(GpioCtrlRegs,"GpioCtrlRegsFile");
这条指令的意思是,告诉编译器,GpioCtrlRegs这个变量,不要随便放置到RAM中,而是要放到GpioCtrlRegsFile这个section.
那么,问题又来了,这个section又有什么用呢?跟GPIO控制寄存器这个外设又是如何关联的呢?
答案在cmd文件里。
打开 headers\cmd\f28002x_headers_nonbios.cmd文件看看。这里节选了ADC和GPIO相关的内容:
- MEMORY
- {
- ADCA : origin = 0x00007400, length = 0x00000080
- ADCC : origin = 0x00007500, length = 0x00000080
- ADCARESULT : origin = 0x00000B00, length = 0x00000018
- ADCCRESULT : origin = 0x00000B40, length = 0x00000018
- …………
- GPIOCTRL : origin = 0x00007C00, length = 0x00000200
- GPIODATAREAD : origin = 0x00007F80, length = 0x00000010
- GPIODATA : origin = 0x00007F00, length = 0x00000040
- …………
- }
-
- SECTIONS
- {
- AdcaRegsFile : > ADCA, type=NOINIT
- AdccRegsFile : > ADCC, type=NOINIT
- AdcaResultRegsFile : > ADCARESULT, type=NOINIT
- AdccResultRegsFile : > ADCCRESULT, type=NOINIT
- …………
- GpioCtrlRegsFile : > GPIOCTRL, type=NOINIT
- GpioDataReadRegsFile : > GPIODATAREAD, type=NOINIT
- GpioDataRegsFile : > GPIODATA, type=NOINIT
- …………
- }
可以看到,在MEMORY中定义了各外设对应的区间,其地址也CPU外设地址一致。在SECTIONS中,指定各个节(比如GpioCtrlRegsFile)要放置的空间(比如放置至GPIOCTRL区间)。
这样,整个链条都打通了。在C语言代码中,对寄存器变量的访问,最终就等同于对硬件寄存器的访问。
以上语法完全符合ANSI C语言规范。CCS只是在此基础上扩展了编译器指令。
那么,针对IER和IFR,CCS又是如何做的呢?
在C代码中,想要给IER赋值,自然也要先告诉编译器,有IER这个变量。
这个,当然是有的。必须有。比如,在F2837xD_device.h文件中:
- //
- // User To Select Target Device:
- //
- #define F28_2837xD TARGET
-
- //
- // Common CPU Definitions:
- //
- extern __cregister volatile unsigned int IFR;
- extern __cregister volatile unsigned int IER;
再比如,在X:\ti\c2000\C2000Ware_3_04_00_00\device_support\f28002x\headers\include\f28002x_device.h文件中,也有类似的定义:
-
-
- #ifndef __TMS320C28XX__
- #define __cregister
- #endif //__TMS320C28xx__
-
- extern __cregister volatile unsigned int IFR;
- extern __cregister volatile unsigned int IER;
这里出现了一个新的关键字:__cregister。关于这个关键字的说明如下。
查询手册:《TMS320C28x Optimizing C_C++ Compiler v21.6.0.LTS User's Guide (Rev. W)-spru514w.pdf》 第6.5.2章节,
The compiler extends the C/C++ language by adding the cregister keyword to allow high level language access to control registers. This keyword is available in normal mode, but not in strict ANSI/ISO mode (using the --strict_ansi compiler option). The alternate keyword, __cregister, provides the same functionality but is available in either strict ANSI/ISO mode or normal mode.
When you use the cregister keyword on an object, the compiler compares the name of the object to a list of standard control registers for the C28x (see Table 6-2). If the name matches, the compiler generates the code to reference the control register. If the name does not match, the compiler issues an error.
如果使用的是新的driverlib库,也有同样的声明。是在cpu.h文件中。比如
X:\ti\c2000\C2000Ware_3_04_00_00\driverlib\f28002x\driverlib\cpu.h文件中:
原文链接:https://blog.csdn.net/booksyhay/article/details/120795087
作者:sdjsdh
链接:http://www.phpheidong.com/blog/article/175404/16dd711b96c7e117030d/
来源:php黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 php黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-4
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!