6. 中断是嵌入式中重要的组成部分,中断服务程序通常需要满足哪些要求?
中断是嵌入式系统中重要的组成部分,很多外设和cpu的交互都是通过中断的方式进行。衡量一个OS的实时性很重要的一个特性就是中断的响应时间,长时间处于中断状态所以中断反应。一旦进入中断状态,cpu是在占用的,所以必须快速的出中断,否则会影响整体性能。
中断服务程序需要满足如下要求:
不能返回值;不能向ISR传递参数;ISR应该尽可能的短小精悍;要尽快出中断;耗时的中断要放到中断的底半部;中断不要调用会因其休眠的函数;通常中断中不做浮点操作;中断函数中不可调用不可重入的函数,会引起意想不到的问题。
7. 使用共享资源时,为了使之满足互斥条件,通常有哪些方法?
共享资源也叫临界资源,在进程和线程、内核下都有自己的同步互斥机制,仅考虑互斥的话,分开来看:
进程:信号量(值设置为1)线程:互斥体、信号量(也叫信号灯)内核:原子操作,自旋锁,信号量,互斥锁
8. 嵌入式操作系统有哪些同步通信服务?
Linux进程间通信方式主要有
信号信号量管道消息队列共享内存套接字(本地的还有域套接字)9. 请举例说明什么是可重入函数与不可重入函数。
1. 不可重入函数
在实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果有一个函数不幸被设计成为不可重入这样:那么不同任务调用这个函数时可能修改其他任务调用这个函数的数据,从而导致不可预料的后果。这样的函数是不安全的函数,也叫不可重入函数。
满足下列条件的函数多数是不可重入的
函数体内使用了静态的数据结构;函数体内调用了malloc()或者free()函数(malloc和free为不可重入函数);函数体内调用了标准I/O函数。
2. 可重入函数
可重入函数可以被一个以上的任务调用,而不必担心数据被破坏。可重入函数任何时候都可以被中断,一段时间以后又可以运行,而相应的数据不会丢失。可重入函数或者只使用局部变量,即保存在CPU寄存器中或堆栈中;或者使用全局变量,则要对全局变量予以保护
如何写出可重入函数在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用缺省态(auto)局部变量,写出的函数就将是可重入的。如果必须访问全局变量,记住利用互斥信号量来保护全局变量。或者调用该函数前关中断,调用后再开中断。Linux常见的可重入函数
3. 举例
A) 可重入函数
void strcpy(char * dest, char * src) {
while(*dest++=*src++);
*dest = 0;
}
B) 不可重入函数1
char temp;//全局变量
void swapchar(char * x, char * y) {
temp = *x;
*x=*y;
*y=temp;//访问了全局变量
}
C) 不可重入函数2
void swapchar(char * x, char * y) {
char temp;//局部变量
temp = *x;
*x=*y;
*y=temp;//使用了全局变量
}
4. 不可重入函数的使用注意事项
int Exam = 0;
unsigned int example( int para )
{
unsigned int temp;
Exam = para; // (**)
temp = Square_Exam( );
return temp;
}
Exam 是 int 型全局变量,函数 Squre_Exam() 返回 Exam 平方值,所以函数example()不具有可重入性。
此函数若被多个进程调用的话,其结果可能是未知的,因为当 Exam = para语句刚执行完后,另外一个使用本函数的进程可能正好被激活,那么当新激活的进程执行到此函数时,将使 Exam 赋与另一个不同的 para 值,所以当控制重新回到 “temp = Square_Exam( )” 后,计算出的temp很可能不是预想中的结果。
此函数应如下改进:
int Exam = 0;
unsigned int example( int para )
{
unsigned int temp;
[申请信号量操作] //(1) 加锁
Exam = para;
temp = Square_Exam( );
[释放信号量操作] // 解锁
return temp;
}
申请不到“信号量”,说明另外的进程正处于给 Exam 赋值并计算其平方过程中(即正在使用此信号),本进程必须等待其释放信号后,才可继续执行。
若申请到信号,则可继续执行,但其它进程必须等待本进程释放信号量后,才能再使用本信号。
5. 可重入函数
可重入函数
10. int *fun(void)与int (*fun)(void)区别?
int *fun(void)fun是一个函数名,该函数的参数是void型,返回值是 int *
int (*fun)(void)fun是一个函数指针,该指针用于指向一个函数,函数的参数是void型,返回值是 int即类型如下:
int function(void)
{
return 0;
}
11. 32位系统上有如下C程序:
struct person
{
int a;
unsigned short int m;
char b;
char *q;
char c;
};
char str[]="yikoulinux";
char *p = str;
int n = 10;
则sizeof(str)、sizeof(p)、sizeof(n)、sizeof(int)、sizeof(struct person)的值分别是:
编写测试程序
1 #include <stdio.h>
2
3 int main(int argc, const char *argv[])
4 {
5 struct person
6 {
7 int a;
8 unsigned short int m;
9 char b;
10 char *q;
11 char c;
12 };
13 char str[]="yikoulinux";
14 char *p = str;
15 int n = 10;
16
17 struct person pe;
18
19 printf("sizeof(str):%d sizeof(p):%d sizeof(n):%d sizeof(int):%d sizeof(struct person):%d",si
20
21 printf("%p %p %p %p %p ",
22 &pe.a,&pe.m,&pe.b,&pe.q,&pe.c);
23 return 0;
24 }
编译执行:
sizeof(str):11 sizeof(p):4 sizeof(n):4 sizeof(int):4 sizeof(struct person):16
0xbf917d18
0xbf917d1c
0xbf917d1e
0xbf917d20
0xbf917d24
解释:
类型值解释sizeof(str)11这是计算数组str的大小,因为没有设置数组大小,以赋值字符串大小为准,而常量字符串在后一个位置会补一个空字符'',所以一共11个字节sizeof(p)4p是一个指针,32位机的指针都是32位,4个字节sizeof(n)4n是一个整型变量,所以是4个字节sizeof(int)4计算int 类型占用的内存大小,是4个字节sizeof(struct person)16默认情况下结构体成员会字节对齐,详细分布见下图