人人范文网 范文大全

嵌入式linux常见问题总结

发布时间:2020-03-03 17:17:01 来源:范文大全 收藏本文 下载本文 手机版

1.什么是嵌入式?

2.字符设备和块设备的区别?

3.进程与程序,进程与线程的区别

4.嵌入式的移植过程

5..守护进程的编写步骤

6.网络的Socket交互过程

7.TCP 三次握手和终止连接的4次握手过程

1)介绍一下你在华清做的这个项目?您在里面负责哪一块? 2)你用的是什么CPU?是什么样的内核? 3)说说嵌入式LINUX移植的过程? 4)字符设备和块设备有什么不同? 5)ARM有几种CPU模式,分别是什么? 6)列举几种文件系统,分别说说他们的优缺点。 7)说说摄像头的视频采集过程

8)如果要提升视频流的流畅度,可以怎么做? 9)按键处理用了CPU哪个中断?

10)BOA和APPACHE有什么区别,你为什么选择XX? 11)嵌入式LINUX 2.6和2.4有什么区别?

以下问答大部分是个人总结,仅供参考,你可以添加合适的自己的理解 1.什么是嵌入式?

A: 嵌入式系统本身是一个相对模糊的定义。目前嵌入式系统已经渗透到我们生活中的每个角落,工业、服务业、消费电子……,而恰恰由于这种范围的扩大,使得“嵌入式系统”更加难于明确定义。以下是几种常见表达方式:

1.执行专用功能并被内部计算机控制的设备或者系统。嵌入式系统不能使用通用型计算机,而且运行的是固化的软件,用术语表示就是固件(firmware),终端用户很难或者不可能改变固件。

2.凡是专用的、小型或者微型的计算机系统都是嵌入式系统,比如MP3, 手机,高清电视 3.比较传神和从技术人员角度来看,嵌入式系统是以应用为中心,以计算机技术为基础,并且软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。

2.字符设备和块设备的区别?

A: 1.字符设备和块设备、网络设备是一个并列的概念

2字符设备按照字符流的方式被有序访问,块设备以块为单位;二者根本区别在于字符设备只能顺序被读写,块设备可以随机访问

3. Linux为块设备和字符设备提供了两套机制。字符设备实现的比较简单,内核例程和用户态API一一对应,用户层的read函数直接对应了内核中的read例程,这种映射关系由字符设备的file_operations维护。块设备接口相对于字符设备复杂,read、write API没有直接到块设备层, 而是通过IO请求的方式通过OS的IO请求队列实现。内核管理块设备要比管理字符设备细致得多,内核对块设备的管理却提供一个专门的提供服务的子系统。块设备对执行性能的要求很高;,LINUX内核开发者门一直致力于优化块设备的驱动。 3.进程与程序的区别和联系

A:

1.程序是一组指令的集合,它是静态的实体,没有执行的含义。进程程序的执行过程,是一个动态的实体,有自己的生命周期,包括产生、运行、消亡的过程。除此之外,进程还有并发性和交往性。简单地说,进程是程序的一部分,程序运行的时候会产生进程。

2.所涉及到的介质不同,程序保存在存储介质,比如FLASH,硬盘等中,进程运行在RAM中

3.内容不完全相同,程序有数据段,代码段,调试信息等,进程执行时候,有代码段,数据段,以及堆栈

线程和进程的区别:

A:

1、线程是进程的一部分,所以线程有的时候被称为是轻权进程或者轻量级进程。

2、一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个进程,进程的执行过程不是一条线(线程)的,而是多条线(线程)共同完成的。

3、系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源。也就是 说,出了CPU之外(线程在运行的时候要占用CPU资源),计算机内部的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。

4、标准LINUX的进程具有独立的虚拟地址空间,而一个进程里面的多个线程共享同一个虚拟内存空间,进程是系统所有资源分配时候的一个基本单位

嵌入式LINUX 2.6和2.4有什么区别?

这个问题涉及的面非常广泛,我们只能列出基本部分:

每个内核主要的变化在http://lwn.net/Articles/2.6-kernel-api/,详细的参考http://blog.mcuol.com/User/bailang/Article/11222_1.htm, 下面列举的是比较基础和必须的部分

1.使用新的入口

必须包含 module_init(your_init_func); module_exit(your_exit_func); 老版本:int init_module(void); void cleanup_module(voi); 2.4中两种都可以用,对如后面的入口函数不必要显示包含任何头文件。

2、模块参数

必须显式包含 module_param(name, type, perm); module_param_named(name, value, type, perm); 参数定义

module_param_string(name, string, len, perm); module_param_array(name, type, num, perm); 老版本:MODULE_PARM(variable,type); MODULE_PARM_DESC(variable,type);

3、模块别名

