1,实现两个设备驱动:蜂鸣器,led灯
2,写一个服务器程序接收客户端命令,根据命令操作不同的设备
3,实现一个客户端程序,向服务器发送命令,控制设备
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/time.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
if(argc!=3){
perror("argc error");
exit(1);
}
int socket_fd = socket(AF_INET,SOCK_STREAM,0);
if(socket_fd==-1){
perror("socket error");
exit(1);
}
int on=1;
setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
char ch[100]={};
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
int connect_ret = connect(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(connect_ret==-1){
perror("connect error");
exit(1);
}
fd_set send_set;
while(1){
FD_ZERO(&send_set);
FD_SET(0,&send_set);
FD_SET(socket_fd,&send_set);
select(socket_fd+1,&send_set,NULL,NULL,NULL);
if(FD_ISSET(0,&send_set)){
bzero(ch,sizeof(ch));
gets(ch);
send(socket_fd,ch,strlen(ch),0);
}
if(FD_ISSET(socket_fd,&send_set)){
bzero(ch,sizeof(ch));
int recv_ret = recv(socket_fd,ch,sizeof(ch),0);
if(recv_ret==0){
break;
}
printf("%s\n",ch);
}
}
return 0;
}
#include "link.h"
#define LED_ALL_ON _IO('L', 0x01)
#define LED_ALL_OFF _IO('L',0x02)
#define LED_NUM_ON _IOW('L', 0x03, int)
#define LED_NUM_OFF _IOW('L',0x04,int)
#define Buzzer_ON _IO('B',0x05)
#define Buzzer_OFF _IO('B',0x06)
int main(int argc,char *argv[])
{
if(argc!=3){
perror("argc error");
exit(1);
}
char ch[100] = {};
char buf[100] = {};
char ch_head[100]={};
char ch_cmd[100]={};
char ch_num[100]={};
char ch_count=0;
char head_count=0;
char cmd_count=0;
char num_count=0;
int send_fd;
int socket_fd = socket(AF_INET,SOCK_STREAM,0);
if(socket_fd==-1){
perror("socket error");
exit(1);
}
int fd = open("/dev/hello2",O_RDWR);
if(fd<0){
perror("open error");
exit(-1);
}
int on=1;
setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
int bind_ret = bind(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(bind_ret==-1){
perror("bind error");
exit(1);
}
listen(socket_fd,5);
plink Describe_Link;
plink temp_link;
int temp_fd;
fd_set recv_set;
int accept_ret;
int Max_nfds = socket_fd;
int ret;
Init_Link(&Describe_Link);
while(1){
FD_ZERO(&recv_set);
FD_SET(0,&recv_set);
FD_SET(socket_fd,&recv_set);
display(Describe_Link,&recv_set);
select(Max_nfds+1,&recv_set,NULL,NULL,NULL);
if(FD_ISSET(socket_fd,&recv_set)){
accept_ret = accept(socket_fd,NULL,NULL);
printf("%d is connnect...\n",accept_ret);
Insert_Link_Head(Describe_Link,accept_ret);
Max_nfds = Find_Link_Node(Describe_Link,0);
}
if(FD_ISSET(0,&recv_set)){
bzero(buf,sizeof(buf));
bzero(ch,sizeof(ch));
gets(ch);
sscanf(ch,"%d:%s",&send_fd,buf);
send(send_fd,buf,strlen(buf),0);
}
temp_link = Describe_Link->next;
while(temp_link != Describe_Link){
if(FD_ISSET(temp_link->data,&recv_set)){
bzero(ch,sizeof(ch));
ret = recv(temp_link->data,ch,sizeof(ch),0);
if(ret == 0){
temp_fd = temp_link->data;
Del_Link_Data(Describe_Link,temp_link->data);
close(temp_fd);
break;
}
bzero(ch_head,sizeof(ch_head));
bzero(ch_cmd,sizeof(ch_cmd));
bzero(ch_num,sizeof(ch_num));
printf("%d:%s\n",temp_link->data,ch);
while(ch[ch_count] != '\0'){
while(ch[ch_count]!=':'){
ch_head[head_count++]=ch[ch_count++];
}
ch_count++;
while(ch[ch_count]!=':'){
ch_cmd[cmd_count++]=ch[ch_count++];
}
ch_count++;
while(ch[ch_count] != '\0')
ch_num[num_count++]=ch[ch_count++];
break;
}
ch_count=0;
head_count=0;
cmd_count=0;
num_count=0;
printf("%s--%s--%s\n",ch_head,ch_cmd,ch_num);
if(strcasecmp(ch_head,"led")==0){
if(strcasecmp(ch_cmd,"on")==0){
ioctl(fd,LED_NUM_ON,atoi(ch_num));
printf("LED_NUM_ON\n");
}else if(strcasecmp(ch_cmd,"off")==0){
ioctl(fd,LED_NUM_OFF,atoi(ch_num));
printf("LED_NUM_OFF\n");
}else if(strcasecmp(ch_cmd,"allon")==0){
ioctl(fd,LED_ALL_ON);
printf("LED_ALL_ON\n");
}else if(strcasecmp(ch_cmd,"alloff")==0){
ioctl(fd,LED_ALL_OFF);
printf("LED_ALL_OFF\n");
}
}else if(strcasecmp(ch_head,"buzzer")==0){
if(strcasecmp(ch_cmd,"on")==0){
ioctl(fd,Buzzer_ON);
printf("Buzzer_ON\n");
}else if(strcasecmp(ch_cmd,"off")==0){
ioctl(fd,Buzzer_OFF);
printf("Buzzer_OFF\n");
}
}
}
temp_link = temp_link->next;
}
}
close(fd);
return 0;
}
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/virtio.h>
#include <linux/gpio.h>
#define LED_ALL_ON _IO('L', 0x01)
#define LED_ALL_OFF _IO('L',0x02)
#define LED_NUM_ON _IOW('L', 0x03, int)
#define LED_NUM_OFF _IOW('L',0x04,int)
#define Buzzer_ON _IO('B',0x05)
#define Buzzer_OFF _IO('B',0x06)
#define GPD0_BASE 0xE02000A0
#define GPC0_BASE 0xE0200060
typedef struct s5pv210_led_dev{
unsigned int major;
struct class *class;
struct device *device;
}s5pv210_led_dev_t,*s5pv210_led_dev_p;
s5pv210_led_dev_p Led_Dev;
unsigned int *gpd_conf;
unsigned int *gpd_data;
unsigned int *gpc0_conf;
unsigned int *gpc0_data;
int led_open(struct inode *inode, struct file * filp)
{
printk("-----------^_^ %s---------------\n",__FUNCTION__);
return 0;
}
int led_close (struct inode *inode, struct file *filp)
{
printk("-----------^_^ %s---------------\n",__FUNCTION__);
*gpd_data &= ~(0x01<<1);
*gpc0_data &= ~(0x03<<3);
return 0;
}
ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *flags)
{
int value;
int ret;
printk("-----------^_^ %s---------------\n",__FUNCTION__);
ret = copy_from_user(&value, buf, size);
if(ret>0){
printk("--------copy_from_user error------\n");
return -EINVAL;
}
#if 0
if(value==1){
*gpd_data |= 0x01<<1;
}else if(value==2){
*gpd_data &= ~(0x01<<1);
}else if(value==3){
*gpc0_data &= ~(0x03<<3);
*gpc0_data |= 0x01<<3;
}else if(value==4){
*gpc0_data &= ~(0x03<<3);
*gpc0_data |= 0x01<<4;
}
#else
switch(value){
case 1://蜂鸣器响
*gpd_data |= 0x01<<1;
break;
case 2://蜂鸣器灭
*gpd_data &= ~(0x01<<1);
break;
case 3://led1亮
*gpc0_data &= ~(0x03<<3);
*gpc0_data |= 0x01<<3;
break;
case 4://led2亮
*gpc0_data &= ~(0x03<<3);
*gpc0_data |= 0x01<<4;
break;
default :
break;
}
#endif
return size;
}
long led_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
{
int led_num = arg+2;
printk("-----------^_^ %s---------------\n",__FUNCTION__);
switch(cmd){
case LED_ALL_ON://开所有灯
gpio_request(S5PV210_GPC0(3),"gpc0_3");
gpio_direction_output(S5PV210_GPC0(3),1);
gpio_free(S5PV210_GPC0(3));
gpio_request(S5PV210_GPC0(4),"gpc0_3");
gpio_direction_output(S5PV210_GPC0(4),1);
gpio_free(S5PV210_GPC0(4));
break;
case LED_ALL_OFF://关所有灯
gpio_request(S5PV210_GPC0(3),"gpc0_3");
gpio_direction_output(S5PV210_GPC0(3),0);
gpio_free(S5PV210_GPC0(3));
gpio_request(S5PV210_GPC0(4),"gpc0_3");
gpio_direction_output(S5PV210_GPC0(4),0);
gpio_free(S5PV210_GPC0(4));
break;
case LED_NUM_ON://开某个灯
if(led_num!=3 && led_num!=4){
printk("--------parameter error------\n");
return -EINVAL;
}
gpio_request(S5PV210_GPC0(led_num),"gpc0_3/4");
gpio_direction_output(S5PV210_GPC0(led_num),1);
gpio_free(S5PV210_GPC0(led_num));
break;
case LED_NUM_OFF://关闭某个灯
if(led_num!=3 && led_num!=4){
printk("--------parameter error------\n");
return -EINVAL;
}
gpio_request(S5PV210_GPC0(led_num),"gpc0_3/4");
gpio_direction_output(S5PV210_GPC0(led_num),0);
gpio_free(S5PV210_GPC0(led_num));
break;
case Buzzer_ON://开蜂鸣器
gpio_request(S5PV210_GPD0(1), "gpd0_1");
gpio_direction_output(S5PV210_GPD0(1),1);
gpio_free(S5PV210_GPD0(1));
break;
case Buzzer_OFF://关闭蜂鸣器
gpio_request(S5PV210_GPD0(1), "gpd0_1");
gpio_direction_output(S5PV210_GPD0(1),0);
gpio_free(S5PV210_GPD0(1));
break;
default :
printk("--------parameter error------\n");
break;
}
return 0;
}
const struct file_operations fops = {
.open = led_open,
.release = led_close,
.write = led_write,
.unlocked_ioctl = led_ioctl,
};
static int __init led_drv_init(void)
{
int ret;
printk("--------%s------\n",__FUNCTION__);
Led_Dev = kzalloc(sizeof(s5pv210_led_dev_t), GFP_KERNEL);
if(IS_ERR(Led_Dev)){
printk("--------kzalloc error------\n");
return -ENOMEM;
}
Led_Dev->major= register_chrdev(0, "led_drv", &fops);
if(Led_Dev->major<0){
printk("--------register_chrdev error------\n");
goto err_kfree;
}
printk("Led_Dev->major=%d\n",Led_Dev->major);
Led_Dev->class= class_create(THIS_MODULE, "led_class");
if(IS_ERR(Led_Dev->class)){
printk("--------class_create error------\n");
ret=PTR_ERR(Led_Dev->class);
goto err_unregister_chrdev;
}
Led_Dev->device=device_create(Led_Dev->class, NULL, MKDEV(Led_Dev->major, 5), NULL, "hello2");
if(IS_ERR(Led_Dev->device)){
printk("--------device_create error------\n");
ret = PTR_ERR(Led_Dev->device);
goto err_destorry_class;
}
gpd_conf = ioremap(GPD0_BASE, 8);
if(IS_ERR(gpd_conf)){
printk("--------ioremap error------\n");
ret = PTR_ERR(gpd_conf);
goto err_device_destory;
}
gpd_data = gpd_conf+1;
gpc0_conf = ioremap(GPC0_BASE, 8);
if(IS_ERR(gpc0_conf)){
printk("--------ioremap error------\n");
ret = PTR_ERR(gpc0_conf);
goto err_iounmap;
}
gpc0_data = gpc0_conf+1;
return 0;
err_iounmap:
iounmap(gpd_conf);
err_device_destory:
device_destroy(Led_Dev->class, MKDEV(Led_Dev->major, 5));
err_destorry_class:
class_destroy(Led_Dev->class);
err_unregister_chrdev:
unregister_chrdev(Led_Dev->major, "led_drv");
err_kfree:
kfree(Led_Dev);
return ret;
}
static void __exit led_drv_exit(void)
{
printk("--------%s------\n",__FUNCTION__);
iounmap(gpc0_conf);
iounmap(gpd_conf);
device_destroy(Led_Dev->class, MKDEV(Led_Dev->major, 5));
class_destroy(Led_Dev->class);
unregister_chrdev(Led_Dev->major, "led_drv");
kfree(Led_Dev);
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");
#include "link.h"
void Init_Link(plink *P_Link)
{
*P_Link = (plink)malloc(sizeof(link));
if(*P_Link==NULL){
printf("*P_Link malloc error %s\n",__FUNCTION__);
return;
}
(*P_Link)->next = *P_Link;
}
plink Creat_Node(datatype d)
{
plink P_Link = (plink)malloc(sizeof(link));
if(P_Link==NULL){
printf("Creat_Node malloc error %s\n",__FUNCTION__);
return;
}
P_Link->data = d;
P_Link->next = P_Link;
return P_Link;
}
void Insert_Link_Head(plink head,datatype data)
{
if(head == NULL){
return ;
}
plink node = Creat_Node(data);
if(node == NULL){
printf("Creat_Node malloc error %s\n",__FUNCTION__);
}
node->next = head->next;
head->next = node;
}
void Insert_Link_Tail(plink head,datatype data)
{
if(head == NULL){
return ;
}
plink p = head->next;
while(p->next != head){
p = p->next;
}
plink node = Creat_Node(data);
if(node == NULL){
printf("Creat_Node malloc error %s\n",__FUNCTION__);
}
node->next = p->next;
p->next = node;
}
void Del_Link_Data(plink head,datatype data)
{
if(head==NULL){
return;
}
plink p = head;
plink old_node;
while(p->next!=head){
if(p->next->data == data){
old_node=p->next;
p->next = p->next->next;
old_node->next = NULL;
free(old_node);
continue;
}
p = p->next;
}
}
void Updata_Link(plink head,datatype Old_data,datatype New_data)
{
if(head==NULL){
return;
}
plink p = head;
plink old_node;
while(p->next!=head){
if(p->next->data == Old_data){
old_node=p->next;
plink New_node=Creat_Node(New_data);
if(New_node == NULL){
return;
}
New_node->next=p->next->next;
p->next = New_node;
old_node->next = NULL;
free(old_node);
continue;
}
p = p->next;
}
}
datatype Find_Link_Node(plink head,datatype data)
{
if(head==NULL){
return;
}
plink p = head->next;
while(p!=head){
if(p->data > data){
data = p->data;
}
p = p->next;
}
return data;
}
void display(plink head,fd_set *recv_set)
{
if(head == NULL){
return ;
}
plink p = head->next;
while(p!=head){
FD_SET(p->data,recv_set);
p = p->next;
}
}
void display_value(plink head)
{
if(head == NULL){
return ;
}
plink p = head->next;
while(p!=head){
printf("%d\n",p->data);
p = p->next;
}
}
#ifndef __LINK___
#define __LINK___
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
typedef int datatype;
typedef struct linklist{
datatype data;
struct linklist *next;
}link,*plink;
extern void Init_Link(plink *P_Link);
extern void Insert_Link_Head(plink head,datatype data);
extern void display(plink head,fd_set *recv_set);
extern void Insert_Link_Tail(plink head,datatype data);
extern void Del_Link_Data(plink head,datatype data);
extern void Updata_Link(plink head,datatype Old_data,datatype New_data);
extern datatype Find_Link_Node(plink head,datatype data);
extern void display_value(plink head);
#endif
KERNEL_DIR = /home/zzz/fs210/kerner/linux-3.0.8
CUR_DIR = $(shell pwd)
MYAPP=home_work_server
all:
make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
arm-none-linux-gnueabi-gcc -o $(MYAPP) link.c $(MYAPP).c
gcc -o home_work_client link.c home_work_client.c
clean:
make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
rm -rf $(MYAPP)
rm -rf home_work_client
install:
cp *.ko $(MYAPP) /opt/rootfs/drv_module
obj-m += led_drv.o