StellarisWare中的错误处理机制
在驱动库中,用一种非传统的方法来处理无效的参数和错误条件,通常函数检查自己的参数,来确保他们的值有效(如果需要,某些参数可能是无条件有效的,如:用作32定时器装载值的一个32位值),如果一个无效的参数被传入的话,则函数就会返回一个错误的代码,然后调用者必须检查每次函数调用的返回代码来确保调用成功。
但是这会导致在每个函数中有大量的参数检查代码,对于一个自我完备的程序代码,一旦应用被调试,这些额外的代码就会变成不需要的负担。在驱动库中,大多数函数不返回错误(FlashProgram();FlashErase()、FlsahProtectSave()、FlashProtectSet()例外)通过调用宏ASSERT来执行参数检查,这个宏有着一个断言宏的常规定义;他接受为一个必须为“true”的表达式;可以通过使用这个宏变成空来从代码中删除参数检查。在debug.h中提供了ASSERT的两个定义:
#ifdef DEBUG
#define ASSERT(expr) { \
if(!(expr)) \
{ \
__error__(__FILE__, __LINE__); \
} \
}
#else
#define ASSERT(expr)
#endif
一个为空(通常情况下都使用这个宏定义);
一个为被用来判断表达式(当库在调试中编译时使用这个定义)
调试情况中将在表达式不为真时调用__error__(__FILE__, __LINE__)函数;传递文件名称和ASSERT宏调用的行编号。而__error__(__FILE__, __LINE__)函数的原型在debug.h中,必须由应用程序来提供,因为是应用程序来负责处理错误条件的。通过在__error__函数中设置一个断点,调试器就能在应用出现错误时立刻停止运行(其他的错误处理方法处理起来可能很困难)。当调试器停止时,__error__函数的参数很堆栈的回溯会精确地指出发现错误的函数、发现的问题和它被调用的地方。
例如:
Long GPIOPinRead(unsigned long ulPort,
unsigned char ucPins)
{
// 参数检查
ASSERT(GPIOBaseValid(ulPort));
// Return the pin value(s).
return(HWREG(ulPort + (GPIO_O_DATA + (ucPins << 2))));
}