从tcp到led

开发板客户端:

/*************************************************************************
	> File Name: led_tcp_client_xxdk.c
	> Author: 联合作战实验室
	> Mail: v.manstein@qq.com
	> Created Time: Tue Apr 18 17:21:02 CST 2017
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<fcntl.h>

#define LED_MAGIC 'L'

#define LED_ON	_IOW(LED_MAGIC, 0, int)
#define LED_OFF	_IOW(LED_MAGIC, 1, int)

#define err_log(errlog) do{printf("%s: %s, %d", __FILE__, __func__, __LINE__);\
                          perror(errlog);}while(0)
#define N 128

struct led
{
	int option;
	char led_name[10];
};

int main(int argc, const char* argv[])
{
	int fd;
    int sockfd, acceptfd;// clinet sockfd
    struct sockaddr_in serveraddr;
    int addrlen = sizeof(struct sockaddr_in);
    char buf[N] = {};

    if(argc < 3) {
        printf("usage: %s ipaddr port\n", argv[0]);
        exit(-1);
    } 
	
	fd = open("/dev/led", O_RDWR);
	if (fd < 0) {
		perror("open");
		exit(1);
	}

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        err_log("socket error");
        exit(-1);
    }
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));
    // 客户端发起对服务器的链接通信访问请求        
    if(connect(sockfd, (struct sockaddr*)&serveraddr, 
               sizeof(struct sockaddr)) < 0) {
        err_log("connect error");
    }
    printf("client connect success\n");
	
	struct led alpha;
	memset(&alpha, 0, sizeof(alpha));

    while(1) {
        if(recv(sockfd, &alpha, sizeof(alpha), 0) < 0) {
            err_log("recv error: ");
        }
		if(strncmp(alpha.led_name, "led2", 4) == 0 ) {
			if(alpha.option == 0) {
				ioctl(fd, LED_OFF);
			} else if(alpha.option == 1) {
				ioctl(fd, LED_ON);
			} 
        }
        printf("\naccept from server: \n");
		printf("alpha.option = %d\n", alpha.option); 
		printf("alpha.led_name = %s\n", alpha.led_name); 
    }

	close(fd);
    close(sockfd);

    return 0;

}
PC服务器端:

/*************************************************************************
	> File Name: led_tcp_server_ubuntu.c
	> Author: 联合作战实验室
	> Mail: v.manstein@qq.com
	> Created Time: Tue Apr 18 17:21:02 CST 2017  
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>


#define err_log(errlog) do{printf("%s: %s, %d", __FILE__, __func__, __LINE__);\
                          perror(errlog);}while(0)
#define N 128

struct led
{
	int option;
	char led_name[10];
};

int main(int argc, const char* argv[])
{

	int sockfd, acceptfd;// clinet sockfd
    // 网络通信结构体
    //  struct sockaddr_in   {                                                   
    //      __SOCKADDR_COMMON (sin_);   // 地址族
    //      in_port_t sin_port;         /* Port number. 端口号 */
    //      struct in_addr sin_addr;    /* Internet address. ip地址  */
    //      /* Pad to size of `struct sockaddr'.  */
    //      unsigned char sin_zero[sizeof (struct sockaddr) -   
    //          __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) -
    //          sizeof (struct in_addr)];   // 占位填充,没有实际意义
    //  }; 
    struct sockaddr_in serveraddr, clinetaddr;
    int addrlen = sizeof(struct sockaddr_in);
    char buf[N] = {};

    if(argc < 3) {
        printf("usage: %s ipaddr port\n", argv[0]);
        exit(-1);
    } 

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        err_log("socket error");
        exit(-1);
    }
    serveraddr.sin_family = AF_INET;
    // inet_addr将点分十进制的ip地址,转换成本地地址进行存储(网络字节序的)
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    // htons将本机字节序转换为网络字节序
    serveraddr.sin_port = htons(atoi(argv[2]));
    // 将网络信息结构体和网络套接字绑定
    if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr_in)) < 0) {
        err_log("bind error");
    }
    // 设置监听队列,将网络套接字置于被动监听模式
    if(listen(sockfd, 5) < 0) {
        err_log("listen error");
    }
    // 接收客户端请求,反回一个与此客户端通信的套接字
    if((acceptfd = accept(sockfd, (struct sockaddr*)&clinetaddr, &addrlen)) < 0) {
        err_log("accept error");
    }
    
    printf("acceptfd: %d, %s, %d", acceptfd, inet_ntoa(clinetaddr.sin_addr), ntohs(clinetaddr.sin_port));

	struct led alpha;
	memset(&alpha, 0, sizeof(alpha));

    while(1) {
		memset(&alpha, 0, sizeof(alpha));
		printf("please input led option<led2 0|1>: ");
		scanf("%s%d", alpha.led_name, &alpha.option);

        if(send(acceptfd, &alpha, sizeof(alpha), 0) < 0) {
            err_log("send error");
        }

    }
    close(sockfd);
    close(acceptfd);

    return 0;

}

