ioctl

ioctl()函数详解 阅读详情
文件描述符是低层的输入和输出接口。通过本文可以了解更多关于套接字 I/O 控制 (ioctl) 命令的内容,以及如何使用它们完成各种网络相关的操作.操作系统为套接字、路由表、ARP 

表、全局网络参数和接口提供了相应的控制操作方式。本文适用于对IPv4和IPv6堆栈网络级操作感兴趣的 AIX® Version 5.3 开发人员。

        描述符可以表示到设备、管道或套接字的连接,这些连接用于与另一个进程或普通文件进行通信。I/O 控制
 (ioctl) 函数调用可以用来对特殊文件的基础设备参数进行操作。它们可以完成与打开的文件描述符相关联的控制功能。这些命令涉及文件、流、普通数据链路控制以及其他各种设备

本文将讨论 AIX® Version 5.3 中提供的与网络操作和套接字相关的命令。在下列文件中列出了与套接字相关的命令和结构: 
  • sys/ioctl.h
  • net/if_arp.h
  • net/if.h
  • net/netopt.h
  • netinet/in.h

应用程序开发人员可以使用这些命令,并且在 AIX Version 5.3 的文档中对这些命令进行了详细的描述。本文说明了有关IPv6地址和IPv4 堆栈的常用命令的典型用法。

一、 什么是ioctl。 

      ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数

      如下: 

      int ioctl(int fd, ind cmd, …); 

      其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和

      cmd的意义相关的。 


        
ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。 

二、 ioctl 命令码 

      在驱动程序中实现的ioctl函数体内,实际上是有一个switch{case}结构,每一个case对应一个命令码,做出一些相应的操作。怎么实现这些操作,这是每一个程序员自己的事

      情,因为设备都是特定的,这里也没法说。关键在于怎么样组织命令码,因为在ioctl中命令码是唯一联系用户程序命令和驱动程序支持的途径。 命令码的组织是有一些讲究的,

      因为我们一定要做到命令和设备是一一对应的,这样才不会将正确的命令发给错误的设备,或者是把错误的命令发给正确的设备,或者是把错误的

      命令发给错误的设备。这些错误都会导致不可预料的事情发生,而当程序员发现了这些奇怪的事情的时候,再来调试程序查找错误,那将是非常困难的事情。 

      所以在Linux核心中是这样定义一个命令码的: 



      ____________________________________



      | 设备类型 | 序列号 | 方向 |数据尺寸|



      |----------|--------|------|--------|



      | 8 bit    |  8 bit |2 bit |8~14 bit|



      |----------|--------|------|--------|







      这样一来,一个命令就变成了一个整数形式的命令码。但是命令码非常的不直观,所以



      Linux Kernel中提供了一些宏,这些宏可根据便于理解的字符串生成命令码,或者是从



      命令码得到一些用户可以理解的字符串以标明这个命令对应的设备类型、设备序列号、数



      据传送方向和数据传输尺寸。

     三、 cmd


      下面的清单介绍了一些最重要的结构,使用 ioctl 套接字命令时常常用到这些结构。 


