OpenRisc入门(11)-编写ipcore 的linux driver,然后run helloworld

引言

我觉得ORPSoC的关键在于‘P’,即programmable。SoC的有优势就在于只要是满足总线interface的ip,可以实现plug & work。

所以一旦完成前面的工作之后,添加属于自己的ip core到ORPSoC的wishbone总线上,并编写它对应的驱动就成为非常关键的一步。

本小节就做一个简单的例子,来说明需要完成的工作步骤及其中遇到的问题和对应的解决方法。

11.1 编写wishbone为interface的ip core(ip_mkg)

1》这一步请参考:

http://blog.csdn.net/rill_zhen/article/details/8659788

2》将其中的my_slave_module链接到ORPSoC的wishbone上。

11.2 编写linux下的driver module

代码及makefile如下:

1》ip_mkg.c

/*
*
* rill mkg driver
*
*/
#include <linux/vmalloc.h>
#include <linux/slab.h>  

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h> /* get_user and put_user */
//#include <linux/clk.h>
//#include <linux/ioport.h>
#include <asm/io.h> /*ioremap*/
#include <linux/platform_device.h> /*cleanup_module*/  

#include "ip_mkg.h"  

void    __iomem     *g_mkg_mem_base = NULL;  

static int device_open(struct inode *inode, struct file *file)
{
    g_mkg_mem_base = ioremap(MKG_MEM_BASE,MKG_MEM_LEN);
    if(NULL == g_mkg_mem_base)
    {
        printk(KERN_ERR "mkg open ioremap error!\n");
        return -1;
    }
    else
    {
        printk("mkg ioremap addr:%d!\n",(int)g_mkg_mem_base);
    }  

    return 0;
}  

static int device_release(struct inode *inode, struct file *file)
{
    return 0;
}  

static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t *offset)
{
    return 0;
}  

static ssize_t device_write(struct file *filp, const char *buffer, size_t count, loff_t *offset)
{
   return 0;
}  

long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
   int ret_val = 0;
   unsigned int ret = 0;
   struct reg_data *new_regs;  

   switch(ioctl_num)
   {
      case IOCTL_REG_SET:
      {
         new_regs = (struct reg_data*)kmalloc(sizeof(struct reg_data), GFP_KERNEL);
         if((ret_val = copy_from_user(new_regs, (struct reg_data*)ioctl_param, sizeof(struct reg_data))) != 0)
            {
                kfree(new_regs);
                printk(KERN_ERR " error copy line_datafrom user.\n");
                return -1;
            }  

            iowrite16(new_regs->value,g_mkg_mem_base+new_regs->addr);
         kfree(new_regs);
     }
     break;  

    case IOCTL_REG_GET:
    {
     new_regs = (struct reg_data*)kmalloc(sizeof(struct reg_data), GFP_KERNEL);
     if((ret_val = copy_from_user(new_regs, (struct reg_data*)ioctl_param, sizeof(struct reg_data))) != 0)
        {
            kfree(new_regs);
            printk(KERN_ERR " error copy line_datafrom user.\n");
            return -1;
        }  

        ret = ioread16(g_mkg_mem_base+new_regs->addr);
        kfree(new_regs);
        return ret;
    }
    break;  

   }  

  return -1;
}  

struct file_operations our_file_ops = {
  .unlocked_ioctl = device_ioctl,
  .read = device_read,
  .write = device_write,
  .open = device_open,
  .release = device_release,
  .owner = THIS_MODULE,
};  

int init_module()
{
    int ret_val;
    int ret;
    void __iomem *ret_from_request;  

    //=== Allocate character device
    ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &our_file_ops);
    if (ret_val < 0)
    {
        printk(KERN_ALERT " device %s failed(%d)\n", DEVICE_NAME, ret_val);
        return ret_val;
    }  

    ret = check_mem_region(MKG_MEM_BASE, MKG_MEM_LEN);
    if (ret < 0)
    {
        printk(KERN_ERR "mkg check_mem_region bussy error!\n");
        return -1;
    }  

    ret_from_request = request_mem_region(MKG_MEM_BASE, MKG_MEM_LEN, "ip_mkg");  

    //===ioremap mkg registers  

    g_mkg_mem_base = ioremap(MKG_MEM_BASE,MKG_MEM_LEN);
    if(NULL == g_mkg_mem_base)
    {
        printk(KERN_ERR "mkg ioremap error!\n");
        return -1;
    }
    else
    {
        ;//printk("mkg ioremap addr:%d!\n",g_mkg_mem_base);
    }  

    printk("mkg module init done!\n");  

    return 0;
}  

void cleanup_module()
{
    release_mem_region(MKG_MEM_BASE, MKG_MEM_LEN);  

    unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
}  

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Rill zhen:rillzhen@gmail.com");

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索struct
, include
, return
, linux 驱动 lcd ioctl
printk
hello old driver、hello world、java helloworld、c hello world、helloworld,以便于您获取更多的相关知识。

