筆試題目
一、選擇題
二、 1:main() { int x=1,y=1; y=x-- printf( “ %d,%d\n ” ,x,y); }運行結果爲( B) A.0 , 0 B.0 , 1 C.1 , 0 D.1 , 1
2:某文件中定義的靜態全局變量(或稱靜態外部變量)其作用域是( B )
A.只限某個函數 B.本文件 C.跨文件 D.不限制作用域
3:設 int a[10],*p=a 則對數組元素的正確引用是(C )
A.a[p] B.p[a] C.*(p+2) D.p+2
4:C語言中,系統自動打開的文件是( A) A.二進制文件 B.隨機文件 C.非緩衝文件 D.設備文件
5:下列程序的運行結果是( D )
main( ) { int a[][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int (*p)[4],i=2,j=1; p=a; printf(″%d\n″,*(*(p+i)+j)); } A.9 B.11 C.17 D.19
6:在軟件生命週期中,下列哪個說法是不準確的?( C )
A.軟件生命週期分爲計劃、開發和運行三個階段 B.在計劃階段要進行問題確認和需求分析 C.在開發後期才能進行編寫代碼和軟件測試 D.在運行階段主要是進行軟件維護
7:下列語句定義整型指針p1、p2,( B ) 是正確的。 A.int p1,p2; B.int *p1,*p2; C.int *p1,p2; D.int **p1,p2;
B. 8:下列程序的運行結果是( B) main() { int a[5] = {1,2,3,4,5}; int *ptr = (int*)(&a+1); printf("%d %d" , *(a+1), *(ptr-1) ); } A. 2 2 B. 2 1 C.2 5 D.以上均不是
C.二、簡答題
D.8、下面的程序或程序段存在一個錯誤或不妥處請在其下劃一條線,並將改正的內容寫到每小題後的空白處
main() {
char c1,c2;
c1='9';
c2='10';
printf(”cl=%c,c2=%c\n”,c1,c2);
}
答:char cl,c2;
printf(”c1=%c,c2=%c\n”,c1,c2);
改: char c1,*c2;
c2="10";
printf(”cl=%c,c2=%s\n”,c1,c2);
9、下面的代碼輸出是什麼,爲什麼? void foo(void) { unsigned int a = 6; int b = -20; (a+b > 6) ? puts("> 6") : puts("<= 6"); }
輸出:>6 因爲:當unsigned int類型和int類型相加int的類型會被轉變成unsigned int,那麼b=10...10100 ,所以:a+b>6
10、中斷是嵌入式系統中重要的組成部分,這導致了很多編譯開發商提供一種擴展 ―讓標準 C支持中斷。具代表事實是,產生了一個新的關鍵字__interrupt,下面的代碼就使用了 __interrupt關鍵字去定義了一箇中斷服務子程序 (ISR),請評論一下這段代碼,找出錯誤並改正.
__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf("\nArea = %f", area);
return area;
}
答:__interrupt double compute_area (double radius)
應把double去掉和把double radius改成void 因爲中斷處理函數不能傳參和返回值所以自然return 也要去掉。
三、內核驅動題
11、請簡述arm linux內核啓動流程。
答:首先IROM先把一段一段裸機程序複製到SRAM中啓動進行初步初始化arm在通過裏面的複製剩餘代碼至DRAM進行下一部分的初始化和引導啓動linux內核從中如果板子的ID和linux中相應的ID不能匹配的話linux將無法啓動。
12、驅動裏面爲什麼要有併發、互斥的控制?如何實現?舉例說明。
併發:可分兩種一種宏觀上併發微觀上串行,一般出現在單核CPU中,這種採用某種算法使得個進程輪流佔用CPU,當時間片用完即退下讓下一個進程佔用CPU。別一種是宏觀上和微觀上都是併發的這種一般在多核CPU中,是真正上併發,併發本質就是提高CPU的效率,使得CPU不會因爲一個進程阻塞而不工作,也不會因爲一個進程運行時間長而使得其他進程等待太久。
互斥:互斥是爲了某個變量,某個函數因爲多人一起操作而使結果不朝着我們想要的方向走。
如系統文件中有個txt文件多人讀可以,但是如果多人一起寫這個txt的話那麼這個txt就很難看懂了,如果這裏這裏設置一個互斥量使一次只有一個人可寫那麼txt就不會混亂了。
13、請簡述linux內核終端處理分成上半部分和下半部分的原因,爲何要分?如何實現?
linux內核終端處理分上下部分的原因:首先分上下部是的真正要屏蔽中斷時間不會太長而使linux重啓。而且把不緊急的代碼放下下部分,可以使CPU更多時間去相應其他終端,也可以提高CPU的效率。
四、編程實現題
14、設計並實現一個在linux平臺下簡單的內存FIFO字符設備驅動,並簡述該驅動的驗證方法。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
MODULE_LICENSE("GPL");
#define FIFO_MAJOR 0
#define FIFO_MINOR 0
#define DEV_NUM 1
#define FIRSTPRI_NUM 0
#define DATA_NUM 100
#define DRI_NAME "fifo_dev"
unsigned int fifo_major = FIFO_MAJOR,fifo_minor = FIFO_MINOR;
dev_t fdev_t;
module_param(fifo_major,int,S_IRUSR);
module_param(fifo_minor,int,S_IRUSR);
struct fifo_dev
{
struct cdev tcdev;
int data[DATA_NUM];
int pri,tail;
};
static struct class *my_class;
static struct fifo_dev *fifo_devs;
static struct device *my_devices;
static int fifo_open(struct inode * node,struct file * filep)
{
int i=0;
struct fifo_dev *fifodev = NULL;
printk(KERN_INFO"Fifo_dev:Hello come to fifo_open");
fifodev = container_of(node->i_cdev,struct fifo_dev,tcdev);
filep->private_data = fifodev;
return 0;
}
static ssize_t fifo_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)
{
int i=0,j=0;
int tbuff[DATA_NUM];
struct fifo_dev *fifodev = NULL;
printk(KERN_INFO"Fifo_dev:Hello come to fifo_open");
fifodev = file->private_data;
if(fifodev->pri == fifodev->tail)
{
printk(KERN_NOTICE"Fifo_dev:No data to read");
count = 0;
return count;
}
i=fifodev->pri - fifodev->tail;
if(i<count)
count = i;
for(;j<=count;j++)
tbuff[j]=fifodev->data[fifodev->tail+j];
copy_to_user(buf,tbuff,count);
fifodev->tail+=count;
return count;
}
static ssize_t fifo_write(struct file * file,const char * buf,size_t n,loff_t * ppos)
{
int i=0,j=0,k=0,q=0;
int tbuff[DATA_NUM];
struct fifo_dev *fifodev = NULL;
printk(KERN_INFO"Fifo_dev:Hello come to fifo_write");
fifodev = file->private_data;
j=DATA_NUM-n;
if((fifodev->pri) >= j)
{
if((fifodev->tail) >= n)
{
k=fifodev->tail-n;
if(((fifodev->pri )- (fifodev->tail)) > k)
q=k;
else
q= fifodev->pri - fifodev->tail;
for(;i<q;i++)
{
fifodev->data[k+i]=fifodev->data[fifodev->tail+i];
}
}
else{
q=n;
k=0;
for(;i<q;i++)
{
fifodev->data[k+i]=fifodev->data[fifodev->tail+i];
}
}
fifodev->tail=k;
fifodev->pri = q + fifodev->tail;
}
copy_from_user(tbuff,buf,n);
for(;j<=n;j++)
fifodev->data[fifodev->pri+j]=tbuff[j];
fifodev->pri +=n;
return n;
}
static struct file_operations fifo_cdev=
{
.owner = THIS_MODULE,
.read = fifo_read,
.open = fifo_open,
.write = fifo_write,
};
static int fifo_probe (struct platform_device *dev)
{
int ret;
if(fifo_major = 0)
{
ret = alloc_chrdev_region(fdev_t,FIFO_MINOR,DEV_NUM,DRI_NAME);
}
else
{
ret = register_chrdev_region(fdev_t,DEV_NUM,DRI_NAME);
}
if(IS_ERR(ret))
{
printk(KERN_ERR"Fifo_dev:Failed for chrdev_region");
return -ENOANO;
}
printk(KERN_INFO"Fifo_dev:Success for chrdev_region");
fifo_devs = kmalloc(sizeof(struct fifo_dev)*DEV_NUM,GFP_KERNEL);
if(fifo_devs ==NULL)
{
printk(KERN_ERR"Fifo_dev:Failed for kmalloc");
goto failed_kmalloc;
}
printk(KERN_ERR"Fifo_dev:Succwss for kmalloc");
memset(fifo_devs,sizeof(struct fifo_dev)*DEV_NUM,0);
my_class = class_create(THIS_MODULE,DRI_NAME);
if(my_class ==NULL)
{
printk(KERN_ERR"Fifo_dev:Failed for my_class");
goto failed_my_class;
}
printk(KERN_ERR"Fifo_dev:Succwss for my_class");
my_devices=device_create(my_class,NULL,fdev_t,NULL,DRI_NAME);
if(my_devices ==NULL)
{
printk(KERN_ERR"Fifo_dev:Failed for my_devices");
goto failed_my_devices;
}
printk(KERN_ERR"Fifo_dev:Succwss for my_devices");
cdev_init(&(fifo_devs->tcdev),&fifo_cdev);
ret=cdev_add(&(fifo_devs->tcdev),fdev_t,1);
if(ret<0)
{
printk(KERN_ERR"Fifo_dev:Succwss for cdev_add");
goto failed_cdev_add;
}
printk(KERN_ERR"Fifo_dev:Succwss for cdev_add");
fifo_devs->pri = FIRSTPRI_NUM;
fifo_devs->tail= FIRSTPRI_NUM;
return 0;
failed_cdev_add:
device_del(my_devices);
failed_my_devices:
class_destroy(my_class);
failed_my_class:
kfree(fifo_devs);
failed_kmalloc:
unregister_chrdev_region(fdev_t,DEV_NUM);
return -ENOANO;
}
static int fifo_resume(struct platform_device *dev)
{
cdev_del(&(fifo_devs->tcdev));
device_del(my_devices);
class_destroy(my_class);
kfree(fifo_devs);
unregister_chrdev_region(fdev_t,DEV_NUM);
return 0;
}
struct platform_driver fifo_plat_dri ={
.probe = fifo_probe,
.resume = fifo_resume,
.driver = {
.name = DRI_NAME,
.owner = THIS_MODULE,
},
};
static int __init fifo_inits(void)
{
int ret;
ret = platform_driver_register(&fifo_plat_dri);
return 0;
}
static void __exit fifo_exits(void)
{
platform_driver_unregister(&fifo_plat_dri);
}
module_init(fifo_inits);
module_exit(fifo_exits);
測試:read.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main(int argc , char **argv){
int fd,count,i;
int buf[100];
char *lednode = "/dev/fifo_dev";
/*O_RDWR只讀打開,O_NDELAY非阻塞方式*/
if((fd = open(lednode,O_RDWR|O_NDELAY))<0){
printf("APP open %s failed!\n",lednode);
}
else{
printf("APP open %s success!\n",lednode);
count = argv[1];
read(fd, buf, count);
printf("read num :\n");
for(i=0;i<count;i++)
{
printf("%d ",buf[i]);
}
printf("\n");
}
close(fd);
}
write.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main(int argc , char **argv){
int fd,count,i;
int buf[100];
char *lednode = "/dev/fifo_dev";
/*O_RDWR只讀打開,O_NDELAY非阻塞方式*/
if((fd = open(lednode,O_RDWR|O_NDELAY))<0){
printf("APP open %s failed!\n",lednode);
}
else{
printf("APP open %s success!\n",lednode);
count = argc;
for(i=1;i<=count;i++)
{
buf[i-1]=argv[i];
}
write(fd, buf,count);
}
close(fd);
}