linux内核驱动读写

/**************************************************************************
 *             F U N C T I O N    I M P L E M E N T A T I O N S           *
 **************************************************************************/
#ifdef SUPPORT_LOAD_BMP
static void _initKernelEnv(mm_segment_t *oldfs)
{
    *oldfs = get_fs();
    set_fs(KERNEL_DS);
}

static void _deinitKernelEnv(mm_segment_t *oldfs)
{
    set_fs(*oldfs);
}

static struct file *_openFile(char *path, int flag, int mode)
{
    struct file *fp;

    fp = filp_open(path, flag, 0);
    if (fp)
        return fp;
    else
        return NULL;
}


static int _writeFile(struct file *fp, char *buf, int readlen)
{
    if (fp->f_op && fp->f_op->read)
        return fp->f_op->write(fp, buf, readlen, &fp->f_pos);
    else
        return -1;
}
 

static int _readFile(struct file *fp, char *buf, int readlen)
{
    if (fp->f_op && fp->f_op->read)
        return fp->f_op->read(fp, buf, readlen, &fp->f_pos);
    else
        return -1;
}

static int _closeFile(struct file *fp)
{
    filp_close(fp, NULL);
    return 0;
}

static void _Draw_Bmpfile(char *filename, unsigned int *fb_ptr, int device_id, int start_x, int start_y)
{
    unsigned char    *tmpbuf = NULL;
    struct file        *fp = NULL;
    mm_segment_t    oldfs;
    BMP_HEADER        bmp = {0};

    _initKernelEnv(&oldfs);
    fp = _openFile(filename, O_RDONLY, 0);

    if (!IS_ERR(fp))
    {
        int line_pitch = 0, bpp = 0;
        int x, y, line_index;

        if ((fp == NULL) || (fp && (_readFile(fp, (char *)&bmp.identifier, sizeof(BMP_HEADER) - sizeof(unsigned short)) <= 0)))
        {
            ERRF("read file:%s error\n", filename);
            goto Failed;
        }

        DEBUG("Image info: size %dx%d, bpp %d, compression %d, offset %d, filesize %d\n", bmp.width, bmp.height, bmp.bpp, bmp.compression, bmp.data_offset, bmp.file_size);

        if (!(bmp.bpp == 24 || bmp.bpp == 32))
        {
            ERRF("only support 24 / 32 bit bitmap\n");
            goto Failed;
        }

        if (bmp.bpp == 24)
            line_pitch = DISP_ALIGN(bmp.width, 2);
        else
            line_pitch = bmp.width;

        if ((bmp.width + start_x) > gFB_INFO[device_id]->var.xres)
        {
            ERRF("bmp_width + start_x >= device width, %d + %d >= %d\n", bmp.width, start_x, gFB_INFO[device_id]->var.xres);
            goto Failed;
        }

        if ((bmp.height + start_y) > gFB_INFO[device_id]->var.yres)
        {
            ERRF("bmp_height + start_y >= device height, %d + %d >= %d\n", bmp.height, start_y, gFB_INFO[device_id]->var.yres);
            goto Failed;
        }

        bpp = bmp.bpp >> 3;

        tmpbuf = chunk_malloc(DRAM_B, line_pitch * bmp.height * bpp);
        if (IS_ERR(tmpbuf))
        {
            ERRF("chunk_malloc error\n");
            goto Failed;
        }

        fp->f_op->llseek(fp, bmp.data_offset, 0);
        if (_readFile(fp, tmpbuf, line_pitch * bmp.height * bpp) <= 0)
        {
            ERRF("read file:%s error\n", filename);
            goto Failed;
        }

        fb_ptr += start_y * gFB_INFO[device_id]->var.xres + start_x;

        for (y = bmp.height-1; y >= 0; y--)
        {
            for (x = 0; x < bmp.width; x++)
            {
                line_index = (line_pitch * y + x) * bpp;
#if 0
                DEBUG("B:%x G:%x R:%x A:%x",
                    tmpbuf[line_index],
                    tmpbuf[line_index + 1],
                    tmpbuf[line_index + 2],
                    (bmp.bpp==24)?0xff:tmpbuf[line_index + 3]);
#endif

                fb_ptr[x] = MAKE_ARGB(
                                    (bmp.bpp == 24)?0xff:tmpbuf[line_index + 3],
                                    tmpbuf[line_index + 2],
                                    tmpbuf[line_index + 1],
                                    tmpbuf[line_index]);
            }
            fb_ptr += gFB_INFO[device_id]->var.xres;
        }
    }
    else
    {
        ERRF("Can't open %s\n", filename);
        goto Failed;
    }

Failed:
    if ((!IS_ERR(fp)) && (fp != NULL))
        _closeFile(fp);

    if (!IS_ERR(tmpbuf) && tmpbuf != NULL)
        chunk_free(tmpbuf);

    _deinitKernelEnv(&oldfs);

    return ;
}
#endif
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值