清单 1. struct ifreq (/usr/include/net/if.h

			

/* Interface request structure used for socket

 * ioctl's.  All interface ioctl's must have parameter

 * definitions which begin with ifr_name.  The

 * remainder may be interface specific.

 */

struct  ifreq {

#ifndef IFNAMSIZ

#define IFNAMSIZ        16

#endif

        char    ifr_name[IFNAMSIZ]; 

        union {

                struct  sockaddr ifru_addr;

                struct  sockaddr ifru_dstaddr;

                struct  sockaddr ifru_broadaddr;

                __ulong32_t     ifru_flags;

                int     ifru_metric;

                caddr_t ifru_data;

                u_short ifru_site6;

                __ulong32_t   ifru_mtu;

                int     ifru_baudrate;

        } ifr_ifru;



Following macros are provided for convenience




#define ifr_addr        ifr_ifru.ifru_addr      /* address */

#define ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-to-p link */

#define ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address */

#define ifr_flags       ifr_ifru.ifru_flags     /* flags */

#define ifr_metric      ifr_ifru.ifru_metric    /* metric */

#define ifr_data        ifr_ifru.ifru_data      /* for use by interface */

#define ifr_site6       ifr_ifru.ifru_site6     /* IPv6 site index */

#define ifr_mtu         ifr_ifru.ifru_mtu       /* mtu of interface */

#define ifr_isno        ifr_ifru.ifru_data      /* pointer to if_netopts */

#define ifr_baudrate    ifr_ifru.ifru_baudrate  /* baudrate of interface */

};

      



清单 2. struct ifconf (/usr/include/net/if.h)

				

/*

 * Structure used in SIOCGIFCONF request.

 * Used to retrieve interface configuration

 * for machine (useful for programs which

 * must know all networks accessible).

 */

struct  ifconf {

        int     ifc_len;                /* size of associated buffer */

        union {

                caddr_t ifcu_buf;

                struct  ifreq *ifcu_req;

        } ifc_ifcu;



Following macros are provided for convenience




#define ifc_buf ifc_ifcu.ifcu_buf       /* buffer address */

#define ifc_req ifc_ifcu.ifcu_req       /* array of structures returned */

};

      

 

下面的表 1 介绍了一些接口检索命令。该信息来源于 IBM System p™ 和 AIX。


表 1. 接口检索命令

ioctl 命令描述
SIOCGSIZIFCONF获得获取 SIOCGIFCONF 返回的所有接口的配置信息所需的内存。
		

ioctl(fd, SIOCGSIZIFCONF, (caddr_t)&ifconfsize);



int ifconfsize;

SIOCGIFADDR

SIOCSIFADDR
SIOCGIFADDR 获取接口地址,而 SIOCSIFADDR 设置接口地址。ifr.ifr_addr 字段返回地址。
ioctl(fd, SIOCGIFADDR, (caddr_t)&ifr, sizeof(struct ifreq));



ioctl(fd, SIOCSIFADDR, (caddr_t)&ifr, sizeof(struct ifreq));



struct ifreq ifr;

SIOCGIFCONF返回系统中配置的所有接口的配置信息。
ioctl(fd, SIOCGIFCONF, (caddr_t)&ifc);



struct ifconf ifconf;

SIOCGSIZIFCONF

下面的代码段可以获取用来填充所有配置接口的信息所需的缓冲区大小。


清单 3. 使用 SIOCGSIZIFCONF 获得所需的缓冲区大小

				

/*Function to get the size needed to allocate for buffers*/

int get_interface_size(int sd){

    int ret,size;

    ret=ioctl(sd,SIOCGSIZIFCONF,&size);

    if(ret==-1){

       perror("Error getting size of interface :");

       return ret;

    }

    return size;

}



main

{

    struct ifconf ifc;

    int sd;

    sd=socket(AF_INET6,SOCK_DGRAM,0);

    printf("Size of memory needed = %d/n",get_interface_size(sd));

}

 

      

 

上面代码的输出是:

$> ./myprog

Size of memory needed = 628

      

 

SIOCGIFCONF 和 SIOCGIFADDR

SIOCGIFCONF 和 SIOCGIFADDR 命令可以用来检索接口的地址。SIOCGIFCONF 可以用来获取所有配置接口的信息,SIOCGIFADDR 可以用来检索特定接口的地址。


清单 4. 使用 SIOCGIFCONF 获取配置信息

					

/*This function uses loops to find out buffer size instead of SIOCGSIZIFCONF 

  allocates the buffer and gets the information list*/

int alloc_buffer_size(int sd,struct ifconf *ifc){

    int ret=-1,bsz=sizeof(struct ifreq);

    int prevsz=bsz;

    ifc->ifc_req=NULL;

    ifc->ifc_len=bsz;

    do{

       ifc->ifc_req=(struct ifreq *)realloc(ifc->ifc_req,bsz);

       if(!ifc->ifc_req){

         perror("Malloc failed :");

         return ret;

       }

       ifc->ifc_len=bsz;

       ret=ioctl(sd,SIOCGIFCONF,(caddr_t)ifc);

       if(ret==-1){

          perror("Error getting size of interface :");

          return ret;

       }

      if(prevsz==ifc->ifc_len)

        break;

      else{

         bsz*=2;

         prevsz=(0==ifc->ifc_len ? bsz : ifc->ifc_len) ;

      }

    }while(1);

    ifc->ifc_req=(struct ifreq *)realloc(ifc->ifc_req,prevsz);

    return ifc->ifc_len;

}



      

 

在使用 ifreq 结构中的配置信息填充了列表之后,可以对其进行遍历以检索所需的数据。根据调用之后该结构中填充的套接字地址的长度,可以对这个指针进行移动。下面的清单 5 显示了上面代码的列表中获得的系统中可用的 IP。


清单 5. 从配置列表中检索信息

					

#define MAX(x,y) ((x) > (y) ? (x) : (y))

#define SIZE(p) MAX((p).sa_len, sizeof(p))



/* This function prints all the configured IPs on the

 * system given the ifconf structure allocated previously*/

void print_ips(struct ifconf *ifc){

     char *cp,*cplim,addr[INET6_ADDRSTRLEN];

     struct ifreq *ifr=ifc->ifc_req;

     cp=(char *)ifc->ifc_req;

     cplim=cp+ifc->ifc_len;

     for(;cp<cplim;cp+=(sizeof(ifr->ifr_name) + SIZE(ifr->ifr_addr))){

        /* NOTE: You cannot just increment cp with sizeof(struct ifreq)

         * as structures returned are of different length.

         */

        ifr=(struct ifreq *)cp;

        printf("%s :",ifr->ifr_name);

        getip(ifr,addr);

        printf("%s/n",addr);

     }

      return ;

}

main

{

    struct ifconf ifc;

    int sd;

    sd=socket(AF_INET6,SOCK_DGRAM,0);

    alloc_buffer_size(sd,&ifc);

    print_ips(&ifc);

}

      

 

上面代码的输出是:

$> ./myprog

en0 :6.3.6.0

en0 :9.182.192.169

en0 :fe80::209:6bff:feeb:70b2

sit0 :1.4.4.0

sit0 :::9.182.192.169

lo0 :24.3.0.0

lo0 :127.0.0.1

lo0 :::1

      



清单 6. 使用 SIOCGIFADDR 获取接口地址

					

/* Given a ifreq structure this function returns its IP address */

void getip(struct ifreq *ifr,char *addr){

  struct sockaddr *sa;

  sa=(struct sockaddr *)&(ifr->ifr_addr);

  switch(sa->sa_family){

    case AF_INET6:

      inet_ntop(AF_INET6,(struct in6_addr *)&(((struct sockaddr_in6 *)sa)->sin6_addr),

         addr,INET6_ADDRSTRLEN);

      break;

    default : strcpy(addr,inet_ntoa(((struct sockaddr_in *)sa)->sin_addr));

    }

   return;

}



main

{

  char netaddr[INET_ADDRSTRLEN];

  int sd;

  sd=socket(AF_INET,SOCK_DGRAM,0);

  strcpy(ifr.ifr_name,"en0");

  if((ioctl(sd,SIOCGIFADDR,(caddr_t)&ifr,sizeof(struct ifreq)))<0)

     perror("Error : ");

  getip(&ifr,netaddr);

  printf("%s/n",netaddr);

}

      

 

上面代码的输出是:

$./myprog

9.182.192.35

      

 

下面的表 2 介绍了接口标志和一些属性检索命令。


表 2. 接口标志和属性检索命令

ioctl 命令描述
SIOCGIFFLAGS
                              
SIOCSIFFLAGS
                                   SIOCGIFFLAGS 可以获取接口标志。

                                   SIOCSIFFLAGS 可以设置接口标志。

                                   ioctl(fd, cmd, (caddr_t)&ifr);

                                   struct ifreq ifr;

SIOCGIFFLAGS

在使用 SIOCGIFCONF 获取了接口列表之后,您可以使用 SIOCGIFFLAGS-SIOCSIFFLAGS 对来获取和设置接口的属性。接口标志表示为 IFF_XXX。有关完整的列表,请参阅文件 /usr/include/net/if.h。

下面的示例使用一对接口标志来检索其当前状态,并检查环回。也可以使用其他选项。


清单 7. 验证接口的状态和类型

				

   for(;cp<cplim;){

        ifr=(struct ifreq *)cp;

        cp+=(sizeof(ifr->ifr_name) + SIZE(ifr->ifr_addr));

        printf("%-9s  ",ifr->ifr_name);

        ret=ioctl(sd,SIOCGIFFLAGS,(caddr_t)ifr);

        if(ret==-1){

          perror("Error getting flags for interface :");

          return ;

        }

        if((ifr->ifr_flags)&IFF_UP)

           printf("UP");

        else printf("DOWN");

        if((ifr->ifr_flags)&IFF_LOOPBACK)

           printf(",Loopback");

	printf("/n");

     }

      

 

上面代码的输出是:

$> ./myprog

en0        UP

en0        UP

en0        UP

sit0       UP

sit0       UP

lo0        UP,Loopback

lo0        UP,Loopback

lo0        UP,Loopback

      



清单 8. 设置接口标志

				

	Partial output of ifconfig before setting the flag




sit0: flags=4900041<UP,RUNNING,LINK0,64BIT>

        inet6 ::9.182.192.169/96



Code to set the interface flag 




int set_interface_flag(int sd,short flag,char *interface){

    struct ifreq ifr;

    int oldflags;

    strcpy(ifr.ifr_name,interface);

    if((ioctl(sd,SIOCGIFFLAGS,(caddr_t)&ifr))==-1){

      perror("Error getting interface flags :");

      return -1;

    }

    printf("Setting new interface flag 0X%x/n",flag);

    ifr.ifr_flags|=flag;

    if((ioctl(sd,SIOCSIFFLAGS,(caddr_t)&ifr))==-1){

      perror("Error setting interface flags :");

      return -1;

    }

    return 0;

}



main

{

    int sd;

    sd=socket(AF_INET6,SOCK_DGRAM,0);

    set_interface_flag(sd,IFF_NOTRAILERS,"sit0");

}

 

上面代码的输出是:

You must have permission to change the flag




$./myprog

Setting new interface flag 0X20



$ifconfig -a

.............

.............

sit0: flags=4900061<UP,NOTRAILERS
,RUNNING,LINK0,64BIT>

        inet6 ::9.182.192.169/96

.............

.............

      

 

表 3 介绍了一些用于网络优化的命令。


表 3. 用于网络优化的命令

ioctl 命令描述
SIOCGIFMTUSIOCGIFMTU 可以获取接口的最大传输单元 (MTU)。

 

ioctl(fd, cmd, (caddr_t)&ifr);



struct ifreq ifr;

这个 MTU 值存储在 ifr.ifr_mtu 字段中。
SIOCGNETOPT
SIOCGNETOPT1
SIOCGNETOPT 可以获取一个网络选项的值。

 

ioctl(fd, cmd, (caddr_t)&oreq);

struct optreq oreq;

SIOCGNETOPT1 可以获取当前值、缺省值和网络选项的范围。

 

ioctl(fd, SIOCGNETOPT1, (caddr_t)&oreq);

struct optreq1 oreq;

SIOCGIFMTU


清单 9. 从 ifreq 结构获取 MTU

				

        ret=ioctl(sd,SIOCGIFMTU,ifr);

        if(ret==-1){

          perror("Error getting mtu for interface :");

          return ;

        }

        printf("  %d/n",ifr->ifr_mtu);

      

 

SIOCGNETOPT1

SIOCGNETOPT1 给出当前值、缺省值和网络选项的范围。


清单 10. 从 optreq1 结构获取网络选项

				

/*Function to get the network options*/

int print_network_options(int sd){

    int ret;

    struct optreq1 oreq;

    oreq.getnext=1;

    while((ioctl(sd,SIOCGNETOPT1,(caddr_t)&oreq))!=-1)

    printf("%s = %s/n",oreq.name,oreq.data);

   return 0;

}

      

 

上面代码的输出是:

$> ./myprog

arpqsize = 12

arpt_killc = 20

arptab_bsiz = 7

arptab_nb = 149

........

........

........

........

ifsize = 256

inet_stack_size = 16

ip6_defttl = 64

........

      

 

在 AIX 中,您还可以使用 no 命令来管理各种网络优化参数。有关更详细的信息,请参阅相应的 man 页面。


清单 11. AIX 计算机上“no”命令的输出
$> no -a|more arpqsize = 12 arpt_killc = 20 arptab_bsiz = 7 arptab_nb = 149 bcastping = 0 clean_partial_conns = 0 delayack = 0 delayackports = {} dgd_packets_lost = 3 dgd_ping_time = 5 dgd_retry_time = 5 directed_broadcast = 0 extendednetstats = 0 fasttimo = 200........

四、小结


ioctl 命令的功能非常强大,您可以使用它们来访问或修改网络(或其他)设备的可配置参数。它们使用了各种各样的数据结构,应该使用正确的数据来填充这些数据结构,以便实现预期的结果。
ioctl compat_ioctl unlock_ioctl <br />区别:<br />ioctl 和 unlock_ioctl <br />ioctl 不会lock_kernel()<br /> <br />compat_ioctl被使用在用户空间为32位模式,而内核运行在64位模式时。这时候,需要将64位转成32位。<br /> <br />引用<br />http://blog.chinaunix.net/u1/38994/showart_2248151.html<br />对几个ioctl执行顺序的分析<br /> <br />关于ioctl,unlock 阅读详情

相关推荐

ioctl调用不执行问题的解决

在驱动开发中,ioctl是很常用的应用层与内核通信的接口,今天调试过程中遇到一个ioctl调用不执行的问题,有点意思,写篇博客记录一下。 对于网络设备,内核通过宏SIOCDEVPRIVATE给各个设备预留了一组私有ioctl命令,驱动可以自行定义响应函数来执行相应的操作。今天接到一个需求,要在驱动里添加一个清空用户统计信息的功能,于是相应的就需要增加一个ioctl命令供应用层调用。看了驱动代

ringrang的专栏 8538

ioctl函数

ioctl函数的概念、意义和用法

zhaoli_1956的专栏 1536

linux ioctl的使用

ioctl iocl命令 和幻数 内核传参 功能号

菜鸡搞计算机 593

嵌入式linux修改串口缓冲区大小

include/linux/serial_core.h ... #define UART_XMIT_SIZE PAGE_SIZE ... include/generated/asm-offsets.h ... #define PAGE_SIZE 4096 ...

锅锅的博客 1万+

linux ioctl及ioctl command

在linux驱动中经常用到的函数为open、read、write用于对设备进行读取和写入数据,但是除了上述功能之外还有另外一个重要的功能ioctl,很多时候用户程序需要根据自己的需求配置所操纵的硬件,比如修改波特兰,获取设备信息等,可以通过ioctl方法来进行与该设备的驱动进行交互,ioctl是在用户层可以之间与内核驱动打交道最直接的方式,但是其自身也有一些缺点。 ioctl整个可以分为用户和内核两个部分。 系统调用ioctl 用户层主要是通过使用ioctl系统调用函数来直接控制设备相关配置,可以使用

weixin_42730667的博客 1666

从FinFET到GAA:手把手解读2nm芯片制造的关键技术(含BSPDN避坑指南)

本文深入解读了2nm芯片制造从FinFET向全环绕栅极(GAA)晶体管架构演进的核心技术,并重点剖析了背面供电网络(BSPDN)的三种实现路径及其工程挑战。文章旨在帮助工程师理解技术变革的内在逻辑,并为应对2nm节点设计中的关键问题提供实用指南。

weixin_29294975的博客 292

linux串口缓冲区的大小,linux-----------串口设置缓冲器的大小

You want to use the serial IOCTLTIOCSSERIALwhich allows changing both receive buffer depth and send buffer depth (among other things). The maximums depend on your hardware, but if a 16550A is in pla...

weixin_29467909的博客 2146

ZED2双目相机运行VINS-FUSION初试

基于ZED2运行VINS-MONO的经验,在运行VINS-FUSION前有几点tips想跟大家分享,应该能在运行的过程中避免一些踩坑吧。 TIPs 1)关于zed2标定 开始使用Kalibr进行相机单目/双目及联合标定,虽然重投影误差最高也就5个像素,但实际使用效果却并不好,故建议大家相机内参还是从ZED2相机发布出的topic获取或可尝试/usr/local/zed/settings文件下的参数文档 另,启动ZED2.launch的时候,会有一个相机(一般是左目)和IMU的轴系转换关系Camera-IMU

