单片机和嵌入式系统linux的区别_第1页
单片机和嵌入式系统linux的区别_第2页
单片机和嵌入式系统linux的区别_第3页
单片机和嵌入式系统linux的区别_第4页
单片机和嵌入式系统linux的区别_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、单片机和嵌入式系统linux的区别 6推荐随着嵌入式行业硬件平台的性能增强,项目需求和功能日益复杂,ARM公司推出的 CORTEX-M3,更是让以往做单片机的工程师在芯片和技术选型面临两难选择,本专题将从芯片价格、整个系统的硬件软件设计及维护的成本等各个方面给您提供一个参考, 并从技术角度分析单片机和带操作系统的系统的软件开发的异同点。    1.单片机与ARM等新处理器的价格比较            2.带操作系统与不带操作系统的软

2、件开发的区别            2.1.驱动开发的区别            2.2.应用程序开发的区别1. 单片机与ARM等新处理器的价格比较表1型号架构 资源 价格(元)AT89S518051 最高频率33MHz4KB Flash128B内部RAM32个可编程IO引脚 两个16bit的计数器 一个UART口 4SST89E564RD8051 最高频率

3、40MHz 64KB Flash1KB内部RAM32个可编程IO引脚 三个16bit的计数器 一个UART口 一个SPI接口 35STM32F103 CORTEX-M3 最高频率72MHz64KB或128BK Flash20KB SRAM80个可编程IO引脚 2个12bit的ADC7通道DMA控制器 标准调试口(SWD和JTAG)7个定时器 USB接口 2个I2C接口 3个UART2个SPI接口 21HI3510ARM9+DSP双核 最高工作频率240MHz视频处理单元,支持多种协议的实时编解码 图形处理单元 视音频接口 以太网接口 DDR控制器 USB、UART、IrDA、 I2C、SPI、

4、GPIO等多种外设接口 80S3C2440ARM9最高工作频率400MHzSDRAM控制器 LCD控制器 4通道DMA控制器 3个UART2个SPI1个I2C接口 IIS音频接口 SD HOST接口 2个USB接口 8个10bit ADC摄像头接口 Camera接口 40 从表1里面各种芯片的资源,大概就可以猜知它们的应用场合。51单片机通常被用来做一些比较简单的控制,比如采集信号、驱动一些开关。AT89S51的Flash只有4K,一个稍微复杂的程序就不止4K了。SST89E564RD是一种扩展的51单片机,它的Flash达到64KB,可以外接最多64KB的SRAM。在SST89E5

5、64RD上的程序可以写得更复杂一些,但是它对外的接口也比较少。CORTEX-M3系列的处理器,对外接口极其丰富,这使得它的应用面更广,但是限于它的Flash、内存还是比较小,一般不在上面运行操作系统,它算是一个性能非常突出的单片机。HI3510是海思半导体公司的一款用于监控设备的芯片,一般上面运行Linux系统,通过摄像头采集数据、编码,然后通过网络传输。另一端接收到数据之后,再解码。在上面运行的程序非常复杂,有漂亮的图片界面、触摸屏控制、数据库等等。对声音图像的编解码更是用到DSP核。S3C2440是一款通用的芯片,它与“高级单片机”STM32F103相比,多了存储控制器和NAND控制器这使

6、得可以外接更大的Flash、更大的内存;多了内存管理单元(MMU)这使得它可以进行地址映身(虚拟地址、物理地址之间的映射)。可以在S3C2440上运行Linux系统,运行更大更复杂的程序。在具体工作中,怎么选择这些芯片呢?一句话:成本!进行任何产品的开发都要考虑性价比,一切应该从“成本”出发。成本不仅包括芯片的价格,也包括整个系统的硬件、软件设计及维护的难易。芯片价格可以在电子市场问到,也可以在上找到有卖这种芯片的柜台,然后电话咨询。基于不同的应用,处理器和其他外设的选择是要统一考虑的,如果要实现一个简单的U盘读写功能,那么可以选择带USB控制器的CORTEX-M3芯片,也可以选择8051外接