MODULE_ALIAS("alias-name"); 这是新增的,在老版本中需在/etc/modules.conf配置,现在在代码中就可以实现。

4、模块计数

int try_module_get(&module); module_put(); 老版本:MOD_INC_USE_COUNT 和 MOD_DEC_USE_COUNT

5、符号导出

只有显示的导出符号才能被其他模块使用,默认不导出所有的符号,不必使用EXPORT_NO _SYMBOLS 老板本:默认导出所有的符号,除非使用EXPORT_NO_SYMBOLS

6、设备号

kdev_t被废除不可用,新的dev_t拓展到了32位,12位主设备号,20位次设备号。

unsigned int iminor(struct inode *inode); unsigned int imajor(struct inode *inode); 老版本:8位主设备号,8位次设备号 int MAJOR(kdev_t dev); int MINOR(kdev_t dev);

7、内存分配头文件变更

所有的内存分配函数包含在头文件,而原来的不存在

老版本:内存分配函数包含在头文件

8、结构体的初试化

gcc开始采用ANSI C的struct结构体的初始化形式: static struct some_structure = { .field1 = value, .field2 = value, ..}; 老版本:非标准的初试化形式

static struct some_structure = { field1: value, field2: value, ..};

9、request_module() request_module("foo-device-%d", number); 老版本:

char module_name[32]; printf(module_name, "foo-device-%d", number); request_module(module_name);

10、dev_t引发的字符设备的变化

1、取主次设备号为

unsigned iminor(struct inode *inode); unsigned imajor(struct inode *inode);

2、老的register_chrdev()用法没变,保持向后兼容,但不能访问设备号大于256的设备。

3、新的接口为

a)注册字符设备范围

int register_chrdev_region(dev_t from, unsigned count, char *name); b)动态申请主设备号

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, char *name); 看了这两个函数郁闷吧^_^!怎么和file_operations结构联系起来啊?别急! c)包含 ,利用struct cdev和file_operations连接 struct cdev *cdev_alloc(void); void cdev_init(struct cdev *cdev, struct file_operations *fops); int cdev_add(struct cdev *cdev, dev_t dev, unsigned count); (分别为,申请cdev结构,和fops连接,将设备加入到系统中!好复杂啊!) d)void cdev_del(struct cdev *cdev); 只有在cdev_add执行成功才可运行。 e)辅助函数

kobject_put(&cdev->kobj); struct kobject *cdev_get(struct cdev *cdev); void cdev_put(struct cdev *cdev); 这一部分变化和新增的/sys/dev有一定的关联。

11、新增对/proc的访问操作 以前的/proc中只能得到string, seq_file操作能得到如long等多种数据。 相关函数:

static struct seq_operations 必须实现这个类似file_operations得数据中得各个成 员函数。

seq_printf();

int seq_putc(struct seq_file *m, char c); int seq_puts(struct seq_file *m, const char *s); int seq_escape(struct seq_file *m, const char *s, const char *esc); int seq_path(struct seq_file *m, struct vfsmount *mnt, struct dentry *dentry, char *esc); seq_open(file, &ct_seq_ops); 等等

12、底层内存分配

1、头文件改为

2、分配标志GFP_BUFFER被取消,取而代之的是GFP_NOIO 和 GFP_NOFS

3、新增__GFP_REPEAT,__GFP_NOFAIL,__GFP_NORETRY分配标志

4、页面分配函数alloc_pages(),get_free_page()被包含在中

5、对NUMA系统新增了几个函数:

a) struct page *alloc_pages_node(int node_id, unsigned int gfp_mask, unsigned int order); b) void free_hot_page(struct page *page); c) void free_cold_page(struct page *page);

13、内核时间变化

1、现在的各个平台的HZ为

Alpha: 1024/1200; ARM: 100/128/200/1000; CRIS: 100; i386: 1000; IA-64: 1024; M68K: 100; M68K-nommu: 50-1000; MIPS: 100/128/1000; MIPS64: 100; PA-RISC: 100/1000; PowerPC32: 100; PowerPC64: 1000; S/390: 100; SPARC32: 100; SPARC64: 100; SuperH: 100/1000; UML: 100; v850: 24-100; x86-64: 1000.

2、由于HZ的变化,原来的jiffies计数器很快就溢出了,引入了新的计数器jiffies_64

3、#include u64 my_time = get_jiffies_64();

4、新的时间结构增加了纳秒成员变量

struct timespec current_kernel_time(void);

5、他的timer函数没变,新增

void add_timer_on(struct timer_list *timer, int cpu);

6、新增纳秒级延时函数 ndelay();

7、POSIX clocks 参考kernel/posix-timers.c

14、工作队列(workqueue)