xiaojinger_123的博客 5355

串口环形缓冲区

串口环形缓冲区应用于嵌入式、物联网开发时,当串口接收数据量过大,此时MCU来不及处理而设计的一套算法,将接收的数据存入一个数组,等待空闲时再做处理。

小途的博客 3544

二维“能量源”(电场、磁场、功率)入射边界设置方法

comsol光学仿真设计相关学习笔记和经验 1. 二维“能量源”(电场、磁场、功率)入射边界设置方法 2.边界条件设置薄膜材料

VJCP_90909Bu0的博客 5192

【数据集4】GSWP3数据集详解

简介GSWP3数据集

WW、forever的博客 1366

【Linux】ioctl()方法

应该在专用头文件中生成自己的ioctl编号,这不是强制性的,但建议这样做,因为这个头文件在用户空间中也可以使用。换句话说,应该复制ioctl头文件,以便在内核中有一个,在用户空间中也有一个,该文件可以包含在用户应用程序中。系统内ioctl号码的唯一性可以防止把正确的命令发送到错误的设备,或者将错误的参数传递给正确的命令(给出重复的ioctl号码)。在Documentation/ioctl/ioctl-number.txt中列出,需要创建ioctl命令时,这是一个很好的开始。使用switch …

pannlz的博客 1896

