今天是学习LM3s1138的第二天,我们接着昨天的继续学习。昨天我打开了SystemInit.h的头文件,深入学习了里面的hw_types.h子头文件。今天我开始学习另外的几个头文件:hw_memmap.h 。这个头文件就比较简单了从字面意思看就知道是存储器映射的头文件。我们打开看看,果不其然:
这和LM3s1138datasheet上是一样的:
只是这个头文件里面只定义了它的起始地址。
还有些存储器的映射我这里就不一一例举了。
好,接下来看看hw_ints.h里面的东西:
从第一行看这是一个定义错误的任务;我们看看datasheet上是怎么说的:
我的理解是这样的:CPU的中断是由异常引发的,异常也有多种。于是怎么处理多个异常呢?ARM Cortex-M3处理器和嵌套向量中断控制器(NVIC)区分所有的异常并对其进行处理。在出现异常时,处理器的状态被自动存储在堆栈中,并在中断服务程序结束后自动从堆栈中恢复。所以CPU先给每个异常分配一个堆栈地址即向量号。这样就处理好了异常的先后顺序。比如:
#define FAULT_NMI 2 就表示不可屏蔽的中断(NMI)是优先级为2的级别
这里就用 FAULT_NMI 表示它在堆栈中的具体优先级2,这样既清楚又方便。
其他的同理。
继续往下看:
这定义的是中断顺序号和上面的异常是一样的,这里就不在啰唆了。 好,那么关于hw_ints.h头文件就初步学习了。
下午再看下面的<interrupt.h>:
//*****************************************************************************
//
// interrupt.h - Prototypes for the NVIC Interrupt Controller Driver.
//
// Copyright (c) 2005-2008 Luminary Micro, Inc. All rights reserved.
//
// Software License Agreement
#ifndef __INTERRUPT_H__
#define __INTERRUPT_H__
//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Macro to generate an interrupt priority mask based on the number of bits
// of priority supported by the hardware.
//
//*****************************************************************************
#define INT_PRIORITY_MASK ((0xFF << (8 - NUM_PRIORITY_BITS)) & 0xFF)
//*****************************************************************************
//
// Prototypes for the APIs.
//
//*****************************************************************************
extern tBoolean IntMasterEnable(void);
extern tBoolean IntMasterDisable(void);
extern void IntRegister(unsigned long ulInterrupt, void (*pfnHandler)(void));
extern void IntUnregister(unsigned long ulInterrupt);
extern void IntPriorityGroupingSet(unsigned long ulBits);
extern unsigned long IntPriorityGroupingGet(void);
extern void IntPrioritySet(unsigned long ulInterrupt,
unsigned char ucPriority);
extern long IntPriorityGet(unsigned long ulInterrupt);
extern void IntEnable(unsigned long ulInterrupt);
extern void IntDisable(unsigned long ulInterrupt);
//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif
看起来有点复杂,但是不要怕相信毛主席那句“一切反动派都是纸老虎”。一步一步来看。先看看说明文档。英文意思是说intrrupt.h头文件是NVIC中断控制器的驱动器原型。再下面的英文意思是如果是一个C++编译器,要把#ifdef __cplusplus
extern "C"
{
#endif 包含进去。这里声明了一个外部变量“C”,只要__cplusplus在前面被定义过,那么就可以使用 “C”这个字符了。这种条件编译对于提高C源程序的通用性是很有好处的。如果一个C源程序在不同计算机系统上运行,而不同的计算机又有一定的差异(例如,有的机器以16位存放一个整数,有的是32位存放一个整数),这样往往需要对源程序做必要的修改,这就降低了程序的通用性。
再回到这里,那如果没有申明__cplusplus呢?查查《C语言程序设计》的条件编译那节说得很详细。就执行下面的程序。这里我想好好复习下《C语言程序设计》。条件编译是对意思就是希望程序中一部分内容旨在满足一定条件时才编译,这对于处理器节省内存是很有用的。具体的例子下次碰到再好好研究,呵呵~~
继续往下看是说宏#define INT_PRIORITY_MASK ((0xFF << (8 - NUM_PRIORITY_BITS)) & 0xFF) 生成一个中断优先码,这个优先码是由硬件支持的优先级别。算算这个INT_PRIORITY_MASK到底等于多少。先要查出NUM_PRIORITY_BITS是多少,我猜应该在上文说道的hw_ints.h里面。果不其然:
我用鼠标划过的就是它的出处,再返回去hw_ints.h看看它是何方神圣。上面的英文说它是优先级的总数。再结合上面的 #define NUM_INTERRUPTS 64 。因为Cortex-M3有64个中断源,这样是为了方便统计。同理#define NUM_PRIORITY_BITS 3 也是对某种类型中断的统计并且这种中断有3个,但是具体哪三个我就真的不知道了。查了datasheet也没发现。先放在这里,以后再来解决。反正我知道NUM_PRITORITY_BITS就是3。再回去算得INT_PRIORITY_MASK 是224。这个224又有什么含义呢?我找了好久的资料,还是一头雾水。也先放着。我们重点看下面的API函数原型。看第一个:
extern tBoolean IntMasterEnable(void); 它是一个外部函数,函数的返回值是tBoolean类型。那么什么是tBoolean类型呢?(字面意思是布尔型的)打开这个函数:
tBoolean
IntMasterEnable(void)
{
//
// Enable processor interrupts.
//
return(CPUcpsie());
}
这是一个使能处理器中断的函数,ZLG是这么解释的:如果在调用该函数之前处理器中断是使能的,则返回false;如果在调用该函数之前处理器中断是禁止的,则返回true。那么接下来:extern tBoolean IntMasterDisable(void); 这个函数就好理解了,它是一个禁止处理器中断的函数。如果在调用该函数之前处理器中断是使能的,则返回false;如果在调用该函数之前处理器中断是禁止的,则返回true。写到这里,我决定要先放一放这个
实在是有复杂,先去上课了。以后再来琢磨
用户377235 2012-1-17 23:04
很不错
用户178464 2010-11-24 16:24