linux - How to identify GPIO pin numbers? Is GPIO driver loaded? - Unix & Linux Stack Exchange
update:2021-11-9
My system: CPU Version: Intel(R) Celeron(R) CPU J1900 @ 1.99GHz

At some point I figured that this implements the IT8786 Chip.

If you check your Kernel Configuration, you might find support for the IT87x family of drivers (under GPIO Drivers of course). In my case this was only enable as a Module.

Then, I loaded the module with:

sudo insmod /lib/modules/5.8.0-55-generic/kernel/drivers/gpio/gpio-it87.ko
dmesg returned the following item:

gpio_it87: Found Chip IT8786 rev 2. 64 GPIO lines starting at 0a00h
By checking /dev, gpiochip0 appeared and from there on you can use the already mentioned sysfs method if you wish so (although in retirement).

If you don't know how to relate the physical pins to the hardware, then try this:

apt-get install gpiod
Running gpioinfo returns in my case the following:

gpiochip0 - 64 lines:

    line   0:  "it87_gp10"       unused   input  active-high
    line   1:  "it87_gp11"       unused   input  active-high
    line   2:  "it87_gp12"      "sysfs"   input  active-high [used]
    line   3:  "it87_gp13"       unused   input  active-high
    line   4:  "it87_gp14"       unused   input  active-high
    line   5:  "it87_gp15"       unused   input  active-high
    line   6:  "it87_gp16"       unused   input  active-high
    line   7:  "it87_gp17"       unused   input  active-high
    line   8:  "it87_gp20"       unused   input  active-high
    line   9:  "it87_gp21"       unused   input  active-high
    line  10:  "it87_gp22"       unused   input  active-high
    line  11:  "it87_gp23"       unused   input  active-high
    line  12:  "it87_gp24"      "sysfs"   input  active-high [used]
    line  13:  "it87_gp25"       unused   input  active-high
    line  14:  "it87_gp26"       unused   input  active-high
    line  15:  "it87_gp27"       unused   input  active-high
    line  16:  "it87_gp30"       unused   input  active-high
    line  17:  "it87_gp31"       unused   input  active-high
    line  18:  "it87_gp32"       unused   input  active-high
    line  19:  "it87_gp33"       unused   input  active-high
    line  20:  "it87_gp34"       unused   input  active-high
    line  21:  "it87_gp35"       unused   input  active-high
    line  22:  "it87_gp36"      "sysfs"  output  active-high [used]
    line  23:  "it87_gp37"       unused   input  active-high
    line  24:  "it87_gp40"       unused   input  active-high
    line  25:  "it87_gp41"       unused   input  active-high
    line  26:  "it87_gp42"       unused   input  active-high
    line  27:  "it87_gp43"       unused   input  active-high
    line  28:  "it87_gp44"       unused   input  active-high
    line  29:  "it87_gp45"       unused   input  active-high
    line  30:  "it87_gp46"       unused   input  active-high
    line  31:  "it87_gp47"       unused   input  active-high
    line  32:  "it87_gp50"       unused   input  active-high
    line  33:  "it87_gp51"       unused   input  active-high
    line  34:  "it87_gp52"       unused   input  active-high
    line  35:  "it87_gp53"       unused   input  active-high
    line  36:  "it87_gp54"       unused   input  active-high
    line  37:  "it87_gp55"       unused   input  active-high
    line  38:  "it87_gp56"       unused   input  active-high
    line  39:  "it87_gp57"       unused   input  active-high
    line  40:  "it87_gp60"       unused   input  active-high
    line  41:  "it87_gp61"       unused   input  active-high
    line  42:  "it87_gp62"       unused   input  active-high
    line  43:  "it87_gp63"       unused   input  active-high
    line  44:  "it87_gp64"       unused   input  active-high
    line  45:  "it87_gp65"       unused   input  active-high
    line  46:  "it87_gp66"       unused   input  active-high
    line  47:  "it87_gp67"       unused   input  active-high
    line  48:  "it87_gp70"       unused   input  active-high
    line  49:  "it87_gp71"       unused   input  active-high
    line  50:  "it87_gp72"       unused   input  active-high
    line  51:  "it87_gp73"      "sysfs"   input  active-high [used]
    line  52:  "it87_gp74"      "sysfs"  output  active-high [used]
    line  53:  "it87_gp75"      "sysfs"   input  active-high [used]
    line  54:  "it87_gp76"      "sysfs"   input  active-high [used]
    line  55:  "it87_gp77"       unused   input  active-high
    line  56:  "it87_gp80"       unused   input  active-high
    line  57:  "it87_gp81"       unused  output  active-high
    line  58:  "it87_gp82"       unused   input  active-high
    line  59:  "it87_gp83"       unused   input  active-high
    line  60:  "it87_gp84"       unused   input  active-high
    line  61:  "it87_gp85"       unused   input  active-high
    line  62:  "it87_gp86"       unused   input  active-high
    line  63:  "it87_gp87"       unused   input  active-high

