當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]關(guān)于系統(tǒng)調(diào)用,相信學(xué)習(xí)過(guò)操作系統(tǒng)的同學(xué)應(yīng)該都不陌生。 那么,什么是系統(tǒng)調(diào)用? 百度的權(quán)威解釋如下: 點(diǎn)擊打開(kāi)鏈接 由操作系統(tǒng)實(shí)現(xiàn)提供的所有系統(tǒng)調(diào)用所構(gòu)成的集合即程序接口或應(yīng)用編程接口(Application Programming Interface,API)。是應(yīng)用程序同系統(tǒng)之間

關(guān)于系統(tǒng)調(diào)用,相信學(xué)習(xí)過(guò)操作系統(tǒng)的同學(xué)應(yīng)該都不陌生。

那么,什么是系統(tǒng)調(diào)用?

百度的權(quán)威解釋如下:

點(diǎn)擊打開(kāi)鏈接

操作系統(tǒng)實(shí)現(xiàn)提供的所有系統(tǒng)調(diào)用所構(gòu)成的集合即程序接口或應(yīng)用編程接口(Application Programming Interface,API)。是應(yīng)用程序同系統(tǒng)之間的接口。

         那么我們編程實(shí)驗(yàn)過(guò)程中使用過(guò)哪些系統(tǒng)調(diào)用呢?

         當(dāng)我們要打開(kāi)一個(gè)文件,對(duì)這個(gè)文件進(jìn)行讀寫(xiě)等操作,我們就需要使用open , read , write , lseek等基本的操作函數(shù)API,操作系統(tǒng)中就會(huì)根據(jù)我們的fd(文件句柄)找到對(duì)應(yīng)的open , read , write , lseek函數(shù),在底層進(jìn)行調(diào)用。

         舉一個(gè)簡(jiǎn)單的例子:

基于tiny4412實(shí)現(xiàn)的LED驅(qū)動(dòng)和應(yīng)用控制

http://blog.csdn.NET/morixinguan/article/details/50619675

         我們?cè)谶@個(gè)例子中就實(shí)現(xiàn)了系統(tǒng)調(diào)用:

fd = open("/dev/test-dev",O_RDWR) ;  

    if(-1 == fd)  

    {  

        printf("open fair!\n");  

        return -1 ;  

    }  

    while(1){  

        val = 0 ;  

        //寫(xiě)write方法就會(huì)調(diào)用到驅(qū)動(dòng)程序的led_write  

        //最后我們能看到的結(jié)果是led燈做流水燈的實(shí)現(xiàn),然后全滅,再周而復(fù)始  

        write(fd , &val , 4);  

        sleep(1);  

        val = 1 ;  

        write(fd , &val , 4);  

        sleep(1);  

        val = 2 ;  

        write(fd , &val , 4);  

        sleep(1);  

        val = 3 ;  

        write(fd , &val , 4);  

        sleep(1);  

        val = 5 ;  

        write(fd , &val , 4);  

        sleep(1);  

    }  

在這里,我們通過(guò)open函數(shù),打開(kāi)相應(yīng)的設(shè)備,這里的設(shè)備就是/dev/test-dev,然后對(duì)設(shè)備進(jìn)行寫(xiě)操作,操作系統(tǒng)就會(huì)通過(guò)設(shè)備節(jié)點(diǎn)識(shí)別我們到底調(diào)用了哪個(gè)驅(qū)動(dòng)函數(shù),進(jìn)而實(shí)現(xiàn)一些簡(jiǎn)單的操作。


       通過(guò)上層的open函數(shù),內(nèi)核的初始化函數(shù)已經(jīng)對(duì)這個(gè)設(shè)備進(jìn)行了注冊(cè)操作,于是通過(guò)主設(shè)備號(hào)和次設(shè)備號(hào)進(jìn)而調(diào)用了相應(yīng)的驅(qū)動(dòng)函數(shù)led_open,接著write函數(shù)調(diào)用到底層的led_write函數(shù),具體API如下:

//啟動(dòng)函數(shù)  

static __init int test_init(void)  

{  

    printk("led_init\n");  

    major = register_chrdev(major, DEV_NAME, &fops);  

    led_config = (volatile unsigned long *)ioremap(GPM4COM , 16);  

    led_dat = led_config + 1 ;    

    return 0;  

}  

//open方法,對(duì)LED燈進(jìn)行初始化  

int led_open(struct inode *inode, struct file *filp)  

{  

    printk("led_open\n");//上層程序?qū)ED進(jìn)行Open操作的時(shí)候會(huì)執(zhí)行這個(gè)函數(shù)  

    //先對(duì)LED的端口進(jìn)行清0操作  

    *led_config &= ~(0xffff);  

    //將4個(gè)IO口16位都設(shè)置為Output輸出狀態(tài)  

    *led_config |= (0x1111);  

    return 0;  

}  

//write方法  

int led_write(struct file *filp , const char __user *buf , size_t count , loff_t *f_pos)  