7、一个USB控制器比如SL811,就看哪种方案成本更低。进行芯片选型时,必须基于整个系统来考虑。员工的偏好和知识结构也是一个很重要的因素,如果他对ATMEL的芯片比较熟,他就不会倾向于三星;如果他不会Linux等操作系统,那么选型时就不会有操作系统的概念。选择自己不熟悉的芯片和技术,最后的成本也可能更高。2. 带操作系统与不带操作系统的软件开发的区别用通俗的话来说,一个处理芯片不运行操作系统,我们就把它称为单片机,而单片机编程就是写裸板程序,这个程序直接在板子上运行;相对的,另一种程序就是基于操作系统的程序,说得简单点就是,这种程序可以通过统一的接口调用“别人写好的代码”,在“别人的基础上”更快

8、更方便地实现自己的功能。2.1. 驱动开发的区别驱动开发的区别我总结有两点:能否借用、是否通用。2.1.1 能否借用基于操作系统的软件资源非常丰富,你要写一个Linux设备驱动时,首先在网上找找,如果有直接拿来用;其次是找到类似的,在它的基础上进行修改;如果实在没有,就要研究设备手册,从零写起。而不带操作系统的驱动开发,一开始就要深入了解设备手册,从零开始为它构造运行环境,实现各种函数以供应用程序使用。 举个例子,要驱动一块LCD,在单片机上的做法是: 首先要了解LCD的规格,弄清楚怎么设置各个寄存器,比如设置LCD的时钟、分辨率、象素 划出一块内存给LCD使用 编写一个函数,实现在指定坐标描

9、点。比如根据x、y坐标在这块内存里找到这个象素对应的小区域,填入数据。基于操作系统时,我们首先是找到类似的驱动,弄清楚驱动结构,找到要修改的地方进行修改。下面是单片机操作LCD的代码: 初始化:void Tft_Lcd_Init(int type)                       /*       

10、;          * 设置LCD控制器的控制寄存器LCDCON15                * 1. LCDCON1:                * 设置VCLK的频

11、率:VCLK(Hz) = HCLK/(CLKVAL+1)x2                * 选择LCD类型: TFT LCD                 * 设置显示模式: 16BPP       &#

12、160;        * 先禁止LCD信号输出                * 2. LCDCON2/3/4:                * 设置控制信号的时间参数  &#

13、160;             * 设置分辨率,即行数及列数                * 现在,可以根据公式计算出显示器的频率:              

14、60; * 当HCLK=100MHz时,                * Rate = 1/(VSPW+1)+(VBPD+1)+(LIINEVAL+1)+(VFPD+1)x                *     &

15、#160;  (HSPW+1)+(HBPD+1)+(HFPD+1)+(HOZVAL+1)x                *        2x(CLKVAL+1)/(HCLK)             

16、60;  *        = 60Hz                * 3. LCDCON5:                *    

17、    设置显示模式为16BPP时的数据格式: 5:6:5                *        设置HSYNC、VSYNC脉冲的极性(这需要参考具体LCD的接口信号): 反转           &

18、#160;    *        半字(2字节)交换使能                */                LCDCON1 = (CLKVAL

19、_TFT_320240<<8) | (LCDTYPE_TFT<<5) |                                         (BPPMODE_16

20、BPP<<1) | (ENVID_DISABLE<<0);                LCDCON2 = (VBPD_320240<<24) | (LINEVAL_TFT_320240<<14) |                

21、0;                        (VFPD_320240<<6) | (VSPW_320240);                LCDCON3 = (HBPD_320

22、240<<19) | (HOZVAL_TFT_320240<<8) | (HFPD_320240);                LCDCON4 = HSPW_320240;        /        LCDCON5 = (FORMAT8BPP_5

23、65<<11) | (HSYNC_INV<<9) | (VSYNC_INV<<8) |         /                               

