linux一键烧写应用程序工具--自制

一、介绍
linux烧写包括应用、内核、文件系统、uboot,在实际开发过程中应用修改是最频繁,但是烧写占用时间比较多,这个给出一个工具通过网络和串口一键烧写并启动应用,让linux应用开发烧写变得和单片机一样简单

二、原理思路
通过在linux设备上面创建tcp服务端,
pc上面通过客户端连接服务端,
pc发送文件数据到设备服务端,
设备服务端收到数据将数据写入文件,
当收到数据完成以后,启动新的程序

开源链接

三、代码实现
设备端
main.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tcp.h"
#include "download.h"



int main()
{
    unsigned char rcvbuff[1024] = {0};
    unsigned char sendbuff[1024] = {0};
    int rcvlen,sendlen;
    unsigned short port = 100;

    printf("update process start\n");
    system("ifconfig");
    printf("server port:%d\n",5000);
    while(tcp_server_init(port) == -1)
    {
        usleep(1000);//1ms
        port+= 10;
        printf("port:%d\n",port);
    }
    printf("tcp server init ok\n");
    

    while (1)
    {
        rcvlen = 0;
        rcvlen = tcp_server_rcv(0, rcvbuff, 1024);
        if(rcvlen > 0)
            printf("tcp rcv:%s\n", rcvbuff);
        download_run(rcvbuff, rcvlen, sendbuff, &sendlen);
        if(sendlen > 0)
        {
            tcp_server_send(0, sendbuff, sendlen);
            sendlen = 0;
        } 
        usleep(10000);//10ms
    }

    return 0;
}

download.c

#include "file.h"
#include <stdio.h>

enum {
    WAIT_CMD = 0,
    RCV_FILE,
    CLOSE_OLD_PROCESS,
    OPEN_NEW_PROCESS
};

unsigned char write_buff[1024] = {0};
int write_len = 0;
unsigned long total_size = 0;

unsigned short check_sum(unsigned char *buff, unsigned int len)
{
    unsigned short ret = 0;
    unsigned int i;
    for ( i = 0; i < len; i++)
    {
        ret += buff[i];
    }
    
    return ret;
}

int mystr_cmp(unsigned char *s1, unsigned char *s2, int len)
{
    int i;

    for ( i = 0; i < len; i++)
    {
        if(s1[i] != s2[i])
            return 0;
    }
    
    return 1;
}
//查询下载命令
//接收文件
//关闭旧的程序
//打开新的程序
int download_run(unsigned char *rcvbuff, int rcvlen,unsigned char *sendbuff, int *sendlen)
{
    static char state = 0;
    unsigned short check_num = 0;

    printf("download_run\n");
    switch (state)
    {
        case WAIT_CMD:
            printf("WAIT_CMD\n");
            if(rcvlen > 0)
            {
                if(mystr_cmp(rcvbuff, "download", 8) == 1)
                {
                    state = RCV_FILE;
                    memcpy(sendbuff, "start", 5);
                    *sendlen = 5;
                    total_size = 0;
                    printf("start to rcv file\n");
                }
            }
            break;

        case RCV_FILE:
            printf("RCV_FILE\n");
            if(mystr_cmp(rcvbuff, "end", 3) == 1)
            {
                state = CLOSE_OLD_PROCESS;
                printf("rcv file ok\nclsoe old app\n");
            }
            else if(rcvlen > 0)
                {
                    //memcpy(write_buff, rcvbuff, rcvlen);
                    write_file1("newapp", rcvbuff, rcvlen);
                    check_num = check_sum(rcvbuff, rcvlen);
                    sendbuff[0] = check_num&0xff;
                    sendbuff[1] = check_num>>8;
                    memcpy(&sendbuff[2],"ok\n", 3);
                    sendlen = 5;
                    total_size += rcvlen;
                    printf("total_size:%d\n", total_size);
                }
            break;

        case CLOSE_OLD_PROCESS:
            //close old app
            printf("CLOSE_OLD_PROCESS\n");
            state = OPEN_NEW_PROCESS;
            //system("rm -rf newapp");
           // sleep(1);
            printf("open new app\n");
            break;

        case OPEN_NEW_PROCESS:
            //open new app
            printf("OPEN_NEW_PROCESS\n");
            system("chmod 777 newapp");
            sleep(1);
            system("./newapp");
            sleep(1);
            printf("app opened\n wait cmd");
            state = WAIT_CMD;
            break;

        default:
            state = WAIT_CMD;
            break;
    }
}

