2009年12月31日星期四

使用iwconfig 配置无线网卡

操作步骤如下:
1. 启动无线网卡
 ifconfig wlan0 on
2.  扫描无线接入点
iwlist wlan0 scanning
3. 连接接入点
iwconfig wlan0 essid   YOUR-SERVICE-NAME
4. 配置网络
例如
ifconfig wlan0 192.168.xxx.xxx netmask 255.255.255.0  up

5. 测试
例如
ping 192.168.1.1

2009年12月14日星期一

使用bootchart-lite监视linux启动和运行状态

使用bootchart可以方便监视linux的启动和运行时的状态,并能将这些状态信息以图形方式表示,以图像方式输出。
但鉴于bootchart的特殊实现方式,它不太适合嵌入式系统。
在嵌入式系统中,可以使用精简化的bootchart--bootchart-lite,替代bootchart。

1. bootchart-lite 源码下载
http://code.google.com/p/bootchart-lite/

2. 编译
CC=arm-linux-gcc ./configure
make
在src目录下面会生成bootchart-lite可执行文件

bootchart-lite 默认配置是把log文件存放在/etc/bootchart-lite/目录下,
使用之前要先建立这个目录。
3. 配置启动参数,让linux启动后,先启动bootchart-lite
init=bootchart-lite

4. 启动linux

5. 收集log文件,渲染图像
bootchart-lite会生成如下3个log文件:
proc_diskstats.log 
proc_ps.log
proc_stat.log

把这3个文件取出后,在pc上运行如下命令:
tar czf bootchart.tgz *.log
bootchart -f png bootchart.tgz

在log所在目录下,会生成一个bootchart.png文件,打开看看你的系统状态吧。。。。

当然,pc上别忘记装bootchart工具。


2009年12月8日星期二

Linux Framebuffer编程简介

linux下,framebuffer设备文件名通常是/dev/fb0,1,2等。
控制framebuffer设备的一般步骤如下:
1) 打开设备,映射framebuffer
2)依照硬件要求,准备好数据
3)把数据复制到framebuffer

例子程序如下:

1)打开设备,映射framebuffer
static void *fbbuf;
int openfb(char *devname)
{
    int fd;
    fd = open(devname, O_RDWR);
    if (ioctl(fd, FBIOGET_VSCREENINFO, &fbvar) < 0)
        return -1;
    bpp = fbvar.bits_per_pixel;
    screen_size = fbvar.xres * fbvar.yres * bpp / 8;
    fbbuf = mmap(0, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    return fd;
}

2)数据准备,假设lcd控制器被初始化为565,16bit格式的
static inline int  make_pixel(unsigned int a, unsigned int r, unsigned int g, unsigned int b)
{
    return (unsigned int)(((r>>3)<<11)|((g>>2)<<5|(b>>3)));
}

3) 把想要显示的数据复制到framebuffer,假设把framebuffer填充成一种颜色
static void fill_pixel(unsigned int pixel, int x0, int y0, int w, int h)
{
    int i, j;
    unsigned short *pbuf = (unsigned short *)fbbuf;
    for (i = y0; i < h; i ++) {
        for (j = x0; j < w; j ++) {
            pbuf[i * screen_width + j] = pixel;
        }
    }
}

2009年11月25日星期三

在nanox中使用cairo来渲染字体

nanox的字体处理功能用起来不是很方便,而cairo有比较强大的字体渲染和画图功能,因此这次尝试将两者结合。

将两者结合时,唯一需要注意的问题是像素的格式区别:
nanox的各颜色通道顺序是: RGBA R是低地址
cairo的顺序是:BGRA B是低地址

示例代码如下:
使用时,先调用prepare函数,创建cairo的surface,然后调用render函数,获取渲染后的图像,图像的地址
通过buf指针传回.这个buf可以通过nanox的GrArea直接显示,比如:
GrArea (win_id, gc_id, 0, 0, width, height, buf_from_cairo, MWPF_RGB);


static cairo_surface_t *prepare_text(int width, int height)
{
cairo_surface_t * surface;
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
fprintf(stderr, "prepare text finished\n");
return surface;
}