24、60;(HWSWP<<1);                        LCDCON5 = (FORMAT8BPP_565<<11) | (HSYNC_INV<<9) | (VSYNC_INV<<8) | (VDEN_INV << 6) |     

25、60;                                           (HWSWP<<0);   

26、0;    /*                * 设置LCD控制器的地址寄存器LCDSADDR13                * 帧内存与视口(view point)完全吻合,     

27、;           * 图像数据格式如下:                *        |-PAGEWIDTH-|          

28、0;     *        y/x    0    1    2    239                *   

29、;     0    rgb rgb rgb . rgb                *        1    rgb rgb rgb . rgb      

30、0;         * 1. LCDSADDR1:                *    设置LCDBANK、LCDBASEU               

31、 * 2. LCDSADDR2:                *    设置LCDBASEL: 帧缓冲区的结束地址A21:1                * 3. LCDSADDR3:   

32、60;            *    OFFSIZE等于0,PAGEWIDTH等于(240*2/2)                */            

33、;    LCDSADDR1 = (LCDBUFFER>>22)<<21) | LOWER21BITS(LCDBUFFER>>1);                LCDSADDR2 = LOWER21BITS(LCDBUFFER+            

34、;                                 (LINEVAL_TFT_320240+1)*(HOZVAL_TFT_320240+1)*2)>>1);       &

35、#160;        LCDSADDR3 = (0<<11) | (LCD_XSIZE_TFT_320240*2/2);        /* 禁止临时调色板寄存器 */                TPAL = 0;    

36、;    fb_base_addr = LCDBUFFER;                bpp = 16;                xsize = 320;      &

37、#160;         ysize = 240;         描点:/*         * 画点        * 输入参数:        *   

38、     x、y : 象素坐标        *        color: 颜色值        *                对于16BPP:

39、 color的格式为0xAARRGGBB (AA = 透明度),        *        需要转换为5:6:5格式        *                对于8BPP: color为

40、调色板中的索引值,        *        其颜色取决于调色板中的数值        */        void PutPixel(UINT32 x, UINT32 y, UINT32 color)      

41、                  UINT8 red,green,blue;        switch (bpp)                  

42、60;     case 16:                                           &

43、#160;            UINT16 *addr = (UINT16 *)fb_base_addr + (y * xsize + x);                            

44、;    red = (color >> 19) & 0x1f;                                green = (color >> 10) & 0x3f; &

45、#160;                              blue = (color >> 3) & 0x1f;             

46、                   color = (red << 11) | (green << 5) | blue; / 格式5:6:5                    &#

47、160;           *addr = (UINT16) color;                                break; 

48、60;                                              case 8:  &#

49、160;                                                 &#

50、160;   UINT8 *addr = (UINT8 *)fb_base_addr + (y * xsize + x);                                *addr = (UINT8) color; 

51、0;                              break;                  

52、0;                     default:                           &#

53、160;    break;                        下面是在Linux的LCD驱动里修改的地方(archarmmach-s3c2440mach-smdk2440.c):        /* 320x240 */

54、60;       static struct s3c2410fb_mach_info smdk2440_lcd_cfg _initdata =                 .regs =               

55、0;         .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |                                 S3C2410_LCDCON

56、1_TFT |                                 S3C2410_LCDCON1_CLKVAL(0x04),            

57、;    .lcdcon2 = S3C2410_LCDCON2_VBPD(1) |                                 S3C2410_LCDCON2_LINEVAL(239) |   

58、60;                             S3C2410_LCDCON2_VFPD(5) |                 &

59、#160;               S3C2410_LCDCON2_VSPW(1),                .lcdcon3 = S3C2410_LCDCON3_HBPD(36) |         

60、;                        S3C2410_LCDCON3_HOZVAL(319) |                      