You can use the utilities of gpiod to work with the different pins. If your manufacturer has in some way indicated which GPI/O you can use, then you can related the "line" to the it87_gpXX" part, being XX the pins probably provided by the manufacturer.

A quick check can be done on the old way.

Go to /sys/class/gpio and see what gpiochip you find. The base number inside the gpiochip is the start position and the line points returned by gpioinfo the offset.

In my case I had 448 as base. If I want to reach GP81, that is line 57, so I would do this:

echo 505 > /sys/class/gpio/export
I hope this helps! It saved me from writing the Driver (By the way, the manufacturer sent me a driver but it didn't work)
Referenced from:https://unix.stackexchange.com/questions/485324/how-to-identify-gpio-pin-numbers-is-gpio-driver-loaded

安装:

sudo apt-get install imagemagick

convert id.pdf id.jpeg
convert id.pdf id.png
convert -density 200 id.pdf id.jpg

The simplest command to do the task is ...

$ convert demo.pdf demo.jpg

If the pdf file has multiple pages then imagemagick shall create multiple image files named as demo-1.jpg, demo-2.jpg ... and so on for all pages in the pdf file.
To convert only a particular page from the pdf file use the following command

$ convert demo.pdf[2] demo.jpg

Creating PDF Thumbnail
To create thumbnail, the image just needs to be scaled down using either of the 'scale', 'thumbnail' or 'resize' option.

Here is a quick example.

$ convert -thumbnail x300 demo.pdf[2] demo.jpg

If the pdf has transparency then scaling might result into an image where all white areas turn into black. To fix this the 'flatten' option can be used as follows

$ convert -thumbnail x300 demo.pdf[2] -flatten demo.jpg

The above command shall put a white background in the transparent areas.

  1. Clearer Text and Higher Resolution
    Using the above command you might notice that the text in the resulting image is not clear or sharp. This can be fixed using the 'density' option.

Use a value of around 175 and the text should become clearer than before. Experiment with the value till the desired level of sharpness is achieved.

$ convert -density 200 demo.pdf[2] demo.jpg
  1. Create gif animation of all pages
    Imagemagick can even create a gif animation of all the pages of the pdf. Its as simple as the following command
$ convert -thumbnail x300 -delay 100 demo.pdf demo.gif

The delay parameter defines the delay of animation.

  1. Quality/compression for jpg
    The quality or compression level of jpg images can be specified using the 'quality' option
$ convert demo.pdf[0] -scale x800 -quality 75  -flatten demo75.jpg

linux下在用户空间访问I/O端口的ioperm和iopl函数
    Linux下设置端口权限的系统调用有两个:ioperm和iopl函数。
1.ioperm函数
     功能描述:
为调用进程设置I/O端口访问权能。ioperm的使用需要具有超级用户的权限,只有低端的[0-0x3ff] I/O端口可被设置,要想指定更多端口的权能,可使用iopl函数。这一调用只可用于i386平台。

用法:

include  / for libc5 /

include  / for glibc /

int ioperm(unsigned long from, unsigned long num,
int turn_on);
      
参数:
from:起始端口地址。
num:需要修改权能的端口数。
turn_on:端口的新权能位。1为开启,0为关闭。
返回说明: 
成功执行时,返回0。失败返回-1,errno被设为以下的某个值 
EINVAL:参数无效
EIO:这一调用不被支持
EPERM:调用进程权能不足。
   
2.iopl函数
功能描述:该调用用于修改当前进程的操作端口的权限。可以用于所有65536个端口的权限。因此,ioperm相当于该调用的子集。和ioperm一样,这一调用仅适用于i386平台。

用法:

include 

   int
iopl(int level);
参数:
level: 端口的权限级别。为3时可以读写端口。默认权能级别为0,用户空间不可读写。
返回说明:成功执行时,返回0。失败返回-1,errno被设为以下的某个值
EINVAL:level值大于3
ENOSYS:未实现该调用
EPERM:调用进程权能不足。
Referenced from:https://blog.csdn.net/chdhust/article/details/8142141

IP和TCP头校验和计算算法
update:2021-11-9
◆◆当发送IP包时,需要计算IP报头的校验和:

1、  把校验和字段置为0;

2、  对IP头部中的每16bit进行二进制求和;

3、  如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit为0,从而获得一个16bit的值;

4、  将该16bit的值取反,存入校验和字段。

◆◆当接收IP包时,需要对报头进行确认,检查IP头是否有误:

算法同上2、3步(不需要将校验和字段置0),然后判断取反的结果是否为0,是则正确,否则有错。

◆◆算法:

SHORT checksum(USHORT* buffer, int size)

{
unsigned long cksum = 0;

//每16位相加

while(size>1)

{
    cksum += *buffer++;

    size -= sizeof(USHORT);

}

//最后的奇数字节

if(size)

{
    cksum += (UCHAR)buffer;

}

cksum = (cksum>>16) + (cksum&0xffff);  //将高16bit与低16bit相加

cksum += (cksum>>16);                             //将进位到高位的16bit与低16bit 再相加,确保高16位为0

return (USHORT)(~cksum); //最后将结果取反,得到checksum

}

 

◆◆实例:

IP头:  

              45 00    00 31

              89 F5    00 00

              6E 06    00 00(校验字段置0)

              DE B7   45 5D     ->    222.183.69.93

              C0 A8   00 DC     ->    192.168.0.220

计算(IP头20字节):   

    4500 + 0031 +89F5 + 0000 + 6e06+ 0000 + DEB7 + 455D + C0A8 + 00DC =3 22C4   //每16bit二进制求和

    0003 + 22C4 = 22C7   //高16bit和低16bit反复相加,直到高16位为0

     ~22C7 = DD38            //即为应填充的校验和

当接受到IP数据包时,要检查IP头是否正确,则对IP头进行检验,方法同上(校验和字段不需要置0):

计算:

    4500 + 0031 +89F5 + 0000 + 6E06+ DD38 + DEB7 + 455D + C0A8 + 00DC =3 FFFC   //每16bit二进制求和

    0003 + FFFC = FFFF         //高16bit和低16bit反复相加,直到高16位为0

     ~FFFF = 00000                  //正确

TCP首部检验和与IP首部校验和的计算方法相同,在程序中使用同一个函数来计算。
需要注意的是,由于TCP首部中不包含源地址与目标地址等信息,为了保证TCP校验的有效性,在进行TCP校验和的计算时,需要增加一个TCP伪首部的校验和,定义如下:

struct 
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz; //强制置空
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}psd_header;