{  

    int val ;   

    //注意,這里是在內(nèi)核中進(jìn)行操作,我們需要使用copy_from_user這個(gè)函數(shù)將用戶(hù)態(tài)的內(nèi)容拷貝到內(nèi)核態(tài)  

    copy_from_user(&val , buf , count);   

    //以下就是當(dāng)val是哪個(gè)值的時(shí)候,led就執(zhí)行相應(yīng)的操作,這里不多說(shuō)  

    switch(val)  

    {  

        case 0 :   

                //對(duì)狀態(tài)寄存器進(jìn)行賦值,以下雷同  

                printk(KERN_EMERG"led1_on\n");  

                *led_dat &= ~0x1 ;  

                break ;  

        case 1 :  

                printk(KERN_EMERG"led2_on\n");  

                *led_dat &= ~0x2 ;  

                break ;  

        case 2 :  

                printk(KERN_EMERG"led3_on\n");  

                *led_dat &= ~0x4 ;  

                break ;  

        case 3 :  

                printk(KERN_EMERG"led4_on\n");  

                *led_dat &= ~0x8 ;   

                break ;  

        case 4 :  

                printk(KERN_EMERG"ledall_on\n");  

                *led_dat &= ~0xf ;  

                break ;  

        case 5 :   

                printk(KERN_EMERG"ledall_off\n");  

                *led_dat |= 0xf ;  

                break ;  

  

    }  

}  

上述調(diào)用過(guò)程在前面的字符設(shè)備驅(qū)動(dòng)其實(shí)已經(jīng)說(shuō)得很詳細(xì)就不再闡述。那么,如果我們現(xiàn)在不調(diào)用open,write,read等系統(tǒng)本身有的函數(shù),我們自己來(lái)實(shí)現(xiàn)一個(gè),如何實(shí)現(xiàn)?


     以下我們以實(shí)現(xiàn)sys_add()系統(tǒng)調(diào)用來(lái)進(jìn)行過(guò)程描述,這個(gè)API很簡(jiǎn)單,就是通過(guò)上層調(diào)用syscall()函數(shù),傳入兩個(gè)參數(shù),使兩數(shù)相加,具體實(shí)現(xiàn)如下:

    1、在內(nèi)核源代碼根目錄找到這個(gè)文件   arch/arm/kernel/calls.S  ,打開(kāi)看看:

/* 0 */ CALL(sys_restart_syscall)

CALL(sys_exit)

CALL(sys_fork_wrapper)

CALL(sys_read)

CALL(sys_write)

/* 5 */ CALL(sys_open)

CALL(sys_close)

....

在這個(gè)文件里,聲明我們系統(tǒng)需要調(diào)用的API,我們把相應(yīng)的添加到最后面:


    我們把我們需要的添加到最后:
    /*376*/ CALL(sys_add)     這里376表示系統(tǒng)調(diào)用號(hào),第376號(hào)

   2、在內(nèi)核源代碼根目錄找到這個(gè)文件   arch/arm/include/asm/unistd.h,打開(kāi)看看:

/*

 * This file contains the system call numbers.

 */


#define __NR_restart_syscall (__NR_SYSCALL_BASE+  0)

#define __NR_exit (__NR_SYSCALL_BASE+  1)

#define __NR_fork (__NR_SYSCALL_BASE+  2)

#define __NR_read (__NR_SYSCALL_BASE+  3)

#define __NR_write (__NR_SYSCALL_BASE+  4)

#define __NR_open (__NR_SYSCALL_BASE+  5)

#define __NR_close (__NR_SYSCALL_BASE+  6)

....

在__NR這個(gè)標(biāo)號(hào)375號(hào)后面添加:


#define __NR_add (__NR_SYSCALL_BASE+376)

  3、在內(nèi)核源代碼根目錄找到這個(gè)文件   arch/arm/kernel/sys_arm.c , 打開(kāi)看看


在文件的最后添加:

asmlinkage long sys_add(int a, int b)

{

return a+b;

}

這樣,我們就完成了對(duì)底層系統(tǒng)調(diào)用的實(shí)現(xiàn),接下來(lái),我們來(lái)驗(yàn)證我們寫(xiě)的這個(gè)程序的結(jié)果,看看對(duì)不對(duì)。

具體如下:

為了方便驗(yàn)證,這里就不再寫(xiě)應(yīng)用程序,有興趣可以自己去驗(yàn)證,也很簡(jiǎn)單。我們這里采用的還是以驅(qū)動(dòng)的形式進(jìn)行加載。

步驟如下:

1、先在driver目錄下創(chuàng)建一個(gè)目錄:yyx_syscall

依次創(chuàng)建syscall_add.c  Makefile

往syscall_add.c添加代碼:

#include<linux/kernel.h>

#include<linux/module.h>

#include<linux/sched.h>

#include<asm/uaccess.h>

#include<linux/compiler.h>

#include<linux/linkage.h>

#include<linux/types.h>

#include<linux/unistd.h>


//在linux內(nèi)核根目錄下找到System.map中sys_add的地址

#define SYS_CALL_ADD_TB 0xc004e30c  

//這里通過(guò)一個(gè)指針去獲取系統(tǒng)函數(shù)的入口地址

unsigned long *sys_call_table_add = (unsigned long*)SYS_CALL_ADD_TB; 

asmlinkage long sys_add(int a , int b) ; //在這里定義一個(gè)函數(shù)


int __init init_addsyscall(void)

{

int ret ;

sys_call_table_add[376] = sys_add(1,2); //上面定義的這個(gè)函數(shù)作為參數(shù)傳遞給這個(gè)指針

ret = sys_call_table_add[376] ;//獲取到了參數(shù)

        printk("System call add loaded ret:%d\n",ret); //執(zhí)行結(jié)果

        return 0;

}


void __exit exit_addsyscall(void)

{

        printk("System call unlodaded\n");

}


module_init(init_addsyscall);

module_exit(exit_addsyscall);

MODULE_LICENSE("GPL");

Makefile內(nèi)容如下:


obj-y += syscall_add.o


然后回到內(nèi)核的根目錄下:

make -j4

將編譯生成的zImage下載到板子上,運(yùn)行,我們可以看到串口中打印了相應(yīng)的數(shù)據(jù),是數(shù)字3,也就是1+2的結(jié)果,驗(yàn)證成功。



免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