上一篇博文说了嵌入式linux通过systemd自启动一个python代码,这次把python代码改为c代码,再试试。
主要有两个文件:
/etc/systemd/system/autostart.service,用于启动/home/roor/autostart.sh
/home/roor/autostart.sh用于启动c代码编译而成的二进制可执行代码xwsoft。
其中,/etc/systemd/system/autostart.service代码如下:
[Unit]
Description=python_detection
DefaultDependencies=no
Documentation=
After=network.target multi-user.target timers.target
Wants=
Requires=
[Service]
Type=forking
ExecStart=/home/root/autostart.sh
Restart=on-failure
ExecStop=
ExecReload=/home/root/autostart.sh
[Install]
WantedBy=multi-user.target
/home/roor/autostart.sh代码如下:
#!/bin/sh
sleep 10
sudo ifconfig eth0 up 192.168.137.81
sleep 5
sudo ip link set can0 up type can bitrate 500000
sleep 5
sudo ip link set can1 up type can bitrate 500000
sleep 5
cd /home/root
sudo ./xwsoft &
#cd /home/root/python
#sudo /usr/bin/python3 mydeamon.py &
而最终要实现的xwsoft代码如下:
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/syslog.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#define MAX_BUF 256
#define RECV_TIME_OUT 1
// int init_daemon(void)
// {
// int pid;
// int i;
// // 1)屏蔽一些控制终端操作的信号
// signal(SIGTTOU, SIG_IGN);
// signal(SIGTTIN, SIG_IGN);
// signal(SIGTSTP, SIG_IGN);
// signal(SIGHUP, SIG_IGN);
// // 2)在后台运行
// if (pid = fork())
// { // 父进程
// exit(0); //结束父进程,子进程继续
// }
// else if (pid < 0)
// { // 出错
// perror("fork");
// exit(EXIT_FAILURE);
// }
// // 3)脱离控制终端、登录会话和进程组
// setsid();
// // 4)禁止进程重新打开控制终端
// if (pid = fork())
// { // 父进程
// exit(0); // 结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
// }
// else if (pid < 0)
// { // 出错
// perror("fork");
// exit(EXIT_FAILURE);
// }
// // 5)关闭打开的文件描述符
// // NOFILE 为 <sys/param.h> 的宏定义
// // NOFILE 为文件描述符最大个数,不同系统有不同限制
// for (i = 0; i < NOFILE; ++i)
// {
// close(i);
// }
// // 6)改变当前工作目录
// chdir("/tmp");
// // 7)重设文件创建掩模
// umask(0);
// // 8)处理 SIGCHLD 信号
// signal(SIGCHLD, SIG_IGN);
// return 0;
// }
int main(int argc, char *argv[])
{
struct ifreq ifr = {0};
struct sockaddr_can can_addr = {0};
struct can_frame frame = {0};
int sockfd = -1;
int i;
int ret;
//printf("start xwsoft daemon.\n");
/* create daemon */
//init_daemon();
/* 打开套接字 */
sockfd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (0 > sockfd)
{
//perror("socket error");
exit(EXIT_FAILURE);
}
/* 指定 can0 设备 */
strcpy(ifr.ifr_name, "can0");
ioctl(sockfd, SIOCGIFINDEX, &ifr);
can_addr.can_family = AF_CAN;
can_addr.can_ifindex = ifr.ifr_ifindex;
/* 将 can0 与套接字进行绑定 */
ret = bind(sockfd, (struct sockaddr *)&can_addr, sizeof(can_addr));
if (0 > ret)
{
//perror("bind error");
close(sockfd);
exit(EXIT_FAILURE);
}
while (1)
{
/* receive msg */
if (0 > read(sockfd, &frame, sizeof(struct can_frame)))
{
//perror("read error");
break;
}
/* send msg */
ret = write(sockfd, &frame, sizeof(frame)); //发送数据
if (sizeof(frame) != ret)
{ //如果 ret 不等于帧长度,就说明发送失败
//perror("write error");
break;
}
}
/* 关闭套接字 */
close(sockfd);
exit(EXIT_SUCCESS);
return 0;
}
如上图所示,本来想创建一个daemon进程,结果试了半天都不行,不知道哪里出错了,只好暂时放弃daemon。
最终程序运行后,可在ps -x进程列表中看到xwsoft进程在启动运行。
134 ? S< 0:00 [ext4-rsv-conver]
154 ? Ss 0:00 /lib/systemd/systemd-journald
164 ? Ss 0:01 /lib/systemd/systemd-udevd
215 ? Ss 0:00 /usr/sbin/crond -n
220 ? Ss 0:00 /lib/systemd/systemd-logind
224 ? Ss 0:00 /sbin/syslogd
283 ? Ss 0:00 /usr/sbin/connmand -n
288 ? Ss 0:00 /usr/sbin/ofonod -n
304 ? Ss 0:00 /usr/sbin/atd -f
441 ? Ss 0:00 /usr/sbin/wpa_supplicant -u
445 ? Ss 0:00 /sbin/klogd
453 tty1 Ss+ 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
457 ttymxc0 Ss 0:00 /bin/login -f
459 ? S 0:00 [kworker/0:5]
505 ? Ss 0:00 /lib/systemd/systemd --user
512 ? S 0:00 (sd-pam)
524 ttymxc0 S 0:00 -sh
539 ? S 0:00 sudo ./xwsoft
540 ? S 0:00 ./xwsoft
542 ttymxc0 R+ 0:00 ps -x