位操作( Bit manipulation )
1. 嵌入式系统总是要用户对变量或寄存器进行位操作。 给定一个整型变量 a ,写两段代码,第一个设置 a 的 bit 3 ,第二个清除 a 的 bit 3 。在以上两个操作中,要保持其它位不变。
对这个问题有三种基本的反应
1) 不知道如何下手。该被面者从没做过任何嵌入式系统的工作。
2) 用 bit fields 。 Bit fields 是被扔到 C 语言死角的东西,它保证你的代码在不同编译器之间是不可移植的,同时也保证了的你的代码是不可重用的。我最近不幸看到 Infineon 为其较复杂的通信芯片写的驱动程序,它用到了 bit fields 因此完全对我无用,因为我的编译器用其它的方式来实现 bit fields 的。从道德讲:永远不要让一个非嵌入式的家伙粘实际硬件的边。
3) 用 #defines 和 bit masks 操作 。这是一个有极高可移植性的方法,是应该被用到的方法。最佳的解决方案如下:
#define BIT3 (0x1 << 3)
static int a;
void set_bit3(void)
{
a |= BIT3;
}
void clear_bit3(void)
{
a &= ~BIT3;
}
一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明常数,这也是可以接受的。我希望看到几个要点:说明常数、 |= 和 &=~ 操作。
访问固定的内存位置( Accessing fixed memory locations )
10. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为 0x67a9 的整型变量的值为 0xaa66 。编译器是一个纯粹的 ANSI 编译器。写代码去完成这一任务。
这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换( typecast )为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下:
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;
A more obscure approach is:
一个较晦涩的方法是:
*(int * const)(0x67a9) = 0xaa55;
即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案。
中断( Interrupts )
2. 中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展 — 让标准 C 支持中断。 具代表事实是,产生了一个新的关键字 __interrupt 。下面的代码就使用了 __interrupt 关键字去定义了一个中断服务子程序 (ISR) ,请评论一下这段代码的。
__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf(""nArea = %f", area);
return area;
}
这个函数有太多的错误了,以至让人不知从何说起了:
1) ISR 不能返回一个值 。如果你不懂这个,那么你不会被雇用的。
2) ISR 不能传递参数 。如果你没有看到这一点,你被雇用的机会等同第一项。
3) 在许多的处理器 / 编译器中,浮点一般都是不可重入的。有些处理器 / 编译器需要让额处的寄存器入栈,有些处理器 / 编译器就是不允许在 ISR 中做浮点运算。此外, ISR 应该是短而有效率的,在 ISR 中做浮点运算是不明智的。
4) 与第三点一脉相承, printf() 经常有重入和性能上的问题。 如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。
http://blog.sina.com.cn/s/blog_4a9a031b0100ekud.html