然后我们将这两个字段复制到同一个缓冲区SendBuf中并计算TCP校验和:
memcpy(SendBuf, &psd_header, sizeof(psd_header)); 
memcpy(SendBuf+sizeof(psd_header), &tcp_header, sizeof(tcp_header));
tcp_header.th_sum=checksum((USHORT *)SendBuf, sizeof(psd_header)+sizeof(tcp_header));
Referenced from:https://blog.csdn.net/jiangqin115/article/details/39313689

IPv4头部结构
  以IPv4版本的IP协议为例,分析其头部信息:
  IPv4的头部结构长度为20字节,若含有可变长的选项部分,最多60字节。

(1) 版本号:IP协议的版本。对于IPv4来说值是4
  (2) 头部长度:4位最大为0xF,注意该字段表示单位是字(4字节)
  (3) 服务类型(Type Of Service,TOS):3位优先权字段(现已被忽略) + 4位TOS字段 + 1位保留字段(须为0)。4位TOS字段分别表示最小延时、最大吞吐量、最高可靠性、最小费用,其中最多有一个能置为1。应用程序根据实际需要来设置 TOS值,如ssh和telnet这样的登录程序需要的是最小延时的服务,文件传输ftp需要的是最大吞吐量的服务
  (4) 总长度: 指整个IP数据报的长度,单位为字节,即IP数据报的最大长度为65535字节(2的16次方)。由于MTU的限制,长度超过MTU的数据报都将被分片传输,所以实际传输的IP分片数据报的长度远远没有达到最大值

  下来的3个字段则描述如何实现分片:
  (5) 标识:唯一地标识主机发送的每一个数据报,其初始值是随机的,每发送一个数据报其值就加1。同一个数据报的所有分片都具有相同的标识值
  (6) 标志: 位1保留,位2表禁止分片(DF),若设置了此位,IP模块将不对数据报进行分片,在此情况下若IP数据报超过MTU,IP模块将丢弃数据报并返回一个ICMP差错报文;位3标识更多分片(MF),除了数据报的最后一个分片,其他分片都要把它设置为1
  (7) 位偏移:分片相对原始IP数据报数据部分的偏移。实际的偏移值为该值左移3位后得到的,所以除了最后一个IP数据报分片外,每个IP分片的数据部分的长度都必须是8的整数倍

  (8) 生存时间::数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置,常设置为64。数据报在转发过程中每经过一个路由该值就被路由器减1.当TTL值为0时,路由器就将该数据包丢弃,并向源端发送一个ICMP差错报文。TTL可以防止数据报陷入路由循环
  (9) 协议: 区分IP协议上的上层协议。在Linux系统的/etc/protocols文件中定义了所有上层协议对应的协议字段,ICMP为1,TCP为6,UDP为17
  (10) 头部校验和: 由发送端填充接收端对其使用CRC算法校验,检查IP数据报头部在传输过程中是否损坏
  (11) 源IP地址和目的IP地址: 表示数据报的发送端和接收端。一般情况下这两个地址在整个数据报传递过程中保持不变,不论中间经过多少个路由器
  (12) 选项:可变长的可选信息,最多包含40字节。选项字段很少被使用。

