TI中文支持网
TI专业的中文技术问题搜集分享网站

sitara系列 访问寄存器问题咨询

Other Parts Discussed in Thread:AM3359

请教一下:

1、sitara系列的ARM端程序访问外设寄存器,是不是只能通过指针的形式?

2、用C2000的那种位域结构体定义的外设头文件访问外设寄存器,进调试模式系统就跑飞。把头文件换成指针结构就没问题

Nancy Wang:

操作位应该也是可以的,但一般通过指针来访问,寄存器部分的详细配置选项一般都会定义好,直接操作就可以了。

,

user18914063:

比较好奇,用位域结构体访问为什么会跑飞,而指针结构访问就没问题,这个和是否开启MMU功能有关系吗,另外,我调试sitara系列的ARM端的时候,程序运行时,寄存器观察窗口显示的片内外设寄存器都无法观察,显示的是不能识别,只能暂停或者打断点程序运行到断点处停下来才能正确观察到寄存器,这个是不是也和MMUC是否开启有关系呢?

,

Nancy Wang:

user18914063 说:我调试sitara系列的ARM端的时候,程序运行时,寄存器观察窗口显示的片内外设寄存器都无法观察,显示的是不能识别,只能暂停或者打断点程序运行到断点处停下来才能正确观察到寄存器,这个是不是也和MMUC是否开启有关系呢?

是裸机下还是RTOS或者Linux?有没有基于TI给出的例程上测试看一下能否看到寄存器。

位域结构体访问方式贴出来看一下。跟指针访问测试的是同一个寄存器吗?

,

user18914063:

你好,是裸机代码,位域结构体的相关地址分配定义在AM3359的CMD文件里面,这种访问导致跑飞,然后改成了指针形式,相关代码如下:
// GPIO 寄存器组
struct hw_GPIORegs
{Uint32Revision;//IP核版本Uint32rsvd1[3];union GPIOSYS_CONFIGConfig;//系统配置Uint32rsvd2[3];union GPIO_EOIEoi;union GPIO_RegsIRQSTATUS_RAW0;union GPIO_RegsIRQSTATUS_RAW1;union GPIO_RegsIRQSTATUS0;union GPIO_RegsIRQSTATUS1;union GPIO_RegsIRQSTATUS_SET0;union GPIO_RegsIRQSTATUS_SET1;union GPIO_RegsIRQSTATUS_CLR0;union GPIO_RegsIRQSTATUS_CLR1;union GPIO_RegsIRQWAKEN0;union GPIO_RegsIRQWAKEN1;Uint32rsvd3[50];union GPIO_SYS_STATUSSYS_STATUS;Uint32rsvd4[6];union GPIORegs_CTRLCtrl; //控制寄存器union GPIO_RegsOE;//输出使能,方向寄存器union GPIO_RegsIN_DATA;//输入数据寄存器union GPIO_RegsOUT_DATA;//输出数据寄存器union GPIO_RegsLowLevelDetection0;//低电平检测使能union GPIO_RegsLowLevelDetection1;//低电平检测使能union GPIO_RegsRisDetection;//上升沿检测使能union GPIO_RegsFalDetection;//下降沿检测使能union GPIO_RegsDebouncEnable;//去抖动使能union GPIO_DEBOUNCTIMEDebouncTime;//去抖动时间Uint32rsvd5[14];union GPIO_RegsCLR_DATAOUT;//复位寄存器union GPIO_RegsSET_DATAOUT;//置位寄存器Uint32rsvd6[922];
};
// GPIO 外设存储空间映射
extern volatile struct hw_GPIORegsGpioARegs;
extern volatile struct hw_GPIORegs*GpioBRegs;
extern volatile struct hw_GPIORegs*GpioCRegs;
extern volatile struct hw_GPIORegs*GpioDRegs;

以上是GPIO的寄存器,很奇怪,端口A可以直接按位域结构体的形式定义在CMD文件里面,其余IO口只能是指针形式,下面是A口在CMD文件里面的地址分配
MEMORY
{PAGE 0:/* Program Memory */PAGE 1:/* Data Memory *///ETH_DESCRIPTOR: o = 0x4A102000,l = 0x00000100/* 256B MDIO物理地址 *///MDIO_REG: o = 0x4A101000,l = 0x00000100/* 256B MDIO物理地址 *///CM_PER_REG: o = 0x44E00000,l = 0x00000400/* 1KB CM_PER物理地址 *///CM_WKUP_REG: o = 0x44E00400,l = 0x00000100/* 256B CM_PER物理地址 *///CM_DPLL_REG: o = 0x44E00500,l = 0x00000100/* 256B CM_PER物理地址 *///CM_MPU_REG: o = 0x44E00600,l = 0x00000100/* 256B CM_PER物理地址 *///CM_DEVICE_REG: o = 0x44E00700,l = 0x00000100/* 256B CM_PER物理地址 *///CM_RTC_REG: o = 0x44E00800,l = 0x00000100/* 256B CM_PER物理地址 *///CM_CEFUSE_REG: o = 0x44E00A00,l = 0x00000100/* 256B CM_PER物理地址 */
//PRM_PER_REG: o = 0x44E00C00,l = 0x00000100/* 256B CM_PER物理地址 *///PRM_CEFUSE_REG: o = 0x44E01200,l = 0x00000100/* 256B CM_PER物理地址 *///CTRL_MODULEREG: o = 0x44E10000,l = 0x00002000/* 128KB 控制模块物理地址 */GPIOAREG: o = 0x44E07000,l = 0x00001000/* 4KB GPIOA物理地址 *///GPIOBREG: o = 0x4804C000,l = 0x00001000/* 4KB GPIOB物理地址 *///GPIOCREG: o = 0x481AC000,l = 0x00001000/* 4KB GPIOC物理地址 *///GPIODREG: o = 0x481AE000,l = 0x00001000/* 4KB GPIOD物理地址 *///TIMER2_REG: o = 0x48040000,l = 0x00001000/* 4KB GPIOD物理地址 *///INTCREG: o = 0x48200000,l = 0x00001000/* 4KB GPIOD物理地址 *///PWMSS0REG:o = 0x48300000l = 0x00000100/* 4KB PWMSS0物理地址 *///ECAP0REG: o = 0x48300100l = 0x00000080/* 80B Ecap0物理地址 */
//PWMSS1REG:o = 0x48302000l = 0x00000100/* 4KB PWMSS1物理地址 *///ECAP1REG: o = 0x48302100l = 0x00000080/* 80B Ecap0物理地址 */
//PWMSS2REG:o = 0x48304000l = 0x00000100/* 4KB PWMSS2物理地址 *///ECAP2REG: o = 0x48304100l = 0x00000080/* 80B Ecap0物理地址 */

}