时间: 2016-06-23

OpenRisc入门(11)-编写ipcore 的linux driver,然后run helloworld的相关文章

OpenRisc入门(24) ORPSoC boot过程分析

引言 之前做了很多工作,能起orpmon,能起linux,能run helloworld.但是这些都可以说是空中楼阁,如果不把CPU的启动过程搞明白,总感觉心里没底似的.所以本小节就看一下ORPSoC在最初上电之后做的一些工作,与大部分介绍启动代码的流程的角度有所不同. Note:并不讨论上电timing等内容,直接从fetch开始. 1,从哪里取第一条指令 从or1200_defines.v里面可以看到PC的初值,这个是由硬件决定的.这个文件的目录和内容如下图: 分析: 第一条取值的地址:0x

OpenRisc入门(27) wishbone接口的vga ipcore的分析与仿真

引言 图形,总是给人直观的感觉.想让ORPSoC能有image/video的输出,是一件很有意义的事情,而VGA就是其中一个不错的选择. 本小节就分析一下一个wishbone接口的vga模块. 1,模块准备 下载: http://opencores.org/project,vga_lcd 2,模块的architecture 3,模块的使用 这一步需要一点与LCD/vedio相关的知识.我曾经写过一个LCDC的linux driver,并且有数字电视的开发经验,所以理解起来就容易了很多. 这里只把

OpenRisc入门(30) SD card controller模块分析与验证

引言 ORPSoC的硬件平台是包含SD card controller控制器的,但是对应的linux里面却没有对应的linux的驱动程序,这使ORPSoC的SD card的使用收到了很大的限制.没有驱动,硬件是不能工作的,SD卡控制器的驱动,linux提供了非常好的framework,在写驱动时只要开发者=关心最底层的部分,就是和硬件直接打交道的部分,即linuxMMC framework的HOST部分. 本小节并不介绍linux的MMC的framework,而把注意力放在核心部分,即直接对硬件

OpenRisc入门(26) openrisc中断实验

引言 中断(异常)系统,可以说是计算机体系结构重要的组成部分,也是最复杂的部分. 现在的很多外设,都提供中断处理机制,来减少CPU的一直占用时间. 本小节就通过一个简单的例子,来说明openrisc的中断机制的使用方法. 1,功能简介 本小节实现一个wishbone slave模块(mycore),此模块接收其对应的linux driver的指令,产生中断信号. linux driver注册中断处理程序,记录中断发生的次数. 本实验中,在模块加载时(insmod ip_mkg.ko)时触发一次中

iOS开发入门:编写OCUnit测试方法-应用测试方法

应用测试方法 应用测试是测试应用程序的一些功能,这个功能具体到点击一个按钮触发一个事件,因此它主要是测试表示层.我们看看视图控制器ViewController.m中有那些方法需要测试,然后再来设计测试用例. @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } -

含编写软件的Linux镜像安装的问题

问题描述 含编写软件的Linux镜像安装的问题 含自己编写软件的Linux系统的镜像可以安装在U盘但不能装在台式机,能说明我写的软件有问题或这个镜像有问题吗? 解决方案 看下报什么错,是不是分区和引导的问题,或者是驱动的问题. 解决方案二: 选择安装时,它会跳过安装模式,直接进入试用模式的桌面,这是什么问题呀?

Hanvon Artmaster 0806, 1209 Linux Driver 0.4发布

Hanvon Artmaster 0806, 1209 Linux Driver是一个Linux内核的USB驱动程序,支持Artmaster0806和1209的完整功能,包括:笔坐标,触摸/浮动/点击检测,压力,X和Y倾斜,画笔按钮,四个简单的平板按钮,以及滑块按钮. Hanvon Artmaster 0806, 1209 Linux Driver 0.4该版本支持平板模型,Hanvon Rollick RL0604,现在也支持驱动程序. 软件信息:http://linux.fjfi.cvut.

Hanvon Tablet Linux Driver 0.5发布 汉王USB驱动程序

Hanvon Tablet Linux Driver 是一个Linux内核的USB驱动程序,主要支持Artmaster I tablets的完整功能,包括:笔坐标,触摸/浮动/点击检测,压力,X和Y倾斜,画笔按钮,四个简单的平板按钮,以及滑块按钮.该驱动程序还支持一些类似的模型. Hanvon Tablet Linux Driver 0.5该版本支持 Hanvon Artmaster AM0605 tablet,以及nilox艺术画家工作. 软件信息:http://forschung.wi.un

c语言-我的C语言基础入门时编写一个代码,出现问题,希望得到求解。

问题描述 我的C语言基础入门时编写一个代码,出现问题,希望得到求解. 它提示我说的 --------------------Configuration: one - Win32 Debug-------------------- Compiling... one.c D:C语言MSDev98MyProjectsoneone.c(12) : error C2065: 'FebSold' : undeclared identifier D:C语言MSDev98MyProjectsoneone.c(1