好记性不如铅笔头

ARM, 操作系统, 编程

ARM学习随手笔记:获取当前中断号

作者最近在学习keil和ARM,哎,只能感叹自己老了,这里简单的记录下学习笔记吧。
备注:
这里的代码都是作者自己写的,作者刚开始学习ARM,对于汇编和C的混编时的PUSH和POP也不是非常清楚,不能保证正确性。
程序状态寄存器如下:

(图片来自《Cortex-M3权威指南》,版权归原作者所有)


中断控制及状态寄存器ICSR如下:

(图片来自《Cortex-M3权威指南》,版权归原作者所有)

作者的工程基于【ARM学习随手笔记:使用systick定时器】,修改main函数和中断响应函数:

/*
使用嵌入式汇编,没有使用返回值。增加第二个参数是因为这样可以占用掉R1。
*/
__asm void getirq1(int *pIrq, int unused)
{
	MRS R1,IPSR
	STR R1,[R0,#0x00]
	BX LR
}

/*
使用嵌入式汇编,使用返回值,这样R0会被自动占用。
*/

__asm int getirq2()
{
	MRS R0,IPSR
	BX LR
}

/*
使用内联汇编和虚拟寄存器方式获取IPSR的值,但是M3应该不支持这种语法,但是这里编译通过了,比较奇怪。
*/
int getirq3()
{
	int R0;
	__asm
	{
		MRS R0,IPSR
	}
	return R0;
}

/*
直接访问寄存器
*/
int getirq4()
{
	return (*((unsigned int *)0xE000ED04)) &0x3FF;
}

/* SysTick中断响应函数,参考startup_ARMCM3.s */
void SysTick_Handler(void)
{
	int irq1,irq2,irq3,irq4;
	
	getirq1(&irq1, 0);
	irq2 = getirq2();
	irq3 = getirq3();
	irq4 = getirq4();
	
	printf("SysTick_Handler Called irq1:%d irq2:%d irq3:%d irq4:%d\n",irq1,irq2,irq3,irq4);
}


int main(void)
{
	unsigned int *pControl = (unsigned int *)(0xE000E010);
	unsigned int *pReload = (unsigned int *)(0xE000E014);
	unsigned int *pCurrent = (unsigned int *)(0xE000E018);
	
	*pControl = 0;  //先关闭SysTick
	*pReload = 0xFFFFFFF; //设置定时值
	*pCurrent = 0;  //清理掉当前值
	*pControl = 0x7; //启动SysTick
	
	while(1)
		;
}

编译执行后使用模拟器运行如下图:

Leave a Reply

10 − 4 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据