SECTIONS
{//.Eth_DescriptorFile : >ETH_DESCRIPTOR
.GpioARegsFile: >GPIOAREG//.GpioBRegsFile: >GPIOBREG//.GpioCRegsFile: >GPIOCREG//.GpioDRegsFile: >GPIODREG
//.CM_PER_RegsFile: >CM_PER_REG,PAGE = 1//.CM_WKUP_RegsFile: >CM_WKUP_REG//.CM_DPLL_RegsFile: >CM_DPLL_REG//.CM_MPU_RegsFile: >CM_MPU_REG//.CM_DEVICE_RegsFile: >CM_DEVICE_REG//.CM_RTC_RegsFile: >CM_RTC_REG//.CM_CEFUSE_RegsFile: >CM_CEFUSE_REG
//.CTRL_MODULERegsFile : >CTRL_MODULEREG

//.PRM_PER_RegsFile: >PRM_PER_REG//.PRM_CEFUSE_RegsFile : >PRM_CEFUSE_REG//.INTCRegsFile: >INTCREG//.PWMSS0RegsFile>PWMSS0REG//.ECap0RegsFile>ECAP0REG
//.PWMSS1RegsFile>PWMSS1REG//.ECap1RegsFile>ECAP1REG
//.PWMSS2RegsFile>PWMSS2REG//.ECap2RegsFile>ECAP2REG
//.MDIORegsFile: > MDIO_REG//.TIMER2_RegsFile:>TIMER2_REG
}
用双斜杠屏蔽掉的地址分配都只能是指针形式,都在另一个C文件里面单独定义,如下:
/** AM335x_GPIODefs.c**Created on: 2021年3月13日*Author: 二哥*/
#include "AM335x_Device.h"

#pragma DATA_SECTION(GpioARegs,".GpioARegsFile");//这里A口可以使用位域结构体,所以在CMD里面分配地址
volatile struct hw_GPIORegsGpioARegs;

//#pragma DATA_SECTION(GpioBRegs,".GpioBRegsFile");
//volatile struct hw_GPIORegsGpioBRegs;
volatile struct hw_GPIORegs *GpioBRegs = (volatile struct hw_GPIORegs *)0x4804C000;
//volatile struct hw_GPIORegsGpioBRegs __attribute__((location(0x4804C000)));

//#pragma DATA_SECTION(GpioCRegs,".GpioCRegsFile");
//volatile struct hw_GPIORegsGpioCRegs __attribute__((location(0x481AC000)));
volatile struct hw_GPIORegs *GpioCRegs = (volatile struct hw_GPIORegs *)0x481AC000;

//#pragma DATA_SECTION(GpioDRegs,".GpioDRegsFile");
//volatile struct hw_GPIORegsGpioDRegs;
volatile struct hw_GPIORegs *GpioDRegs = (volatile struct hw_GPIORegs *)0x481AE000;

,

user18914063:

以上,不管是A口的直接位域结构体访问寄存器,还是指针访问寄存器,在调试模式的运行期间都不能在寄存器窗口观察,必须暂停下来才能观察到。上面文件是我看了3359技术参考手册后自己独立完成的。

,

user18914063:

#define LED1 GpioBRegs->OUT_DATA.bit.GPIO4
#define LED2 GpioBRegs->OUT_DATA.bit.GPIO5
#define LED3 GpioBRegs->OUT_DATA.bit.GPIO7

#define LED5 GpioARegs.OUT_DATA.bit.GPIO20
#define LED6 GpioARegs.OUT_DATA.bit.GPIO19

以上位定义都能正常工作,相关LED完全受控制

,

user18914063:

我的理解是,指针是间接访问,在CMD文件里面分配地址的位域结构体那种是直接访问,这就是两种访问的唯一区别,但直接访问导致跑飞,感觉是MMU没有开启的缘故,我也只是猜测

,

user18914063:

其它外设的寄存器访问也是完全相同的情况,包括PRCM,电源,复位,时钟,这些系统基本的控制寄存器

赞(0)
未经允许不得转载:TI中文支持网 » sitara系列 访问寄存器问题咨询
分享到: 更多 (0)