1、任务队列(task queue )接口函数都被取消,新增了workqueue接口函数 struct workqueue_struct *create_workqueue(const char *name); DECLARE_WORK(name, void (*function)(void *), void *data); INIT_WORK(struct work_struct *work, void (*function)(void *), void *data); PREPARE_WORK(struct work_struct *work, void (*function)(void *), void *data);

2、申明struct work_struct结构

int queue_work(struct workqueue_struct *queue, struct work_struct *work); int queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, unsigned long delay); int cancel_delayed_work(struct work_struct *work); void flush_workqueue(struct workqueue_struct *queue); void destroy_workqueue(struct workqueue_struct *queue); int schedule_work(struct work_struct *work); int schedule_delayed_work(struct work_struct *work, unsigned long delay);

15、DMA的变化 未变化的有:

void *pci_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_handle); void pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle); 变化的有:

1、void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag); void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle);

2、列举了映射方向:

enum dma_data_direction { DMA_BIDIRECTIONAL = 0, DMA_TO_DEVICE = 1, DMA_FROM_DEVICE = 2, DMA_NONE = 3, };

16、新增完成事件(completion events) init_completion(&my_comp); void wait_for_completion(struct completion *comp); void complete(struct completion *comp); void complete_all(struct completion *comp);

25、RCU(Read-copy-update) rcu_read_lock();

中断处理

1、中断处理有返回值了。 IRQ_RETVAL(handled);

2、cli(), sti(), save_flags(), 和 restore_flags()不再有效,应该使用local_save _flags() 或local_irq_disable()。

3、synchronize_irq()函数有改动

4、新增int can_request_irq(unsigned int irq, unsigned long flags);

5、request_irq() 和free_irq() 从 改到了

18、异步I/O(AIO) ize_t (*aio_read) (struct kiocb *iocb, char __user *buffer, size_t count, loff_t pos); ize_t (*aio_write) (struct kiocb *iocb, const char __user *buffer, size_t count, loff_t pos); int (*aio_fsync) (struct kiocb *, int datasync); 新增到了file_operation结构中。

is_sync_kiocb(struct kiocb *iocb);

int aio_complete(struct kiocb *iocb, long res, long res2);

19、block I/O 层

这一部分做的改动最大。不祥叙。

20.内核的一些功能函数的名称、参数、头文件、宏定义的变化

如:中断注册函数的格式及参数在2.4内核、2.6内核低版本和高版本之间都存在差别

在2.6.8中,中断注册函数的定义为:

int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),unsigned long irq_flags, const char * devname, void *dev_id) irq_flags的取值主要为下面的某一种或组合: SA_INTERRUPT、SA_SAMPLE_RANDOM、SA_SHIRQ 在2.6.26中,中断注册函数的定义为: int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id) typedef irqreturn_t (*irq_handler_t)(int, void *); irq_flags的取值主要为下面的某一种或组合:(功能和2.6.8的对应) IRQF_DISABLED、IRQF_SAMPLE_RANDOM、IRQF_SHARED平台代码关于硬件操作方面封装的一些函数的变化

内 核中,硬件平台相关的代码在内核更新过程中变化比较频繁。和我们的设备驱动也是息息相关。所以在针对一个新内核编写设备驱动前,一定要熟悉你的平台代码的 结构。有时平台虽然提供了内核要求的接口函数,但使用起来功能却并不完善。下面还是先举个例子说明平台代码更新对设备驱动的影响。 如: 在linux-2.6.8内核中,调用set_irq_type(IRQ_EINT0, IRQT_FALLING);去设置S3C2410的IRQ_EINT0的中断触发信号类型,你会发现不会有什么效果。跟踪代码发现内核的 set_irq_type函数需要平台提供一个针对硬件平台的实现函数

static struct irqchip s3c_irqext_chip = { .mask = s3c_irqext_mask, .unmask = s3c_irqext_unmask, .ack = s3c_irqext_ack, .type = s3c_irqext_type }; s3c_irqext_type就是linux内核需要的实现函数,而s3c_irqext_type在2.6.8中的实现为:

static int s3c_irqext_type(unsigned int irq, unsigned int type) { irqdbf("s3c_irqext_type: called for irq %d, type %d\n", irq, type); return 0; } 原来并没有实现。而在较高版本的内核,如2.6.26内核中,这个函数是实现了的。

嵌入式linu学习心得

嵌入式总结

嵌入式存储卡总结

嵌入式 知识点总结

嵌入式学习总结

嵌入式论文总结

嵌入式试题总结

嵌入式复习总结

嵌入式考试总结

嵌入式Linux总结

嵌入式linux常见问题总结
《嵌入式linux常见问题总结.doc》
将本文的Word文档下载到电脑,方便编辑。
推荐度:
点击下载文档
点击下载本文文档