2013年6月26日 星期三

C

led.c
#include <linux/config.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/init.h>                 
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <linux/miscdevice.h>
#include <asm/delay.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-mem.h>
#define LED_R 1
#define LED_L 2
#define LED_AA 3
#define LED_BB 4
#define LED_MAJOR 210      //裝置預設號碼
#define led_name "led"     //
裝置號碼
static int __iomem * LED8X8_Address;  //led
點矩陣記憶體位置指標
u16 LED8X8_Disp1[8] = {0x00,0x02,0x02,0x02,0x02,0x02,0xfe,0x00};
u16 LED8X8_Disp2[8] = {0x00,0x1e,0x12,0x12,0x12,0x12,0xfe,0x00};
u16 LED8X8_Disp3[8] = {0x00,0x9e,0x92,0x92,0x92,0x92,0xf2,0x00};
u16 LED8X8_Disp4[8] = {0x00,0xf2,0x92,0x92,0x92,0x92,0x9e,0x00};
u16 LED8X8_Disp5[8] = {0x00,0x92,0x92,0x92,0x92,0x92,0xfe,0x00};
u16 LED8X8_Disp6[8] = {0x00,0xf2,0x92,0x92,0x92,0x92,0x9e,0x00};
u16 LED8X8_Disp7[8] = {0x00,0x92,0x92,0x92,0x92,0x92,0xfe,0x00};
u16 LED8X8_Disp8[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x00};
#define MS_DELAY(s)   Delay(s<<3)
void Delay(int time)        //
延遲副程式
{
#define S 3C 2440A _FCLK 400000000     //2440
的工作時脈(倍頻)
 volatile int i, j = 0;
 volatile static int loop = S 3C 2440A _FCLK/100000; 

 for(;time > 0;time--)
  for(i=0;i < loop; i++) { j++; }

}
void LED8X8_Display( u16 *LED8X8, u32 d )//left
{
u 16 m ,i ;
while( d-- ){
for( i = 16; i > 0; i-- )  {
for( m = 0; m < 8; m++ )    {
*LED8X8_Address = ( (1<<(i+m))&0xff00 ) | ( (~(LED8X8[m])) & 0x00ff ) ;
 MS_DELAY( 2) ;          
  }}
 break ;
 }
}
void ALED8X8_Display( u16 *LED8X8, u32 d )   //right
{
u 16 m ,j;
while( d-- ) {
for( j = 0; j < 16; j++ ){
for( m = 0; m < 8; m++ )        {
*LED8X8_Address = ( (1<<(j+m))&0xff00 ) | ( (~(LED8X8[m])) & 0x00ff ) ;
 MS_DELAY( 2) ;                 
}}
      break ;
 }
}
static void led_LL()        //8*8left
{  
 LED8X8_Display( LED8X8_Disp1,30) ;
 LED8X8_Display( LED8X8_Disp2,30) ;
 LED8X8_Display( LED8X8_Disp3,30) ;
 LED8X8_Display( LED8X8_Disp4,30) ;
 LED8X8_Display( LED8X8_Disp5,30) ;
 LED8X8_Display( LED8X8_Disp6,30) ;
 LED8X8_Display( LED8X8_Disp7,30) ;
 LED8X8_Display( LED8X8_Disp8,30) ;
*LED8X8_Address = 0xffff ;
}
static void led_RR()          //8*8right
{
 ALED8X8_Display(LED8X8_Disp1,30) ;
 ALED8X8_Display(LED8X8_Disp2,30) ;
 ALED8X8_Display(LED8X8_Disp3,30) ;
 ALED8X8_Display(LED8X8_Disp4,30) ;
 ALED8X8_Display(LED8X8_Disp5,30) ;
 ALED8X8_Display( LED8X8_Disp6,30) ;
 ALED8X8_Display( LED8X8_Disp7,30) ;
 ALED8X8_Display( LED8X8_Disp8,30) ;
*LED8X8_Address = 0xffff ;
}

static void led_A()          //4led on
{
int gpfdat,count;
 gpfdat = __raw_readl(S 3C 2410_GPFDAT);    
 for(count=4;count<8;count++){            
  gpfdat &=~(1<<count);                 
  __raw_writel(gpfdat,S 3C 2410_GPFDAT);  
  Delay(1000);
 }
}
static void led_B()          //4led off
{
int gpfdat,count;
 gpfdat = __raw_readl(S 3C 2410_GPFDAT);    
 for(count=4;count<8;count++){            
  gpfdat |=1<<count;                    
  __raw_writel(gpfdat,S 3C 2410_GPFDAT);  
  Delay(1000);
 }
}