执行telnet命令登录本机,并在另一终端抓取这个过程中telnet服务器-telnet客户端之间的数据包:

$ sudo tcpdump -ntx -i lo

  在另一终端:

$ telnet 127.0.0.1

  观察tcpdump抓取到的数据:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
IP 127.0.0.1.44626 > 127.0.0.1.23: Flags [S], seq 3041640326, win 43690, options [mss 65495,sackOK,TS val 4701824 ecr 0,nop,wscale 7], length 0

0x0000:  4510 003c 0106 4000 4006 3ba4 7f00 0001
0x0010:  7f00 0001 ae52 0017 b54b bf86 0000 0000
0x0020:  a002 aaaa fe30 0000 0204 ffd7 0402 080a
0x0030:  0047 be80 0000 0000 0103 0307

  这是一个IP数据报:
  (1) telnet登录的是本机,所以IP数据报的源端IP地址和目的端IP地址都是127.0.0.1。telnet服务器使用的端口号是23,

  telnet客户端使用的是临时端口号44626。telnet服务使用的是TCP协议,Flags、sq、win、options描述的都是TCP头部信息,详细将在TCP协议分析中解析。

  (2) tcpdump命令开启-x选项,使之输出二进制码。这些二进制码用十六进制的格式呈现,共60字节: 前20字节是IP头部,后40字节是TCP头部。length为0表示这些数据不包含数据。

  对照前面表格的IPv4,可得各数据取值意义如下:

0x4             4位的版本号                      IP版本号
0x5             4位的头部长度                 头部长度为5个字(20字节)
0x10            8位的服务类型TOS              开启最小延时服务
0x003c          16位的总长度                 数据包总长度(60字节)

0x0106          16位的标识                      数据报标识
0x4             3位的标志                       禁止分片,因没携带数据

0x000           13位的位偏移                 为0表没发生位偏移
0x40            8位的生存时间                 生存时间为64跳
0x06            8位的协议字段                 为6表上层协议是TCP协议

0x3ba4          16位的IP头部校验和             头部校验和

0x7f00 0001     32位的源端IP地址              源端IP地址127.0.0.1
0x7f00 0001     32位的目的端IP地址             目的端IP地址127.0.0.1

Referenced from:https://blog.csdn.net/qq_29344757/article/details/78570272