单片机和linux嵌入式操作系统区别随着嵌入式行业硬件平台的性能增强,项目需求和功能日益复杂,ARM公司推出的 CORTEX-M3,更是让以往做单片机的工程师在芯片和技术选型面临两难选择,本专题将从芯片价格、整个系统的硬件软件设计及维护的成本等各个方面给您提供一个参考,并从技术角度分析单片机和带操作系统的系统的软件开发的异同点。
● 1.单片机与ARM等新处理器的价格比较● 2.带操作系统与不带操作系统的软件开发的区别● 2.1.驱动开发的区别● 2.2.应用程序开发的区别1. 单片机与ARM等新处理器的价格比较表1自己不熟悉的芯片和技术,最后的成本也可能更高。
2. 带操作系统与不带操作系统的软件开发的区别用通俗的话来说,一个处理芯片不运行操作系统,我们就把它称为单片机,而单片机编程就是写裸板程序,这个程序直接在板子上运行;相对的,另一种程序就是基于操作系统的程序,说得简单点就是,这种程序可以通过统一的接口调用“别人写好的代码”,在“别人的基础上”更快更方便地实现自己的功能。
2.1. 驱动开发的区别驱动开发的区别我总结有两点:能否借用、是否通用。
2.1.1 能否借用基于操作系统的软件资源非常丰富,你要写一个Linux设备驱动时,首先在网上找找,如果有直接拿来用;其次是找到类似的,在它的基础上进行修改;如果实在没有,就要研究设备手册,从零写起。
而不带操作系统的驱动开发,一开始就要深入了解设备手册,从零开始为它构造运行环境,实现各种函数以供应用程序使用。
举个例子,要驱动一块LCD,在单片机上的做法是:①首先要了解LCD的规格,弄清楚怎么设置各个寄存器,比如设置LCD的时钟、分辨率、象素②划出一块内存给LCD使用③编写一个函数,实现在指定坐标描点。
比如根据x、y坐标在这块内存里找到这个象素对应的小区域,填入数据。
基于操作系统时,我们首先是找到类似的驱动,弄清楚驱动结构,找到要修改的地方进行修改。
下面是单片机操作LCD的代码:①初始化:void Tft_Lcd_Init(int type){/** 设置LCD控制器的控制寄存器LCDCON1~5* 1. LCDCON1:* 设置VCLK的频率:VCLK(Hz) = HCLK/[(CLKVAL+1)x2]* 选择LCD类型: TFT LCD* 设置显示模式: 16BPP* 先禁止LCD信号输出* 2. LCDCON2/3/4:* 设置控制信号的时间参数* 设置分辨率,即行数及列数* 现在,可以根据公式计算出显示器的频率:* 当HCLK=100MHz时,* Rate =1/[{(VSPW+1)+(VBPD+1)+(LIINEVAL+1)+(VFPD+1)}x* {(HSPW+1)+(HBPD+1)+(HFPD+1)+(HOZVAL+1)}x * {2x(CLKVAL+1)/(HCLK)}]* = 60Hz* 3. LCDCON5:* 设置显示模式为16BPP时的数据格式: 5:6:5* 设置HSYNC、VSYNC脉冲的极性(这需要参考具体LCD 的接口信号): 反转* 半字(2字节)交换使能*/LCDCON1 = (CLKVAL_TFT_320240<<8) | (LCDTYPE_TFT<<5) | \(BPPMODE_16BPP<<1) | (ENVID_DISABLE<<0);LCDCON2 = (VBPD_320240<<24) |(LINEVAL_TFT_320240<<14) | \(VFPD_320240<<6) |(VSPW_320240);LCDCON3 = (HBPD_320240<<19) | (HOZVAL_TFT_320240<<8) | (HFPD_320240);LCDCON4 = HSPW_320240;// LCDCON5 = (FORMAT8BPP_565<<11) | (HSYNC_INV<<9) | (VSYNC_INV<<8) | \// (HWSWP<<1);LCDCON5 = (FORMAT8BPP_565<<11) |(HSYNC_INV<<9) | (VSYNC_INV<<8) | (VDEN_INV << 6) | \(HWSWP<<0);/** 设置LCD控制器的地址寄存器LCDSADDR1~3* 帧内存与视口(view point)完全吻合,* 图像数据格式如下:* |----PAGEWIDTH----|* y/x 0 1 2 239* 0 rgb rgb rgb ... rgb* 1 rgb rgb rgb ... rgb* 1. LCDSADDR1:* 设置LCDBANK、LCDBASEU* 2. LCDSADDR2:* 设置LCDBASEL: 帧缓冲区的结束地址A[21:1]* 3. LCDSADDR3:* OFFSIZE等于0,PAGEWIDTH等于(240*2/2)*/LCDSADDR1 = ((LCDBUFFER>>22)<<21) |LOWER21BITS(LCDBUFFER>>1);LCDSADDR2 = LOWER21BITS((LCDBUFFER+ \(LINEVAL_TFT_320240+1 )*(HOZVAL_TFT_320240+1)*2)>>1);LCDSADDR3 = (0<<11) | (LCD_XSIZE_TFT_320240*2/2);/* 禁止临时调色板寄存器 */TPAL = 0;fb_base_addr = LCDBUFFER;bpp = 16;xsize = 320;ysize = 240;}②描点:/** 画点* 输入参数:* x、y : 象素坐标* color: 颜色值* 对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),* 需要转换为5:6:5格式* 对于8BPP: color为调色板中的索引值,* 其颜色取决于调色板中的数值*/void PutPixel(UINT32 x, UINT32 y, UINT32 color){UINT8 red,green,blue;switch (bpp){case 16:{UINT16 *addr = (UINT16*)fb_base_addr + (y * xsize + x);red = (color >> 19) & 0x1f;green = (color >> 10) & 0x3f;blue = (color >> 3) & 0x1f;color = (red << 11) | (green << 5) | blue; // 格式5:6:5*addr = (UINT16) color;break;}case 8:{UINT8 *addr = (UINT8 *)fb_base_addr + (y * xsize + x);*addr = (UINT8) color;break;}default:break;}}下面是在Linux的LCD驱动里修改的地方(arch\arm\mach-s3c2440\mach-smdk2440.c):/* 320x240 */static struct s3c2410fb_mach_info smdk2440_lcd_cfg__initdata = {.regs = {.lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \S3C2410_LCDCON1_TFT | \S3C2410_LCDCON1_CLKVAL(0x04),.lcdcon2 = S3C2410_LCDCON2_VBPD(1) | \S3C2410_LCDCON2_LINEVAL(239) | \ S3C2410_LCDCON2_VFPD(5) | \S3C2410_LCDCON2_VSPW(1),.lcdcon3 = S3C2410_LCDCON3_HBPD(36) | \S3C2410_LCDCON3_HOZVAL(319) | \S3C2410_LCDCON3_HFPD(19),.lcdcon4 = S3C2410_LCDCON4_MVAL(13) | \S3C2410_LCDCON4_HSPW(5),.lcdcon5 = S3C2410_LCDCON5_FRM565 |S3C2410_LCDCON5_INVVLINE |S3C2410_LCDCON5_INVV |S3C2410_LCDCON5_INVVDEN |S3C2410_LCDCON5_PWREN |S3C2410_LCDCON5_HWSWP,},.gpccon = 0xaaaa56aa,.gpccon_mask = 0xffffffff,.gpcup = 0xffffffff,.gpcup_mask = 0xffffffff,.gpdcon = 0xaaaaaaaa,.gpdcon_mask = 0xffffffff,.gpdup = 0xffffffff,.gpdup_mask = 0xffffffff,.fixed_syncs = 1,.type = S3C2410_LCDCON1_TFT,.width = 320,.height = 240,.xres = {.min = 320,.max = 320,.defval = 320,},.yres = {.max = 240,.min = 240,.defval = 240,},.bpp = {.min = 16,.max = 16,.defval = 16,},};这并不表示代码Linux的驱动程序就比单片机的驱动程序好写,怎么在几万个文件中找到要修改的代码,这也是需要艰苦的学习的。
基于操作系统的驱动开发,既要懂得芯片的具体操作,也要理解操作系统的软件结构。
2.1.2 是否通用有些单片机厂家也给客户提供了大量的驱动程序,比如USB HOST驱动程序,这可以让客户很容易就可以在它的上面编写程序读写U盘。
但是客户写的这些程序,只能在这种芯片、这个驱动程序上使用;更换另一种芯片后,即使芯片公司也提供了驱动程序,但是接口绝对不一样,客户又得重新编写应用程序。
基于操作系统的驱动程序要遵循统一的接口,比如对于不同的芯片的USB HOST驱动,它们都要向上提供一个相同的数据结构,在里面实现了各自的USB操作。