61、;           S3C2410_LCDCON3_HFPD(19),                .lcdcon4 = S3C2410_LCDCON4_MVAL(13) |             &#

62、160;                   S3C2410_LCDCON4_HSPW(5),                .lcdcon5 = S3C2410_LCDCON5_FRM565 |    

63、60;                           S3C2410_LCDCON5_INVVLINE |                  &

64、#160;             S3C2410_LCDCON5_INVV |                                S3C

65、2410_LCDCON5_INVVDEN |                                S3C2410_LCDCON5_PWREN |          

66、60;                     S3C2410_LCDCON5_HWSWP,                ,        .gpc

67、con = 0xaaaa56aa,                .gpccon_mask = 0xffffffff,                .gpcup = 0xffffffff,       

68、60;        .gpcup_mask = 0xffffffff,        .gpdcon = 0xaaaaaaaa,                .gpdcon_mask = 0xffffffff,     

69、60;          .gpdup = 0xffffffff,                .gpdup_mask = 0xffffffff,        .fixed_syncs = 1,     &

70、#160;          .type = S3C2410_LCDCON1_TFT,                 .width = 320,                .

71、height = 240,        .xres =                         .min = 320,            

72、0;           .max = 320,                        .defval = 320,          

73、60;     ,        .yres =                         .max = 240,         &

74、#160;              .min = 240,                        .defval = 240,       

75、         ,        .bpp =                         .min = 16,      

76、                  .max = 16,                        .defval = 16,    &

77、#160;           ,        这并不表示代码Linux的驱动程序就比单片机的驱动程序好写,怎么在几万个文件中找到要修改的代码,这也是需要艰苦的学习的。基于操作系统的驱动开发,既要懂得芯片的具体操作,也要理解操作系统的软件结构。2.1.2 是否通用有些单片机厂家也给客户提供了大量的驱动程序,比如USB HOST驱动程序,这可以让客户很容易就可以在它的上面编写程序读写U盘。但是客户写的这些程

78、序,只能在这种芯片、这个驱动程序上使用;更换另一种芯片后,即使芯片公司也提供了驱动程序,但是接口绝对不一样,客户又得重新编写应用程序。基于操作系统的驱动程序要遵循统一的接口,比如对于不同的芯片的USB HOST驱动,它们都要向上提供一个相同的数据结构,在里面实现了各自的USB操作。下面是S3C2410/S3C2440的USB驱动向上层提供的数据结构:static const struct hc_driver ohci_s3c2410_hc_driver =            

79、60;    .deion = hcd_name,                .product_desc = "S3C24XX OHCI",                .hcd_priv_size = sizeo

80、f(struct ohci_hcd),        /*                * generic hardware linkage                */  

81、;              .irq = ohci_irq,                .flags = HCD_USB11 | HCD_MEMORY,        /*   

82、60;            * basic lifecycle operations                */                .st

83、art = ohci_s3c2410_start,                .stop = ohci_stop,                .shutdown = ohci_shutdown,      

84、60; /*                * managing i/o requests and associated device resources                */      

85、0;         .urb_enqueue = ohci_urb_enqueue,                .urb_dequeue = ohci_urb_dequeue,              

86、  .endpoint_disable = ohci_endpoint_disable,        /*                * scheduling support             &#

87、160;  */                .get_number = ohci_get_,        /*                * root hub suppo

88、rt                */                .hub_status_data = ohci_s3c2410_hub_status_data,         &#

89、160;      .hub_control = ohci_s3c2410_hub_control,                .hub_irq_enable = ohci_rhsc_enable,        #ifdef CONFIG_PM    &

90、#160;           .bus_suspend = ohci_bus_suspend,                .bus_resume = ohci_bus_resume,        #endif   

91、;             .start_port_reset = ohci_start_port_reset,        下面是ATMEL公司的ARM芯片的USB驱动向上层提供的数据结构:/*-*/static const struct hc_driver ohci_at91_hc_driver =        