华为OD机试 - 打印机队列 - 优先队列(Python/JS/C/C++ 双机位C卷 200分)

这个问题要求模拟打印机的文件调度过程,关键在于正确处理每个打印机队列中的文件优先级和文件进入队列的顺序。优先级处理:每个文件有一个 1 到 10 的优先级,数字越大优先级越高,打印机应首先处理优先级最高的文件。在打印机 1 的队列中插入了 3 个文件,分别有不同的优先级,其中编号 3 的文件优先级最高,先被取出。因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10 不同的 优先级,其中数字越大优先级越高。在打印机 2 的队列中插入了 1 个文件,优先级为 1,因此它被首先取出。

学Java,找哪吒 1079

Linux驱动开发—ioctl命令构成,设备驱动基础使用ioctl详解

ioctl(输入/输出控制)是一种系统调用,用于设备驱动程序与用户空间应用程序之间进行设备特定的输入/输出操作。它通常用于对设备执行标准文件操作(如读取、写入、打开和关闭)之外的特殊操作。ioctl提供了一种通用的机制,通过文件描述符与设备进行交互,支持各种类型的设备操作和控制。ioctl定义命令和参数:设备驱动程序和用户空间应用程序之间的交互是通过命令和参数来实现的。命令通常是一个宏,表示特定的操作,而参数则是传递给驱动程序的数据。调用ioctl系统调用:用户空间应用程序通过文件描述符调用ioctl。