static void render_text(cairo_surface_t *surface, unsigned char **buf,
unsigned int *width, unsigned int *height)
{
unsigned char *databuf;
unsigned int dw, dh , ds;
unsigned char *pixbuf;
unsigned int i, j;
cairo_t *cr = cairo_create(surface);
cairo_select_font_face(cr, "Sazanami Gothic",
CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr, 30.0);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_move_to(cr, 0.0, 35.0);
cairo_show_text(cr, "R u 学生.");
cairo_move_to(cr, 0.0, 0.0);
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
cairo_line_to(cr, 100.0, 15.0);
cairo_arc(cr, 200, 30, 15, 0.0, 2 * 3.1415926);
cairo_stroke(cr);
cairo_destroy(cr);

databuf = cairo_image_surface_get_data(surface);
if (!databuf) {
fprintf(stderr, "get cairo image data failed\n");
return;
}

dw = cairo_image_surface_get_width(surface);
dh = cairo_image_surface_get_height(surface);
ds = cairo_image_surface_get_stride(surface);

fprintf(stderr, " w: %d, h: %d, s: %d\n", dw, dh ,ds);
pixbuf = (unsigned char *)malloc(dh * ds);

/* Name : Low High */
/* Cairo: B G R A */ /* src */
/* Nanox: R G B A */ /* dst */
/* only for little endian ? */
for (i = 0; i < dh; i++) {
unsigned char *row = databuf + i * ds;
unsigned char *dst = pixbuf + i * ds;

for (j = 0; j < ds; j += 4) {
unsigned char *data = &row[j];
unsigned char *b = &dst[j];
unsigned int pixel;
/* wait for optimization */
memcpy(&pixel, data, sizeof(unsigned int));

b[0] = (pixel & 0xff0000) >> 16;
b[1] = (pixel & 0x00ff00) >> 8;
b[2] = (pixel & 0x0000ff) >> 0;
b[3] = 0;
}
}
fprintf(stderr, " render text finished\n");
#if 0
cairo_surface_write_to_png(surface, "hello.png");

2009年10月13日星期二

估计yaffs2内存使用情况

yaffs2主要使用内存的地方是yaffs_object和yaffs_tnode,下面的方法大体上可以估计出使用的
内存数量,但由于yaffs2的内存是根据系统运行情况,动态变化的,实际情况会有些出路。

计算方法如下:
1. yaffs_Objectszh占用 内存情况
   每个文件,目录,符号连接都是一个object,每个object大概用了120个字节。
  所以假设有1000个文件,那么object占用ram的大小是1000 * 120 => 120Kbytes

2. yaffs_Tnode 占用内存情况
  首先计算 需要用多少bit数来表示整个nand:
  bitnum =  log2(nand 有的page数目)
  然后在此基础上加1,yaffs内部表示时候需要多一个bit。
  如果如上的bitnum不是偶数,加1。
  最后内存使用情况是bitnum * pagenum / 8 字节

 例如:nand有65536个页面
          bitnum = log2(65536)  + 1 = 16 + 1 = 17
         向上去偶数,得到bitnum = 18
          最后,表示整个nand的tnode用的内存是:
         18 * 65536 / 8 = 147456 字节

2009年9月16日星期三

arm的按条件执行指令的功能

arm的条件执行功能可以避免执行jmp指令,但每条指令都判断一次条件。

和x86对比的汇编代码如下。

C语言代码如下:
int b;
int test(int a) {
        if (a>0)
                return a+b;
        return b;
}

分别用arm gcc 4.3.3 和x86 gcc 4.3.3 加-O2 -S选项 生成汇编代码。

arm的汇编代码如下:
test:
        .fnstart
.LFB2:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        cmp     r0, #0
        ldrgt   r3, .L5
        ldrle   r3, .L5
        ldrgt   r2, [r3, #0]
        ldrle   r0, [r3, #0]
        addgt   r0, r0, r2
        bx      lr
.L6:
        .align  2
.L5:
        .word   b

x86的汇编代码如下:
test:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        testl   %eax, %eax
        jle     .L2
        addl    b, %eax
        popl    %ebp
        ret
        .p2align 4,,7
        .p2align 3
.L2:
        movl    b, %eax
        popl    %ebp
        ret
        .size   test, .-test
        .comm   b,4,4


2009年9月15日星期二

directfb显示中文

 1. 编译directfb软件栈
     需要的软件包:
                        zlib_1.2.3.3.dfsg.orig.tar.gz, libpng-1.2.38.tar.bz2 , jpegsrc.v7.tar.gz, freetype_2.3.7.orig.tar.gz,  directfb_1.2.8.orig.tar.gz
     (1) zlib 编译:
                 tar zxvf ../src/zlib_1.2.3.3.dfsg.orig.tar.gz
                 cd zlib-1.2.3.3.dfsg
                 CC=arm-none-linux-gnueabi-gcc ./configure --prefix=/opt
                 make && make install
                 cd .. && rm -rf zlib*
     (2) libpng  编译:
tar jxvf ../src/libpng-1.2.38.tar.bz2
cd libpng-1.2.38/
PKG_CONFIG_PATH=/opt/lib/pkgconfig CC=arm-none-linux-gnueabi-gcc CFLAGS=-I/opt/include  \
LDFLAGS=-L/opt/lib ./configure --host=arm-none-linux-gnueabi --prefix=/opt --with-gnu-ld
make && make install
cd .. && rm -rf libpng*
     (3) libjpeg 编译:
                  tar zxvf ../src/jpegsrc.v7.tar.gz
                 cd jpeg-7/
                 CC=arm-none-linux-gnueabi-gcc ./configure --host=arm-none-linux-gnueabi \
                 --prefix=/opt --with-gnu-ld
                make && make install
                 cd .. && rm -rf jpeg*
       (4) freetype 编译:
             tar zxvf ../src/freetype_2.3.7.orig.tar.gz
             cd freetype-2.3.7/
             PKG_CONFIG_PATH=/opt/lib/pkgconfig CC=arm-none-linux-gnueabi-gcc \
             CFLAGS=-I/opt/include LDFLAGS=-L/opt/lib ./configure --host=arm-none-linux-gnueabi  \
             --prefix=/opt --with-gnu-ld
            make && make install
             cd .. && rm -rf freetype*
        (5) directfb 编译:
tar zxvf ../src/directfb_1.2.8.orig.tar.gz
cd directfb-1.2.8
CPPFLAGS="-I/opt/include" CFLAGS="-I/opt/include" LDFLAGS="-L/opt/lib" \
PKG_CONFIG_PATH="/opt/lib/pkgconfig" CC=arm-none-linux-gnueabi-gcc \
./configure --host=arm-none-linux-gnueabi --prefix=/opt --exec-prefix=/opt --enable-zlib --disable-x11  \
--enable-fbdev --disable-sdl --disable-vnc --enable-jpeg --disable-gif \
--enable-text --enable-freetype --enable-text --disable-network --disable-debug-support \
--disable-video4linux --with-gnu-ld
make && make install
cd .. && rm -rf directfb*

 2. 配置根文件系统
     (1) 复制库文件(可根据需要选择,比如帮助文件之类的可以不要, 还可以strip,减少库的占用空间) 
          cp -avrf /opt/*  /mnt/armfs/opt/
     (2) 复制字体文件
          cp -avf /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc  /mnt/armfs/opt/share/directfb-1.2.8/
 3. 编译可应用程序 (参考directfb的文本显示例子)
     程序代码(我用的是linux系统,所以源代码中输入的中文应该是utf8的):
/**
 * text.c
 *
 * Drawing text
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <directfb.h>

/*
 * (Globals)
 */
static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static int screen_width  = 0;
static int screen_height = 0;
#define DFBCHECK(x...)                                         \
  {                                                            \
    DFBResult err = x;                                         \
                                                               \
    if (err != DFB_OK)                                         \
      {                                                        \
        fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
        DirectFBErrorFatal( #x, err );                         \
      }                                                        \
  }

/*
 * The font we will use to draw the text.
 */
static IDirectFBFont *font = NULL;

/*
 * The string we will draw. Strings in DirectFB have to UTF-8 encoded.
 * For ASCII characters this does not make any difference.
 */
static char *text = "DirectFB rulez!我是中国人";
#define DATADIR "/opt/share/directfb-1.2.8"
int main (int argc, char **argv)
{
  int i, width;

  /*
   * A structure describing font properties.
   */
  DFBFontDescription font_dsc;

  /*
   * (Locals)
   */
  DFBSurfaceDescription dsc;

  /*
   * (Initialize)
   */
  DFBCHECK (DirectFBInit (&argc, &argv));
  DFBCHECK (DirectFBCreate (&dfb));
  DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
  dsc.flags = DSDESC_CAPS;
  dsc.caps  = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
  DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary ));
  DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height));

  /*
   * First we need to create a font interface by passing a filename
   * and a font description to specify the desired font size. DirectFB will
   * find (or not) a suitable font loader.
   */
  font_dsc.flags = DFDESC_HEIGHT;
  font_dsc.height = 48;
  DFBCHECK (dfb->CreateFont (dfb, DATADIR"/wqy-zenhei.ttc", &font_dsc, &font));
 
  /*
   * Set the font to the surface we want to draw to.
   */
  DFBCHECK (primary->SetFont (primary, font));
 
  /*
   * Determine the size of our string when drawn using the loaded font.
   * Since we are interested in the full string, we pass -1 as string length.
   */
  DFBCHECK (font->GetStringWidth (font, text, -1, &width));

  /*
   * We want to let the text slide in on the right and slide out on the left.
   */
  for (i = screen_width; i > -width; i--)
    {
      /*
       * Clear the screen.
       */
      DFBCHECK (primary->SetColor (primary, 0x0, 0x0, 0x0, 0xFF));
      DFBCHECK (primary->FillRectangle (primary, 0, 0, screen_width, screen_height));

      /*
       * Set the color that will be used to draw the text.
       */
      DFBCHECK (primary->SetColor (primary, 0x80, 0x0, 0x20, 0xFF));

      /*
       * Draw the text left aligned with "i" as the X coordinate.
       */
      DFBCHECK (primary->DrawString (primary, text, -1, i, screen_height / 2, DSTF_LEFT));

      /*
       * Flip the front and back buffer, but wait for the vertical retrace to avoid tearing.
       */
      DFBCHECK (primary->Flip (primary, NULL, DSFLIP_WAITFORSYNC));
    }

  /*
   * Release the font.
   */
  font->Release (font);

  /*
   * (Release)
   */
  primary->Release (primary);
  dfb->Release (dfb);
 
  return 23;
}