驱动:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>

#include <asm/io.h>
#include <asm/uaccess.h>

MODULE_LICENSE("Dual BSD/GPL");

#define LED_MAGIC 'L'
/*
 * need arg = 1/2 
 */

#define LED_ON	_IOW(LED_MAGIC, 0, int)
#define LED_OFF	_IOW(LED_MAGIC, 1, int)


#define LED_MA 500
#define LED_MI 0
#define LED_NUM 1

#define FS4412_GPX2CON	0x11000C40
#define FS4412_GPX2DAT	0x11000C44

static unsigned int *gpx2con;
static unsigned int *gpx2dat;

struct cdev cdev;

static int s5pv210_led_open(struct inode *inode, struct file *file)
{
	return 0;
}
	
static int s5pv210_led_release(struct inode *inode, struct file *file)
{
	return 0;
}
	
static long s5pv210_led_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int nr;

	switch (cmd) {
		case LED_ON:
			writel(readl(gpx2dat) | 1 << 7, gpx2dat);
			break;
		case LED_OFF:
			writel(readl(gpx2dat) & ~(1 << 7), gpx2dat);
			break;
	}

	return 0;
}
	
struct file_operations s5pv210_led_fops = {
	.owner = THIS_MODULE,
	.open = s5pv210_led_open,
	.release = s5pv210_led_release,
	.unlocked_ioctl = s5pv210_led_unlocked_ioctl,
};

static int s5pv210_led_init(void)
{
	dev_t devno = MKDEV(LED_MA, LED_MI); 
	int ret;

	ret = register_chrdev_region(devno, LED_NUM, "newled");
	if (ret < 0) {
		printk("register_chrdev_region\n");
		return ret;
	}

	cdev_init(&cdev, &s5pv210_led_fops);
	cdev.owner = THIS_MODULE;
	ret = cdev_add(&cdev, devno, LED_NUM);
	if (ret < 0) {
		printk("cdev_add\n");
		goto err1;
	}

	gpx2con = ioremap(FS4412_GPX2CON, 4);
	if (gpx2con == NULL) {
		printk("ioremap gpx2con\n");
		ret = -ENOMEM;
		goto err2;
	}

	gpx2dat = ioremap(FS4412_GPX2DAT, 4);
	if (gpx2dat == NULL) {
		printk("ioremap gpx2dat\n");
		ret = -ENOMEM;
		goto err3;
	}

	writel((readl(gpx2con) & ~(0xf << 28)) | (0x1 << 28), gpx2con);
	writel(readl(gpx2dat) & ~(0x1<<7), gpx2dat);

	printk("Led init\n");

	return 0;
err3:
	iounmap(gpx2con);
err2:
	cdev_del(&cdev);
err1:
	unregister_chrdev_region(devno, LED_NUM);
	return ret;
}

static void s5pv210_led_exit(void)
{
	dev_t devno = MKDEV(LED_MA, LED_MI);

	iounmap(gpx2dat);
	iounmap(gpx2con);
	cdev_del(&cdev);
	unregister_chrdev_region(devno, LED_NUM);
	printk("Led exit\n");
}

module_init(s5pv210_led_init);
module_exit(s5pv210_led_exit);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值