download.h

#ifndef __DOWNLOAD_H
#define __DOWNLOAD_H
int download_run(unsigned char *rcvbuff, int rcvlen,
unsigned char *sendbuff, int *sendlen);

#endif

tcp.c

//-------tcp相关头文件------
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> //close()


static int socket_fd = 0;

//tcp_client_init()
//1、创建socket
//2、配置为客户端
//3、配置要连接的服务器ip和端口以及协议类型
//4、连接服务器
//5、收发数据
//6、关闭连接
int tcp_client_init(char *ip, int port)
{
	int ret;
	//1 2
	socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(socket_fd == -1)
	{
		printf("create socket fail\n");
		return -1;
	}
	//3 
	struct sockaddr_in servaddr;
	servaddr.sin_family = AF_INET;//IPv4协议	
	servaddr.sin_port = htons(port);//服务器端口号	
	servaddr.sin_addr.s_addr = inet_addr(ip);//设置服务器
	//4
	ret = connect(socket_fd, &servaddr, sizeof(servaddr));
	if(ret == -1)
	{
		printf("connect %s fail\n", ip);
		return -1;
	}
}

//tcp_client_send()
int tcp_client_send(char *buff, int len)
{
	write(socket_fd, buff, len);
}

//tcp_client_rcv()
int tcp_client_rcv(char *buff, int *len)
{
	int ret;

	ret = read(socket_fd, buff, 1024);
    *len = ret;

	return ret;
}

//tcp_client_close()
int tcp_client_close()
{
	close(socket_fd);
}


#define CLENT_NUM 2
struct sockaddr_in sSever_c_sd[CLENT_NUM];
static int socket_s_fd = 0;
static int socket_c_fd[CLENT_NUM] = {0};
//tcp_server_init()
#if 0
1、创建socket
2、设置本地ip和端口以及协议类型
3、绑定
4、监听
5、等待客户端连接
6、收发数据
7、关闭连接
#endif

int tcp_server_init(int port)
{
	int ret;
	//1 
	socket_s_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(socket_s_fd == -1)
	{
		printf("create socket fail\n");
		return -1;
	}
	else
	{
		printf("create socket ok\n");
	}
	//2 
	struct sockaddr_in local_addr,c_addr;
	local_addr.sin_family = AF_INET;//IPv4协议	
	local_addr.sin_port = htons(port);//服务器端口号	
	local_addr.sin_addr.s_addr = INADDR_ANY;//设置服务器ip
	//3
	ret = bind(socket_s_fd, &local_addr, sizeof(local_addr));
	if(ret == -1)
	{
		printf("bind fail\n");
		close(socket_s_fd);
		return -1;
	}
	else
	{
		printf("bind ok\n");
	}
	//4
	ret = listen(socket_s_fd, 3);
	if(ret == -1)
	{
		printf("listen fail\n");
		close(socket_s_fd);
		return -1;
	}
	else
	{
		printf("listen ok\n");
	}
	//5
	socklen_t addrlen = 0;
	while(1)
	{
		printf("wait client conect\n");
		socket_c_fd[0] = accept(socket_s_fd, &c_addr, &addrlen);
		if(addrlen != 0)
			break;
		sleep(1);
	}
	printf("client conect\n");

	return 0;
}

//tcp_server_send()
int tcp_server_send(char c, char *buff, int len)
{
	write(socket_c_fd[c], buff, len);
}

//tcp_server_rcv()
int tcp_server_rcv(char c, char *buff, int len)
{
	int ret;
	
	ret = read(socket_c_fd[c], buff, len);
	return ret;
}

//tcp_server_close()
int tcp_server_close()
{
	close(socket_s_fd);
}


tcp.h

#ifndef __TCP_H
#define __TCP_H

int tcp_client_init(char *ip, int port);
int tcp_client_send(unsigned char *buff, int len);
int tcp_client_rcv(unsigned char *buff, int *len);
int tcp_client_close();
int tcp_server_init( int port);
int tcp_server_send(char c, unsigned char *buff, int len);
int tcp_server_rcv(char c, unsigned char *buff, int len);
int tcp_server_close();

#endif

file.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int write_file(char *filename, char *s, int len)
{
	int fd;
	
	fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, O_APPEND); //创建并打开文件
	if(fd > 0)//创建成功或者打开成功
	{
		write(fd, s, len);
		close(fd);

        return -1;
	}
	else
	{
        printf("open %s fail\n",filename);
        return 0;
	}
}