92、;         .deion = hcd_name,                .product_desc = "AT91 OHCI",               

93、60;.hcd_priv_size = sizeof(struct ohci_hcd),        /*                * generic hardware linkage              

94、  */                .irq = ohci_irq,                .flags = HCD_USB11 | HCD_MEMORY,       

95、0;/*                * basic lifecycle operations                */            &#

96、160;   .start = ohci_at91_start,                .stop = ohci_stop,                .shutdown = ohci_shutdown,   

97、;     /*                * managing i/o requests and associated device resources                */   

98、             .urb_enqueue = ohci_urb_enqueue,                .urb_dequeue = ohci_urb_dequeue,          &#

99、160;     .endpoint_disable = ohci_endpoint_disable,        /*                * scheduling support         

100、0;      */                .get_number = ohci_get_,        /*               

101、 * root hub support                */                .hub_status_data = ohci_hub_status_data,       

102、         .hub_control = ohci_hub_control,                .hub_irq_enable = ohci_rhsc_enable,        #ifdef CONFIG_PM   &

103、#160;            .bus_suspend = ohci_bus_suspend,                .bus_resume = ohci_bus_resume,        #endif  

104、;              .start_port_reset = ohci_start_port_reset,        基于通用性,即使是你自己写的Linux驱动,简单到只是点亮一个LED,基于“通用性”,这个驱动也要向上提供统一的接口。下面是单片机LED驱动程序和Linux下的LED驱动程序的部分代码。单片机LED驱动程序:void led_init(void)&#

105、160;                       GPBCON = GPB5_out; / 将LED对应的GPB5引脚设为输出        void led_on(void)          

106、               GPBDAT &= (1<<5);        void led_off(void)                    &#

107、160;    GPBDAT |= (1<<5);        Linux的LED驱动程序:        #define DEVICE_NAME "leds" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */        #define LED_

108、MAJOR 231 /* 主设备号 */* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */        #define IOCTL_LED_ON 0        #define IOCTL_LED_OFF 1/* 用来指定LED所用的GPIO引脚 */        static unsigned long led_table =

109、                 S3C2410_GPB5,                S3C2410_GPB6,             

110、60;  S3C2410_GPB7,                S3C2410_GPB8,        /* 用来指定GPIO引脚的功能:输出 */        static unsigned int led_cfg_table =  

111、60;              S3C2410_GPB5_OUTP,                S3C2410_GPB6_OUTP,             

112、60;  S3C2410_GPB7_OUTP,                S3C2410_GPB8_OUTP,        /* 应用程序对设备文件/dev/leds执行open(.)时,        * 就会调用s3c24xx_leds_open函数

113、        */        static int s3c24xx_leds_open(struct inode *inode, struct file *file)                      &#

114、160; int i;                for (i = 0; i < 4; i+)                         / 设置GPIO引脚的功能:本驱动中

115、LED所涉及的GPIO引脚设为输出功能                        s3c2410_gpio_cfgpin(led_tablei, led_cfg_tablei);               

116、;                 return 0;        /* 应用程序对设备文件/dev/leds执行ioclt(.)时,        * 就会调用s3c24xx_leds_ioctl函数     

117、60;  */        static int s3c24xx_leds_ioctl(                struct inode *inode,               

118、0; struct file *file,                 unsigned int cmd,                 unsigned long arg)       

119、60;                if (arg > 4)                         return -EINVAL;    &#

120、160;                           switch(cmd)                 case IOCTL_LED_ON: &#

121、160;                      / 设置指定引脚的输出电平为0                        s3c24

122、10_gpio_setpin(led_tablearg, 0);                        return 0;        case IOCTL_LED_OFF:        

123、                / 设置指定引脚的输出电平为1                        s3c2410_gpio_setpin(led_tablearg, 1); &#

124、160;                      return 0;        default:                        return -EINVAL;                        /*

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论