weixin_46999174的博客 6077

ChatGPT充值,银行卡被拒绝,图文教程

ChatGPT充值,银行卡被拒绝

weixin_46713695的博客 2万+

基于STM32L4XX、HAL库的TESEO-LIV4FTR定位模块驱动程序设计

支持多星座系统:GPS、GLONASS、Galileo和北斗。支持NMEA 0183协议和ST专有协议。高灵敏度:-167dBm跟踪灵敏度。低功耗设计,适合物联网和便携设备。内置LNA和SAW滤波器。

zhusl6688的博客 237

比较:unlocked_ioctl、compat_ioctl

compat_ioctl:支持64bit的driver必须要实现的ioctl,当有32bit的userspace application call 64bit kernel的IOCTL的时候,这个callback会被调用到。如果没有实现compat_ioctl,那么32位的用户程序在64位的kernel上执行ioctl时会返回错误:Not a typewriter 。 如果是64位的用户程序运行在64位的kernel上,调用的是unlocked_ioctl,如果是32位的APP运行在32位的kernel上

Golden_Chen的专栏 3077

借助AI高效写出结构严谨、内容专业的课题申报书:10大核心模块拆解(附实用提示词)

在很多老师和科研人员眼中,写一份高质量的课题申报,确实是一件非常困难的事。难就难在不只是要说清楚写了什么研究内容,还要体现申报书的可行性和创新性。七哥除了自己写课题,也经常指导会员同仁使用高级学术版搞定课题的申报工作,摸索出了一套行之有效的借助AI申报课题的技巧,在这篇文章中,我将给大家点明课题申报书的10大核心模块的写作技巧,还会给大家一些提示词模板供大家参考,如果你也正准备申报课题,那么这篇文章一定不要错过!特别说明的是,提示词的使用并不是一蹴而就的,是专业思考的延伸和AI化专业表达,过程中需要多次的调

