新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機和嵌入式系統linux的區別

        單片機和嵌入式系統linux的區別

        作者: 時間:2016-11-26 來源:網絡 收藏

        2.1.2 是否通用

        有些單片機廠家也給客戶提供了大量的驅動程序,比如USB HOST驅動程序,這可以讓客戶很容易就可以在它的上面編寫程序讀寫U盤。但是客戶寫的這些程序,只能在這種芯片、這個驅動程序上使用;更換另一種芯片后,即使芯片公司也提供了驅動程序,但是接口絕對不一樣,客戶又得重新編寫應用程序。
        基于操作系統的驅動程序要遵循統一的接口,比如對于不同的芯片的USB HOST驅動,它們都要向上提供一個相同的數據結構,在里面實現了各自的USB操作。

        下面是S3C2410/S3C2440的USB驅動向上層提供的數據結構:

        static const struct hc_driver ohci_s3c2410_hc_driver = {
        .deion = hcd_name,
        .product_desc = "S3C24XX OHCI",
        .hcd_priv_size = sizeof(struct ohci_hcd),


        .irq = ohci_irq,
        .flags = HCD_USB11 | HCD_MEMORY,


        .start = ohci_s3c2410_start,
        .stop = ohci_stop,
        .shutdown = ohci_shutdown,


        .urb_enqueue = ohci_urb_enqueue,
        .urb_dequeue = ohci_urb_dequeue,
        .endpoint_disable = ohci_endpoint_disable,


        .get__number = ohci_get_,


        .hub_status_data = ohci_s3c2410_hub_status_data,
        .hub_control = ohci_s3c2410_hub_control,
        .hub_irq_enable = ohci_rhsc_enable,
        #ifdef CONFIG_PM
        .bus_suspend = ohci_bus_suspend,
        .bus_resume = ohci_bus_resume,
        #endif
        .start_port_reset = ohci_start_port_reset,
        };

        下面是ATMEL公司的ARM芯片的USB驅動向上層提供的數據結構:

        static const struct hc_driver ohci_at91_hc_driver = {
        .deion = hcd_name,
        .product_desc = "AT91 OHCI",
        .hcd_priv_size = sizeof(struct ohci_hcd),


        .irq = ohci_irq,
        .flags = HCD_USB11 | HCD_MEMORY,


        .start = ohci_at91_start,
        .stop = ohci_stop,
        .shutdown = ohci_shutdown,


        .urb_enqueue = ohci_urb_enqueue,
        .urb_dequeue = ohci_urb_dequeue,
        .endpoint_disable = ohci_endpoint_disable,


        .get__number = ohci_get_,


        .hub_status_data = ohci_hub_status_data,
        .hub_control = ohci_hub_control,
        .hub_irq_enable = ohci_rhsc_enable,
        #ifdef CONFIG_PM
        .bus_suspend = ohci_bus_suspend,
        .bus_resume = ohci_bus_resume,
        #endif
        .start_port_reset = ohci_start_port_reset,
        };

        基于通用性,即使是你自己寫的Linux驅動,簡單到只是點亮一個LED,基于“通用性”,這個驅動也要向上提供統一的接口。下面是單片機LED驅動程序和Linux下的LED驅動程序的部分代碼。

        單片機LED驅動程序:

        void led_init(void)
        {
        GPBCON = GPB5_out; // 將LED對應的GPB5引腳設為輸出
        }

        void led_on(void)
        {
        GPBDAT &= ~(1<<5);
        }

        void led_off(void)
        {
        GPBDAT |= (1<<5);
        }

        Linux的LED驅動程序:
        #define DEVICE_NAME "leds"
        #define LED_MAJOR 231


        #define IOCTL_LED_ON 0
        #define IOCTL_LED_OFF 1


        static unsigned long led_table [] = {
        S3C2410_GPB5,
        S3C2410_GPB6,
        S3C2410_GPB7,
        S3C2410_GPB8,
        };


        static unsigned int led_cfg_table [] = {
        S3C2410_GPB5_OUTP,
        S3C2410_GPB6_OUTP,
        S3C2410_GPB7_OUTP,
        S3C2410_GPB8_OUTP,
        };


        static int s3c24xx_leds_open(struct inode *inode, struct file *file)
        {
        int i;

        for (i = 0; i < 4; i++) {
        // 設置GPIO引腳的功能:本驅動中LED所涉及的GPIO引腳設為輸出功能
        s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
        }
        return 0;
        }


        static int s3c24xx_leds_ioctl(
        struct inode *inode,
        struct file *file,
        unsigned int cmd,
        unsigned long arg)
        {
        if (arg > 4) {
        return -EINVAL;
        }

        switch(cmd) {
        case IOCTL_LED_ON:
        // 設置指定引腳的輸出電平為0
        s3c2410_gpio_setpin(led_table[arg], 0);
        return 0;

        case IOCTL_LED_OFF:
        // 設置指定引腳的輸出電平為1
        s3c2410_gpio_setpin(led_table[arg], 1);
        return 0;

        default:
        return -EINVAL;
        }
        }


        static struct file_operations s3c24xx_leds_fops = {
        .owner = THIS_MODULE,
        .open = s3c24xx_leds_open,
        .ioctl = s3c24xx_leds_ioctl,
        };


        static int __init s3c24xx_leds_init(void)
        {
        int ret;


        ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c24xx_leds_fops);
        if (ret < 0) {
        printk(DEVICE_NAME " cant register major number");
        return ret;
        }

        printk(DEVICE_NAME " initialized");
        return 0;
        }


        static void __exit s3c24xx_leds_exit(void)
        {

        unregister_chrdev(LED_MAJOR, DEVICE_NAME);
        }


        module_init(s3c24xx_leds_init);
        module_exit(s3c24xx_leds_exit);

        2.2. 應用程序開發的區別

        2.2.1 對于不帶操作系統的應用編程,應用程序和驅動程序之間的間隔并不明顯。

        舉個例子,要在LCD上顯示字母“a”,在單片機上的做法是:
        ① 事先在Flash上保存“a”的點陣數據,假設它的象素大小是8x8,那么這個點陣大小就是8x8=64 bits,即8字節
        ② 應用程序讀取這64bit數據,逐個象素地在LCD上描點

        相對的,基于操作系統的應用編程,就不需要懂得硬件知識,執行一個簡單的“echo a > /dev/tty1”就可以在LCD上顯示“a”了。

        2.2.2 不帶操作系統的應用程序,可借用的軟件資源很少;

        帶操作系統的應用程序,網上各種開源的軟件很多。

        比如要做一個播放器,在不帶操作系統上實現會非常困難;如果是在Linux下,有現成的。

        2.2.3 不帶操作系統的應用程序,各個任務是串行執行的;

        帶操作系統的應用程序,各個任務是并行執行的。

        2.2.4 不帶操作系統的應用程序,一旦發生程序錯誤,整個系統將崩潰

        帶操作系統的應用程序,即使發生了程序錯誤,操作系統本身并不會崩潰


        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 阿拉善盟| 永嘉县| 辛集市| 咸阳市| 玉龙| 湾仔区| 东光县| 自贡市| 桃园县| 五河县| 永年县| 东阳市| 新营市| 嘉善县| 铁力市| 富裕县| 连江县| 宁波市| 偏关县| 淮北市| 黑山县| 青浦区| 临泽县| 沅陵县| 平江县| 虹口区| 昌宁县| 灌南县| 佛教| 桐城市| 启东市| 长沙市| 房产| 铁岭市| 全椒县| 蚌埠市| 嵊泗县| 瑞丽市| 马公市| 巴楚县| 庆阳市|