static ssize_t led_read(struct file *filp,char *buf,size_t count,loff_t *l)
{
 return count;
}
static ssize_t led_write(struct file *filp,const char *buf,size_t count,loff_t *f_ops)
{
 return count;
}
static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{        
 int ret = 0;
 int num;
 switch(cmd)  
 {
 case LED_R:
  led_RR();
  break;
 case LED_L:
  led_LL();
  break;
 case LED_AA:
 led_A();
  break;
 case LED_BB:
 led_B();
  break;

 }
 return 0;
}
static int led_open(struct inode *inode, struct file *filp)    

        s 3c 2410_gpio_cfgpin(S 3C 2410_GPF4, S 3C 2410_GPF4_OUTP);
        s 3c 2410_gpio_cfgpin(S 3C 2410_GPF5, S 3C 2410_GPF5_OUTP);
        s 3c 2410_gpio_cfgpin(S 3C 2410_GPF6, S 3C 2410_GPF6_OUTP);
        s 3c 2410_gpio_cfgpin(S 3C 2410_GPF7, S 3C 2410_GPF7_OUTP);
 return 0;
}
static int led_release(struct inode *inode, struct file *filp)
{
 return 0;
}
static struct file_operations led_fops =     //led檔案作業結構
{
 owner:  THIS_MODULE,      //
指向擁有此結構的模組
 read : led_read,
 write : led_write,
 ioctl : led_ioctl,    //led I/O
控制
 open : led_open,     //
應用程式開啟檔案的動作
 release : led_release,  
};

static int __init led_init(void)   
{
 int retval;
 int bwscon;
 int bankcon1;

 retval = register_chrdev(LED_MAJOR,led_name,&led_fops);                 //
註冊字元裝置函式,MAJOR是主裝置號碼,Name是驅動程式名稱,fops是檔案作業結構
 if(retval < 0)
 {
  printk(KERN_WARNING"Can't get major %d\n",LED_MAJOR);
  return retval;
 }
 s 3c 2410_gpio_cfgpin(S 3C 2410_GPA12, S 3C 2410_GPA12_nGCS1);
 bwscon = __raw_readl(S 3C 2410_BWSCON);         
 bwscon&= ~(0xF << 4);  //
設定bank1記憶體
 bwscon|= (0x6 << 4);
 __raw_writel(bwscon, S 3C 2410_BWSCON); //
寫入設定

 bankcon1 = __raw_readl(S 3C 2410_BANKCON1); //
取得bankcon1控制暫存器
 bankcon1 =((0x3<<13)+(0x3<<11)+(0x7<<8)+(0x3<<6)  //
設定工作時序
  +(0x3<<4)+(0x3<<2)+(0x0));
 __raw_writel(bankcon1, S 3C 2410_BANKCON1);         
 
 LED8X8_Address = ioremap(0x08000000,4); 
 if (LED8X8_Address == 0) {
  printk(KERN_INFO  "failed to ioremap() region\n");
  return -EINVAL;
 }

 printk("LED driver register success!\n");                
 return 0;
}
static void __exit led_exit(void)   //
卸載函式
{
 unregister_chrdev(LED_MAJOR,led_name);  //
註銷函式將裝置移出系統 MAJOR為設備號碼,Name為裝置名稱
 printk("LED driver release success!\n");
}
module_init(led_init);   //
巨集函式,作用是指出模組初始函式位置,必設
module_exit(led_exit);  //
巨集函式,作用是註銷註冊軟體介面,將資源還給系統,必設
MODULE_LICENSE("GPL"); //不打會有warning
MODULE_AUTHOR("usb lab");//
目的碼資訊檔
MODULE_DESCRIPTION("led  driver");   //
目的碼資訊檔
LED_run
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(){
 int fd;
 int val=-1;
 fd=open("/dev/led",O_RDONLY);
 if(fd<0){
  printf("can not open device\n");
  exit(1);
 }
 while(1){
  printf("please select number to run program\n");
  printf("BY ME TEST              \n");
  printf("1:Right \n 2:Left\n 3:POEWR ON\n 4:POWER OFF\n  5:Exit\n");
  scanf("%d",&val);
  if(val==1)ioctl(fd,1,10);
  else if(val==2) ioctl(fd,2,10);
  else if(val==3) ioctl(fd,3,10);
  else if(val==4) ioctl(fd,4,10);
  else if(val==5){
   close(fd);
   break;
 }
 }
 return 0;
}
Makefile
#2.6 Makefile
CC= /usr/local/arm/ 3.4.1 /bin/arm-linux-gcc
S 3C 2440_KERNEL_DIR = /home/Kernel/linux- 2.6.14 .7-2440
ifneq ($(KERNELRELEASE),)
 obj-m := led.o
else
 KERNELDIR ?= $(S 3C 2440_KERNEL_DIR)
 PWD := $(shell pwd)
default: A B
A:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
B:
 $(CC) -o LED LED_run.c
clean:
 rm -rf *.o *.mod.* *.ko *.o.* .*.*.cmd
endif
VM模擬器下跑LINUX作業系統,使用RS-232傳輸
(LINUX指令)編寫程式
先解壓縮cross- 3.4.1 .tar,才會有交叉編輯環境。
cd / usr/local /arm/ 3.4.1 /
tar jvxf cross- 3.4.1 .tar.bz2
export PATH=$PWD/usr/local/arm/ 3.4.1 / bin:$PATH
$PATH

撰寫的3個檔
Makefile
LED_run .c 
led.c

1.Led.c   2.LED_run  3.Makefile 必須放在同一資料夾
放置同一資料夾:cd /home/LED終端機執行指令
cd /home/LED
make
開啟另一終端機當平台
minicom 
s傳送   led.ok  and LED 兩檔案
cd /tmp
insmod ./led.ko  //
掛載
cat /porc/devices
mknod /dev/led c 210 0
ls /dev
./LED    //
執行
rmmod led.ko   //
卸載
rm LED led.ko  //
移除


Download

沒有留言:

張貼留言