智能AI让学术科研更容易 441

Linux下ioctl的应用

Linux下ioctl的应用

CATTLE_L的博客 1388

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

windows ioctl

Windows IOCTL Reference | Extracted from DDK 7.1.0 | Entries: 760 | Quick Filter  Ioctl Hex Value Header Brief IOCTL_1394_CLASS 0x22021d inc\ddk\1394.h An

anna的专栏 8546

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

ioctl系统调用

先mark一下: https://www.cnblogs.com/lifexy/p/10289491.html https://www.cnblogs.com/tdyizhen1314/p/4896689.html https://blog.youkuaiyun.com/dayancn/article/details/52953777 https://www.cnblogs.com/sky-heaven/archive/2019/11/27/11940638.html ioctl内核实现的地方: //\l

hhhhhyyyyy8的博客 2466

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

nvme ioctl解密

对于Nvme SSD,我们有的时候会用到ioctl系统调用,该调用的流程是怎样的呢? 首先,在注册nvme设备的时候,会初始化该设备的注册了file operations: static const struct file_operations nvme_dev_fops = { .owner = THIS_MODULE, .open = n...

weixin_30855761的博客 1950

ioctl 函数

用户空间可以将命令通过ioctl系统调用的方式传给内核,从而实现配置某事或者倾卸某事的任务,网络代码使用ioctl的方式就是传递套接字描述符和相应的命令。我们熟悉的ifconfig命令就是利用ioctl与内核通信。      下面是一个简单的程序。 #include #include #include #include #include #include #include #include #

博观约取 1350

linux驱动之ioctl详解

字符设备驱动中ioctl的使用

qq_40684669的博客 2822

关于ioctl,unlocked_ioctl和compat_ioctl执行的顺序

关于ioctl,unlocked_ioctl和compat_ioctl执行的顺序 对于ioctl操作,优先执行f_op->unlocked_ioctl,如果没有unlocked_ioctl,那么执行f_op->ioctl sys_ioctl ==> vfs_ioctl ==> file_ioctl ==> do_ioctl static long do_ioctl(s...

Gick 1018
上一篇: PKU 1389 Area of Simple Polygons
下一篇: PKU 2104 K-th Number
Mei废话
博客等级 码龄14年 5粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值