int read_file(char *filename, char *s, int len)
{
	int fd,rtn_len;
	
	fd = open(filename, O_RDWR);
	rtn_len = read(fd, s, len); /* 读取文件内容 */
	close(fd);

	return rtn_len;
}

int write_file1(char *filename, char *s, int len)
{
	FILE *fp;
	
	fp = fopen(filename, "ab+"); //创建并打开文件
	if(fp > 0)//创建成功或者打开成功
	{
		fwrite(s, 1, len, fp);
		fclose(fp);

        return -1;
	}
	else
	{
        printf("open %s fail\n",filename);
        return 0;
	}
	fclose(fp);
}

int read_file1(char *filename, char *s, int len)
{
	int rtn_len;
	FILE *fp;

	fp = fopen(filename, "rb");
	rtn_len = fread(s, 1, len, fp); /* 读取文件内容 */
	fclose(fp);

	return rtn_len;
}

file.h

#ifndef __FILE_H
#define __FILE_H

int write_file(char *filename, char *s, int len);
int read_file(char *filename, char *s, int len);
int write_file1(char *filename, char *s, int len);
int read_file1(char *filename, char *s, int len);
#endif

编译脚本
build.sh

gcc  *.c -o netupdate -w

运行
./netupdate

测试
1、windows传执行文件到linux
1)启动程序./netupdate
在这里插入图片描述

2)打开网络调试最新版(老版本发送文件有问题)
连接设备
在这里插入图片描述
3)发送download启动下载
在这里插入图片描述
4)发送文件
这个文件事先已经编译好了放在windows上的测试程序
在这里插入图片描述在这里插入图片描述
选择文件
在这里插入图片描述
发送完成以后,发送end结束发送
在这里插入图片描述
再发送两次end等待设备启动程序
在这里插入图片描述

2、linux传执行文件到linux
linux端需要写发送程序
main.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "tcp.h"

int mystr_cmp(unsigned char *s1, unsigned char *s2, int len)
{
    int i;

    for ( i = 0; i < len; i++)
    {
        if(s1[i] != s2[i])
            return 0;
    }
    
    return 1;
}

int sendrcv(unsigned char *s, int len, unsigned char *rcv, int rcvlen)
{
    unsigned char rcvbuff[1024] = {0};
    unsigned char sendbuff[1024] = {0};
    int sendlen;
    char overtime = 0;

    tcp_client_send(s, len);
    while(1)
    {
        if(tcp_client_rcv(rcvbuff, 1024) > 0)
        {
            if( mystr_cmp(&rcvbuff, rcv, rcvlen) == 1)
            {
                printf("send ok\n");
                return 0;
            }
        }
        overtime++;
        usleep(1000);
        if(overtime > 3)
        {
            return -1;
        }
    }
}

int sendfile(char *filename, char *ip, int port)
{
    FILE *fp;
    int rtn_len;
    int ret = 0;

    unsigned char rcvbuff[1024] = {0};
    unsigned char sendbuff[1024] = {0};
    int rcvlen,sendlen;
    unsigned long total_size = 0;
    int overtime = 0;

    while(tcp_client_init(ip, port) == -1)
    {
        printf("conncet ip:%s port:%d fail\n",ip, port);
        sleep(1);
    }
	fp = fopen(filename, "rb");
    if(fp == -1)
    {
        printf("open %s fail\n", filename);
    }

	tcp_client_send("download", 8);
    sleep(1);

    while(1)
    {
        rtn_len = 0;
        rtn_len = fread(sendbuff, 1, 1024, fp); /* 读取文件内容 */
        if(rtn_len > 0)
        {
            total_size += rtn_len;
            tcp_client_send(sendbuff, rtn_len);
            printf("total size %d\n", total_size);
        }

        while(1)
        {
            if(tcp_client_rcv(rcvbuff, 10) > 0)
            {
                 if( mystr_cmp(&rcvbuff[2], "ok", 2) == 1)
                {
                    printf("send ok\n");
                    break;
                }
            }
            usleep(1000);
            overtime++;
            if(overtime > 10)
            {
                overtime = 0;
                break;
            }   
        }
        
        if(rtn_len == 0)
        {
            printf("send finished\n");
            tcp_client_send("end", 3);
            break;
        }  
    }
    tcp_client_send("end", 3);
    sleep(1);
    tcp_client_send("end", 3);

    fclose(fp);
}

