2019-08-17 20:51:27 yangang185 阅读数 57
  • linux线程全解-linux应用编程和网络编程第7部分

    本课程讲解linux中线程,首先使用多进程解决上个课程中提出的并发式读取按键和鼠标的任务,然后引出多线程并讲解多线程的优势,后详细讲了多线程的同步技术。学习本课程的目的是学会在linux应用编程中使用多线程技术。

    5141 人正在学习 去看看 朱有鹏

简介

讲解RTOS和linux内核对于临界区处理

资源

linux_irq.md
标题:闫刚 linux应用程序为什么不要关闭中断

RTOS处理临界区

RTOS中,中断和线程的打断,需要做原子操作,那么就是普通的关闭中断处理,因为在RTOS中,我们经常和中断打交道。

linux处理临界区

linux中用户态的进程是调用内核态的资源, 中断和内核态会出现打断的线程,所有在内核态的部分要处理关闭中断的处理

在linux1.0中在_sleep_on中调用save_flags(flags)和save_flags();

static inline void __sleep_on(struct wait_queue **p, int state)
{
	unsigned long flags;
	struct wait_queue wait = { current, NULL };

	if (!p)
		return;
	if (current == task[0])
		panic("task[0] trying to sleep");
	current->state = state;
	add_wait_queue(p, &wait);
	save_flags(flags);
	sti();
	schedule();
	remove_wait_queue(p, &wait);
	restore_flags(flags);
}
2020-01-04 23:49:06 weixin_42429718 阅读数 534
  • linux线程全解-linux应用编程和网络编程第7部分

    本课程讲解linux中线程,首先使用多进程解决上个课程中提出的并发式读取按键和鼠标的任务,然后引出多线程并讲解多线程的优势,后详细讲了多线程的同步技术。学习本课程的目的是学会在linux应用编程中使用多线程技术。

    5141 人正在学习 去看看 朱有鹏

2020 Linux系统应用基础教程 期末复习【整理】 第一章 认识linux

点击跳转第一章

2020 Linux系统应用基础教程 期末复习【整理】 第二章 系统的启动与关闭

点击跳转第二章

2020 Linux系统应用基础教程 期末复习【整理】 第三章 用户登录和账号管理

点击跳转第三章

2020 Linux系统应用基础教程 期末复习【整理】 第四章 文件系统管理

点击跳转第四章

在这里插入图片描述

2020 Linux系统应用基础教程 期末复习【整理】 第五章 磁盘文件与目录管理

点击跳转第五章

2020 Linux系统应用基础教程 期末复习【整理】第六章 Linux的包管理

点击跳转第六章

2020 Linux系统应用基础教程 期末复习【整理】第七章 进程管理

点击跳转第七章

2020 Linux系统应用基础教程 期末复习【整理】第八章 shell编程

点击跳转第八章

学如逆水行舟,不进则退
2010-12-02 22:56:00 yangcuncunzhang 阅读数 1383
  • linux线程全解-linux应用编程和网络编程第7部分

    本课程讲解linux中线程,首先使用多进程解决上个课程中提出的并发式读取按键和鼠标的任务,然后引出多线程并讲解多线程的优势,后详细讲了多线程的同步技术。学习本课程的目的是学会在linux应用编程中使用多线程技术。

    5141 人正在学习 去看看 朱有鹏

最近在做Android,其中一个任务是写一个能在Linux命令行运行的测试AP,运行这个AP就能关闭设备电源,即Power Off。

 

在Linux内核中已经找到了关闭电源的函数kernel_power_off(),然后也知道了在sys_reboot()函数中调用kernel_power_off()的,但是linux的应用程序怎么调用sys_reboot()呢? 经过1天的研究,终于搞明白了

 

这样的函数属于linux的系统调用函数(System call),需要用system call的方式调用,一共有下面3中途径:

 

一、使用标准C库函数

 

    例如我们使用open(), read(), write()等标准C函数时,实际上是经过C库包装了的sys_open(),sys_read(),sys_write()等函数,这个包装过程不用我们操心。这应该是属于隐性调用system call。

 

二、在Linux 2.6.18以前版本

 

    include/asm-arm/unistd.h文件中定义了7个_syscall宏,分别是:

 

_syscall0(type, name)  

_syscall1(type, name,type1,arg1)  

_syscall2(type, name,type1,arg1,type2,arg2)  

_syscall3(type, name,type1,arg1,type2,arg2,type3,arg3)  

_syscall4(type, name,type1,arg1,type2,arg2,type3, arg3,type4,arg4)  

_syscall5(type, name,type1,arg1,type2,arg2,type3, arg3,type4,arg4,type5,arg5)  

_syscall6(type, name,type1,arg1,type2,arg2,type3, arg3,type4,arg4,type5,arg5,type6,arg6)

 

       这7个宏是用来产生系统调用的函数名的,其中type表示系统调用的返回值类型,name表示该系统调用的名称,typeN、argN分别表示第N个参数的类型和名称,它们的数目和_syscall后面的数字一样大。

 

       另外,include/linux/syscalls.h文件中定义有所用系统调用函数的原型,例如:

 

asmlinkage int sysinfo(struct sysinfo * info);

 

       在需要系统调用的时候,先找到要调用的函数的声明,看有多少个参数,然后用上面7个宏中的对应的一个,产生函数名,还是以sysinfo为例:

 

_syscall1(int, sysinfo, struct sysinfo *, info);

 

      然后在调用的地方直接用sysinfo()函数就可以了:

 

struct sysinfo s_info;  

int error;  

 

error = sysinfo(&s_info);  

 

 

三、在Linux 2.6.19之后的版本

 

      上面的7个宏明显有问题:不近麻烦,而且最多只有6个参数,在2.6.19以后的linux中,废除了_syscallx这7和宏,而使用syscall()函数,这个函数定义在syscall.h中:

 

int syscall(int number, ...); 

 

      有一个新的概念:系统调用号,就是所用系统调用对应的编号,它们定义在include/asm-arm/unistd.h中。

 

      当需要系统调用时,直接用这个函数,参数number就是需要的函数的系统调用号,例如上面的例子就变成:

 

struct sysinfo s_info;  

syscall(__NR_sysinfo, &s_info);

 

上面的方法中描述的目录可能每个平台上都不太一样,但大概都差不多,文件名应该是一样的。

没有更多推荐了,返回首页