linux 下每一個設備都是一個文件

所以要操作就是要先  open 出來 才可以操作

//應用程式端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstring>    //因為 手淫 想用 C++ 寫  而 C++ 的memset 就剛好放在這裡  所以要 include cstring

//static unsigned char seg_buf[4];    // seg_buf 4 * 8 = 32 bits
static unsigned short seg_buf[2];
unsigned char INDEX[] = {0xc0,0xf9,0xa4,0xB0,0x99,0x92,0x82,0xd8,0x80,0x98};    // 0 ~ 9

int main(void)
{
    int fd,len;    //file use
    int count,num1,num2;    // time use
    int i,j;    //loop use
    fd = open("/dev/sseg",O_WRONLY);    //open file READ and WRITE

   // 有 RDONLY WRONLY RDWR 看應該很明顯了
    if (fd < 0)    //file open faile
    {
        printf("error open");
        return (-1);
    }
    num1 = 0,num2 = 0;
    memset(seg_buf, 0, 4);    // short initial
    for (count = 0; count < 100; count++)
    {
        seg_buf[1] = (INDEX[num2] << 8 | INDEX[num1]);    // char + char = short
        len = write(fd, seg_buf, 2);    //write from seg_buf
        num1++;
        if (num1 >= 10)
        {
            num1 = 0;
            num2++;
        }
        for (i = 0; i < 100; i++)
            for (j = 0; j < 2000; j++);
    }
    close(fd);   // close file
    printf("\nclose the device\n");
    return 0;
}

//驅動端 - 字元型態

#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/utsname.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/timer.h>
#include <linux/fs.h>
#include <linux/init.h>

#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>

#define Device_Name    "sseg"  //設備名 對應到 上面的  open /dev/sseg
#define SEG_PORT    (0x8000000)   //nGCS4 的頭位址

int ESD_SEG_init(void);
static int ESD_seg_open(struct inode *inode, struct file *filp);
static ssize_t ESD_seg_write(struct file *filp, void *buf, size_t count, loff_t *l);


struct file_operations ESD_SEG_fops =
{
    owner:   THIS_MODULE,
    open:    ESD_seg_open,
    write:   ESD_seg_write,
};

int ESD_SEG_init(void)
{
    if (register_chrdev(ESD_SEG_MAJOR,Device_Name,&ESD_SEG_fops))  //在 initial 時 register 一個 char device
    {
        printk("can't register");
        return (-EBUSY);
    }
    CSR_WRITE(rBWSCON,(unsigned int)(((CSR_READ(rBWSCON)) & 0xfffcffff) |  (0x01 << 16))); // Set the bank4 bus = 16bits
    CSR_WRITE(rNCACHBE1,((unsigned int)(0xbffffff>>12)<<16 )|((0x8000000 >>12))); // 0x8000000 - 0xbffffff Non-Catch
    printk("ESD 7 Seg set OK!\n");
    return 0;
}

int ESD_SEG_exit(void)
{
    int ret;
    if (0 > (ret = unregister_chrdev(ESD_SEG_MAJOR,Device_Name)))
    {
        printk("can't unregister the char dev %d\n",ret);
        //perror("\n\nerror to unregister char dev : ");
        return (-EBUSY);
    }
}

static int ESD_seg_open(struct inode *inode, struct file *filp)
{
    printk("\ndriver open\n");
    return 0;
}

static ssize_t ESD_seg_write(struct file *filp, void *buf, size_t count, loff_t *l)
{
    unsigned int *var;
    var = (unsigned int *)(buf);
    CSR_WRITE(SEG_PORT,*var);
    printk("write data = 0x%08x\n",*var);
    return count;
}

module_init(ESD_SEG_init);
module_exit(ESD_SEG_exit);

MODULE_LICENSE("GPL");

 

 

程式就是要騙 ARM 去存取 通道4 的記穩體

所以才會對 nGCS4 的位址做存取

nGCS4 的第一個位址就是 0x8000000

es


寫完了這個  我才真正的了解到  計算機組織真的很重要

Little Endian 快把我搞死了

輸出的bug (不知道為什麼 通道就是 16 bits 了,但輸出的空間還是要用 32 bits ...)

就留給未來吧~~~~~

創作者介紹
創作者 喜歡亂搞的世界 的頭像
ffyy99

喜歡亂搞的世界

ffyy99 發表在 痞客邦 留言(0) 人氣( 269 )