int main(int argc, char *argv[])
{
    if(argc > 3)
    {
        printf("input:%s %s %s\n",argv[1],argv[2],argv[3]);
        sendfile(argv[1], argv[2], atoi(argv[3]));
    }
    else
    {
        sendfile("test", "192.168.136.130", 1040);
    }
    
    return 0;
}

tcp.c

//-------tcp相关头文件------
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> //close()


static int socket_fd = 0;

//tcp_client_init()
//1、创建socket
//2、配置为客户端
//3、配置要连接的服务器ip和端口以及协议类型
//4、连接服务器
//5、收发数据
//6、关闭连接
int tcp_client_init(char *ip, int port)
{
	int ret;
	//1 2
	socket_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(socket_fd == -1)
	{
		printf("create socket fail\n");
		return -1;
	}
	//3 
	struct sockaddr_in servaddr;
	servaddr.sin_family = AF_INET;//IPv4协议	
	servaddr.sin_port = htons(port);//服务器端口号	
	servaddr.sin_addr.s_addr = inet_addr(ip);//设置服务器
	//4
	ret = connect(socket_fd, &servaddr, sizeof(servaddr));
	if(ret == -1)
	{
		printf("connect %s fail\n", ip);
		close(socket_fd);
		return -1;
	}
	return 0;
}

//tcp_client_send()
int tcp_client_send(char *buff, int len)
{
	write(socket_fd, buff, len);
}

//tcp_client_rcv()
int tcp_client_rcv(char *buff, int len)
{
	int ret;

	//ret = read(socket_fd, buff, 1024);
	ret = recv(socket_fd, buff, len, MSG_DONTWAIT);

	return ret;
}

//tcp_client_close()
int tcp_client_close()
{
	close(socket_fd);
}


#define CLENT_NUM 2
struct sockaddr_in sSever_c_sd[CLENT_NUM];
static int socket_s_fd = 0;
static int socket_c_fd[CLENT_NUM] = {0};
//tcp_server_init()
#if 0
1、创建socket
2、设置本地ip和端口以及协议类型
3、绑定
4、监听
5、等待客户端连接
6、收发数据
7、关闭连接
#endif

int tcp_server_init(int port)
{
	int ret;
	//1 
	socket_s_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(socket_s_fd == -1)
	{
		printf("create socket fail\n");
		return -1;
	}
	else
	{
		printf("create socket ok\n");
	}
	//2 
	struct sockaddr_in local_addr,c_addr;
	local_addr.sin_family = AF_INET;//IPv4协议	
	local_addr.sin_port = htons(port);//服务器端口号	
	local_addr.sin_addr.s_addr = INADDR_ANY;//设置服务器ip
	//3
	ret = bind(socket_s_fd, &local_addr, sizeof(local_addr));
	if(ret == -1)
	{
		printf("bind fail\n");
		close(socket_s_fd);
		return -1;
	}
	else
	{
		printf("bind ok\n");
	}
	//4
	ret = listen(socket_s_fd, 3);
	if(ret == -1)
	{
		printf("listen fail\n");
		close(socket_s_fd);
		return -1;
	}
	else
	{
		printf("listen ok\n");
	}
	//5
	socklen_t addrlen = 0;
	while(1)
	{
		printf("wait client conect\n");
		socket_c_fd[0] = accept(socket_s_fd, &c_addr, &addrlen);
		if(addrlen != 0)
			break;
		sleep(1);
	}
	printf("client conect\n");

	return 0;
}

//tcp_server_send()
int tcp_server_send(char c, char *buff, int len)
{
	write(socket_c_fd[c], buff, len);
}

//tcp_server_rcv()
int tcp_server_rcv(char c, char *buff, int len)
{
	int ret;
	
	ret = read(socket_c_fd[c], buff, len);
	return ret;
}

//tcp_server_close()
int tcp_server_close()
{
	close(socket_s_fd);
}


tcp.h

#ifndef __TCP_H
#define __TCP_H

int tcp_client_init(char *ip, int port);
int tcp_client_send(unsigned char *buff, int len);
int tcp_client_rcv(unsigned char *buff, int len);
int tcp_client_close();
int tcp_server_init( int port);
int tcp_server_send(char c, unsigned char *buff, int len);
int tcp_server_rcv(char c, unsigned char *buff, int len);
int tcp_server_close();

#endif

编译脚本,大家要把运行后面的程序名字和ip端口自己改一下

gcc  *.c -o netupdatesend -w
./netupdatesend test 192.168.136.130 1030

运行设备端tcp服务```
在这里插入图片描述

执行,发送端
在这里插入图片描述
结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值