V4l2的結構體 --- ioctl【轉】

来源:http://www.cnblogs.com/linhaostudy/archive/2017/09/26/7595675.html
-Advertisement-
Play Games

在應用程式獲取視頻數據的流程中,都是通過 ioctl 命令與驅動程式進行交互,常見的 ioctl 命令有: 1 VIDIOC_QUERYCAP /* 獲取設備支持的操作 */ 2 VIDIOC_G_FMT /* 獲取設置支持的視頻格式 */ 3 VIDIOC_S_FMT /* 設置捕獲視頻的格式 * ...


 

在應用程式獲取視頻數據的流程中,都是通過 ioctl 命令與驅動程式進行交互,常見的 ioctl 命令有:

 1 VIDIOC_QUERYCAP     /* 獲取設備支持的操作 */
 2 VIDIOC_G_FMT        /* 獲取設置支持的視頻格式 */
 3 VIDIOC_S_FMT        /* 設置捕獲視頻的格式 */
 4 VIDIOC_REQBUFS      /* 向驅動提出申請記憶體的請求 */
 5 VIDIOC_QUERYBUF     /* 向驅動查詢申請到的記憶體 */
 6 VIDIOC_QBUF         /* 將空閑的記憶體加入可捕獲視頻的隊列 */
 7 VIDIOC_DQBUF        /* 將已經捕獲好視頻的記憶體拉出已捕獲視頻的隊列 */
 8 VIDIOC_STREAMON     /* 打開視頻流 */
 9 VIDIOC_STREAMOFF    /* 關閉視頻流 */
10 VIDIOC_QUERYCTRL    /* 查詢驅動是否支持該命令 */
11 VIDIOC_G_CTRL       /* 獲取當前命令值 */
12 VIDIOC_S_CTRL       /* 設置新的命令值 */
13 VIDIOC_G_TUNER      /* 獲取調諧器信息 */
14 VIDIOC_S_TUNER      /* 設置調諧器信息 */
15 VIDIOC_G_FREQUENCY  /* 獲取調諧器頻率 */
16 VIDIOC_S_FREQUENCY  /* 設置調諧器頻率 */

 

 

1、struct v4l2_capability 與 VIDIOC_QUERYCAP

VIDIOC_QUERYCAP 命令通過結構 v4l2_capability 獲取設備支持的操作模式:

1 struct v4l2_capability {
2     __u8    driver[16];     /* i.e. "bttv" */
3     __u8    card[32];       /* i.e. "Hauppauge WinTV" */
4     __u8    bus_info[32];   /* "PCI:" + pci_name(pci_dev) */
5     __u32   version;        /* should use KERNEL_VERSION() */
6     __u32    capabilities;   /* Device capabilities */
7     __u32    reserved[4];
8 };

其中域 capabilities 代表設備支持的操作模式,常見的值有 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING 表示是一個視頻捕捉設備並且具有數據流控制模式;另外 driver 域需要和 struct video_device 中的 name 匹配。

 

2、struct v4l2_format 與 VIDIOC_G_FMT、VIDIOC_S_FMT、VIDIOC_TRY_FMT

通常用 VIDIOC_S_FMT 命令通過結構 v4l2_format 初始化捕獲視頻的格式,如果要改變格式則用 VIDIOC_TRY_FMT 命令:

 1 struct v4l2_format {
 2     enum v4l2_buf_type type;
 3     union {
 4         struct v4l2_pix_format         pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
 5         struct v4l2_window             win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
 6         struct v4l2_vbi_format         vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
 7         struct v4l2_sliced_vbi_format  sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
 8         __u8   raw_data[200];                   /* user-defined */
 9     } fmt;
10 };
11 其中
12 enum v4l2_buf_type {
13     V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,
14     V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,
15     V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,
16     ...
17     V4L2_BUF_TYPE_PRIVATE              = 0x80,
18 };
19 
20 struct v4l2_pix_format {
21     __u32                   width;
22     __u32                   height;
23     __u32                   pixelformat;
24     enum v4l2_field         field;
25     __u32                   bytesperline;   /* for padding, zero if unused */
26     __u32                   sizeimage;
27     enum v4l2_colorspace    colorspace;
28     __u32                   priv;           /* private data, depends on pixelformat */
29 };

 

 常見的捕獲模式為 V4L2_BUF_TYPE_VIDEO_CAPTURE 即視頻捕捉模式,在此模式下 fmt 聯合體採用域 v4l2_pix_format:其中 width 為視頻的寬、height 為視頻的高、pixelformat 為視頻數據格式(常見的值有 V4L2_PIX_FMT_YUV422P | V4L2_PIX_FMT_RGB565)、bytesperline 為一行圖像占用的位元組數、sizeimage 則為圖像占用的總位元組數、colorspace 指定設備的顏色空間。

 

3、struct v4l2_requestbuffers 與 VIDIOC_REQBUFS

VIDIOC_REQBUFS 命令通過結構 v4l2_requestbuffers 請求驅動申請一片連續的記憶體用於緩存視頻信息:

 1 struct v4l2_requestbuffers {
 2     __u32                   count;
 3     enum v4l2_buf_type      type;
 4     enum v4l2_memory        memory;
 5     __u32                   reserved[2];
 6 };
 7 其中
 8 enum v4l2_memory {
 9     V4L2_MEMORY_MMAP             = 1,
10     V4L2_MEMORY_USERPTR          = 2,
11     V4L2_MEMORY_OVERLAY          = 3,
12 };

count 指定根據圖像占用空間大小申請的緩存區個數,type 為視頻捕獲模式,memory 為記憶體區的使用方式。

 

4、struct v4l2_buffer與 VIDIOC_QUERYBUF

VIDIOC_QUERYBUF 命令通過結構 v4l2_buffer 查詢驅動申請的記憶體區信息:

 1 struct v4l2_buffer {
 2     __u32                   index;
 3     enum v4l2_buf_type      type;
 4     __u32                   bytesused;
 5     __u32                   flags;
 6     enum v4l2_field         field;
 7     struct timeval          timestamp;
 8     struct v4l2_timecode    timecode;
 9     __u32                   sequence;
10 
11     /* memory location */
12     enum v4l2_memory        memory;
13     union {
14             __u32           offset;
15             unsigned long   userptr;
16     } m;
17     __u32                   length;
18     __u32                   input;
19     __u32                   reserved;
20 };

 

5、enum v4l2_buf_type 與 VIDIOC_STREAMON、VIDIOC_STREAMOFF

 這兩個命令使用的只是一個整形數據,即 v4l2_buf_type,一般只要指定其值為 V4L2_BUF_TYPE_VIDEO_CAPTURE 即可。

 

6、struct v4l2_queryctrl 與 VIDIOC_QUERYCTRL

VIDIOC_QUERYCTRL 命令通過結構 v4l2_queryctrl 查詢驅動是否支持該 id 代表的命令,並返回該命令的各種參數:

 1 struct v4l2_queryctrl {
 2     __u32                id;            /* 命令編號 */
 3     enum v4l2_ctrl_type  type;          /* 命令值的類型 */
 4     __u8                 name[32];        /* 命令名稱*/
 5     __s32                minimum;       /* 最小的命令值 */
 6     __s32                maximum;       /* 最大的命令值 */
 7     __s32                step;          /* 命令值變化的步長 */
 8     __s32                default_value; /* 預設的命令值 */
 9     __u32                flags;         /* 命令的標誌 */
10     __u32                reserved[2];   /* 命令值的點陣圖表示 */
11 };
12 其中
13 enum v4l2_ctrl_type {
14     V4L2_CTRL_TYPE_INTEGER         = 1,   /* 整形 */
15     V4L2_CTRL_TYPE_BOOLEAN         = 2,   /* 真值 */
16     V4L2_CTRL_TYPE_MENU          = 3,   /* 菜單 */
17     V4L2_CTRL_TYPE_BUTTON         = 4,   /* 無值 */
18     V4L2_CTRL_TYPE_INTEGER64     = 5,   /* 後面三種不常用 */
19     V4L2_CTRL_TYPE_CTRL_CLASS    = 6,
20     V4L2_CTRL_TYPE_STRING        = 7,
21 };
22 命令的標誌取值如下:
23 /*  Control flags  */
24 #define V4L2_CTRL_FLAG_DISABLED        0x0001
25 #define V4L2_CTRL_FLAG_GRABBED        0x0002
26 #define V4L2_CTRL_FLAG_READ_ONLY     0x0004
27 #define V4L2_CTRL_FLAG_UPDATE         0x0008
28 #define V4L2_CTRL_FLAG_INACTIVE     0x0010
29 #define V4L2_CTRL_FLAG_SLIDER         0x0020
30 #define V4L2_CTRL_FLAG_WRITE_ONLY     0x0040
31 
32 /*  Query flag, to be ORed with the control ID */
33 #define V4L2_CTRL_FLAG_NEXT_CTRL    0x80000000

 

id 是命令的編號,常見的命令有兩種:一種以 V4L2_CID_BASE 為起始值,是公用命令;一種以 V4L2_CID_PRIVATE_BASE 為起始值,是私有命令。在一般的應用中命令值可見如下:

 1 V4L2_CID_CONTRAST               (V4L2_CID_BASE+1)            /* 對比度調節 */
 2 V4L2_CID_SATURATION             (V4L2_CID_BASE+2)            /* 飽和度調節 */
 3 V4L2_CID_AUDIO_VOLUME           (V4L2_CID_BASE+5)            /* 音量調節 */
 4 V4L2_CID_AUDIO_MUTE             (V4L2_CID_BASE+9)            /* 靜音設置 */
 5 V4L2_CID_DO_WHITE_BALANCE       (V4L2_CID_BASE+13)           /* 白平衡調節 */
 6 V4L2_CID_GAMMA                  (V4L2_CID_BASE+16)           /* 伽馬值調節 */
 7 V4L2_CID_EXPOSURE               (V4L2_CID_BASE+17)           /* 曝光度調節 */
 8 
 9 V4L2_CID_PRIVATE_ATXX_FLASH     (V4L2_CID_PRIVATE_BASE + 2)  /* 閃光燈控制 */
10 V4L2_CID_PRIVATE_ATXX_FRAME     (V4L2_CID_PRIVATE_BASE + 12) /* 幀率調節 */

 

 type 為命令值的類型(總共有7中類型的值),name 是命令的名稱,reserved 則是命令值的點陣圖表示,驅動會將所有的命令值都以 bit 的形式寫到 64 位的域中,上層應用查詢時可以根據點陣圖判斷命令支持的值。

 

 

7、struct v4l2_control 與 VIDIOC_G_CTRL、VIDIOC_S_CTRL

 VIDIOC_S_CTRL 或 VIDIOC_G_CTRL 命令通過結構 v4l2_control 設置或者獲取 id 命令的值:

1 struct v4l2_control { 2 __u32 id; 3 __s32 value; 4 };

 

 這個結構只有 2 個域,id 是命令編號,value 則是命令的值。

 

8、struct v4l2_tuner 與 VIDIOC_G_TUNER、VIDIOC_S_TUNER

 VIDIOC_S_TUNER 或 VIDIOC_G_TUNER 命令通過結構 v4l2_tuner 設置調諧器的信息:

1 struct v4l2_tuner {

2 __u32 index; /* 調諧器編號,由應用程式設置 */

3 __u8 name[32]; /* 調諧器名稱 */

4 enum v4l2_tuner_type type; /* 調諧器類型 */

5 __u32 capability; /* 調諧器支持的操作 */

6 __u32 rangelow; /* 最低頻率值,單位為62.5Hz或者62.5KHz */

7 __u32 rangehigh; /* 最高頻率值 */

8 __u32 rxsubchans; /* 接收的音頻信號類型 */

9 __u32 audmode; /* 當前音頻播放形式 */

10 __s32 signal; /* 信號強度 */

11 __s32 afc; /* 自動頻率控制 */

12 __u32 reserved[4]; /* 保留備用 */

13 };

14 其中

15 enum v4l2_tuner_type {

16 V4L2_TUNER_RADIO = 1, /* 調頻收音機 */

17 V4L2_TUNER_ANALOG_TV = 2, /* 模擬電視高頻頭 */

18 V4L2_TUNER_DIGITAL_TV = 3, /* 數字電視高頻頭 */

19 };

 其中域 type 有三種類型;capability 域一般為 V4L2_TUNER_CAP_LOW,表明頻率調節的步長是62.5Hz,如果沒有這個標誌位則步長為62.5KHz;rangelow 與 rangehigh 是調諧器可以調頻率的最高值和最低值,但都以步長為單位表示;rxsubchans 表示調諧器接收的音頻信號類型,常見值有 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO  即單聲道與立體聲;audmode 表示以何種方式播放聲音,常見值有 V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO,即以單聲道還是立體聲的方式播放;signal 為當前信號強度,一般取值範圍為 0 - 65535。

 

 

9、struct v4l2_frequency 與 VIDIOC_G_FREQUENCY、VIDIOC_S_FREQUENCY

VIDIOC_S_FREQUENCY 或 VIDIOC_G_FREQUENCY 命令通過結構 v4l2_frequency 設置或獲取當前頻率值:

struct v4l2_frequency {
    __u32                 tuner;          /* 調諧器編號 */
    enum v4l2_tuner_type  type;           /* 調諧器類型 */
    __u32                 frequency;      /* 調諧器頻率 */
    __u32                 reserved[8];
};

 註意:frequency 的值是以62.5Hz 或者 62.5KHZ 為單位的。

附:_IO、_IOR、_IOW、_IOWR 巨集的使用說明

驅動程式中 ioctl  函數傳遞的變數 cmd 是應用程式向驅動程式請求處理的命令。cmd 除了用於區別不同命令的數值,還可包含有助於處理的幾種信息。cmd 的大小為 32 bit,共分 4 個域:

bit29 ~ bit31: 3bit  為 “讀寫” 區,作用是區分是讀命令還是寫命令。
bit16 ~ bit28:13bit 為 "數據大小" 區,表示 ioctl 中的 arg 變數傳遞的數據大小;有時候為 14bit 即將 bit29 覆蓋。
bit8 ~ bit15:   8bit  為 “魔數"(也稱為"幻數")區,這個值用以與其它設備驅動程式的 ioctl 命令進行區別。
bit0 ~ bit7:     8bit  為 "序號" 區,是區分命令的命令順序序號。

魔數(magic number)
魔數範圍為 0~255 。通常,用英文字元 'A' ~ 'Z' 或者 'a' ~ 'z' 來表示。設備驅動程式從傳遞進來的命令獲取魔數,然後與自身處理的魔數想比較,如果相同則處理,不同則不處理。魔數是拒絕誤使用的初步輔助參數。設備驅動程式可以通過巨集 _IOC_TYPE (cmd) 來獲取魔數。不同的設備驅動程式最好設置不同的魔數,但並不是要求絕對,也是可以使用其他設備驅動程式已用過的魔數。

基數(序號)
基數用於區別各種命令。通常,從 0開始遞增,相同設備驅動程式上可以重覆使用該值。例如,讀和寫命令中使用了相同的基數,設備驅動程式也能分辨出來,原因在於設備驅動程式區分命令時使用 switch ,且直接使用命令變數 cmd 值。創建命令的巨集生成的值由多個域組合而成,所以即使是相同的基數,也會判斷為不同的命令。設備驅動程式想要從命令中獲取該基數,就使用巨集 _IOC_NR (cmd)。

下麵我們看一下上述巨集在內核中的原型:

下麵我們看一下上述巨集在內核中的原型

 1 /*
 2  * Our DIR and SIZE overlap in order to simulteneously provide
 3  * a non-zero _IOC_NONE (for binary compatibility) and
 4  * 14 bits of size as on i386. Here's the layout:
 5  *
 6  *   0xE0000000   DIR            3bit
 7  *   0x80000000   DIR = WRITE    bit31
 8  *   0x40000000   DIR = READ     bit30
 9  *   0x20000000   DIR = NONE     bit29
10  *   0x3FFF0000   SIZE (overlaps NONE bit)  13bit
11  *   0x0000FF00   TYPE           8bit
12  *   0x000000FF   NR (CMD)       8bit
13  */
14 /* 各個域的長度 */
15 #define _IOC_NRBITS      8
16 #define _IOC_TYPEBITS    8
17 #define _IOC_SIZEBITS   13    /* Actually 14, see below. */
18 #define _IOC_DIRBITS     3
19 /* 各個域的掩碼 */
20 #define _IOC_NRMASK      ((1 << _IOC_NRBITS)-1)
21 #define _IOC_TYPEMASK    ((1 << _IOC_TYPEBITS)-1)
22 #define _IOC_SIZEMASK    ((1 << _IOC_SIZEBITS)-1)
23 #define _IOC_XSIZEMASK   ((1 << (_IOC_SIZEBITS+1))-1)
24 #define _IOC_DIRMASK     ((1 << _IOC_DIRBITS)-1)
25 /* 各個域的偏移 */
26 #define _IOC_NRSHIFT     0
27 #define _IOC_TYPESHIFT   (_IOC_NRSHIFT + _IOC_NRBITS)       /* 8 */
28 #define _IOC_SIZESHIFT   (_IOC_TYPESHIFT + _IOC_TYPEBITS)   /* 16 */
29 #define _IOC_DIRSHIFT    (_IOC_SIZESHIFT + _IOC_SIZEBITS)   /* 29 */
30 /* 讀寫域的值 */
31 #define _IOC_NONE        1U
32 #define _IOC_READ        2U
33 #define _IOC_WRITE       4U
34 
35 #define _IOC(dir,type,nr,size) \
36         (((dir)  << _IOC_DIRSHIFT) | \      /* 讀寫方向左移 29bit */
37          ((type) << _IOC_TYPESHIFT) | \     /* 幻數左移 8bit */
38          ((nr)   << _IOC_NRSHIFT) | \       /* 命令序號 */
39          ((size) << _IOC_SIZESHIFT))        /* 參數大小左移 16bit */
40 /* 巨集原型,這裡將會根據傳遞的數據類型取其長度 */
41 #define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0)
42 #define _IOR(type,nr,size)  _IOC(_IOC_READ,(type),(nr),sizeof(size))
43 #define _IOW(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
44 #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
45 /* 獲取各個域的值 */
46 #define _IOC_DIR(nr)        (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
47 #define _IOC_TYPE(nr)       (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
48 #define _IOC_NR(nr)         (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
49 #define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)

這裡特別說明一下 _IO 巨集,該巨集沒有可傳遞的變數,只用於發送命令。這是因為變數需要可變數據,只作為命令(比如 reset)使用時,沒有必要判斷設備上的數據,因此設備驅動程式沒有必要執行文件相關的處理。在 v4l2 中使用示例如下:

#define VIDIOC_QUERYCAP      _IOR('V',  0, struct v4l2_capability)
#define VIDIOC_RESERVED       _IO('V',  1)
#define VIDIOC_S_FMT        _IOWR('V',  5, struct v4l2_format)
#define VIDIOC_STREAMON      _IOW('V', 18, int)

v4l2 中對上述巨集命令的處理在 video_ioctl2 函數中:

 1 static unsigned long cmd_input_size(unsigned int cmd)
 2 {
 3 #define CMDINSIZE(cmd, type, field)                 \
 4     case VIDIOC_##cmd:                     \
 5         return offsetof(struct v4l2_##type, field) +     \  /* 域的偏移 */
 6             sizeof(((struct v4l2_##type *)0)->field);      /* 域的長度 */
 7 
 8     switch (cmd) {
 9         CMDINSIZE(ENUM_FMT,        fmtdesc,    type);
10         CMDINSIZE(G_FMT,        format,        type);
11         ...
12         CMDINSIZE(ENUM_FRAMESIZES,    frmsizeenum,    pixel_format);
13         CMDINSIZE(ENUM_FRAMEINTERVALS,    frmivalenum,    height);
14     default:
15         return _IOC_SIZE(cmd);  /* 剩下的是需要全部拷貝的命令 */
16     }
17 }
18 
19 long video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg)
20 {
21     char    sbuf[128];          /* 在棧中分配128個位元組空間用來儲存命令的參數 */
22     void    *mbuf = NULL;
23     void    *parg = NULL;       /* 參數存放的首地址 */
24     long    err  = -EINVAL;
25     int     is_ext_ctrl;
26     size_t  ctrls_size = 0;
27     void __user *user_ptr = NULL;
28 
29     ...
30     /* 判斷是否包含讀寫命令,如果是則將用戶空間的參數值拷貝到內核 */
31     if (_IOC_DIR(cmd) != _IOC_NONE) {
32         /* 判斷參數大小是否超過128位元組 */
33         if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
34             parg = sbuf;
35         } else {
36             /* 如果超過128位元組則從堆中申請 */
37             mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
38             if (NULL == mbuf)
39                 return -ENOMEM;
40             parg = mbuf;
41         }
42 
43         err = -EFAULT;
44         /* 如果包含寫命令 */
45         if (_IOC_DIR(cmd) & _IOC_WRITE) {
46             /* 計算需要拷貝的有效數據長度,有的命令不需要全部拷貝 */
47             unsigned long n = cmd_input_size(cmd);
48             /* 從用戶空間拷貝參數值 */
49             if (copy_from_user(parg, (void __user *)arg, n))
50                 goto out;
51 
52             /* 將剩下的空間清零 */
53             if (n < _IOC_SIZE(cmd))
54                 memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
55         } else {
56             /* 如果是只讀命令則將整個buffer清零 */
57             memset(parg, 0, _IOC_SIZE(cmd));
58         }
59     }
60 
61     ...
62     /* 調用 v4l2_ioctl_ops 的成員函數處理命令 */
63     err = __video_do_ioctl(file, cmd, parg);
64     if (err == -ENOIOCTLCMD)
65         err = -EINVAL;
66     ...
67     if (err < 0)
68         goto out;
69 
70 out_ext_ctrl:
71     /* 如果包含讀命令則將參數值拷貝到用戶空間 */
72     switch (_IOC_DIR(cmd)) {
73     case _IOC_READ:
74     case (_IOC_WRITE | _IOC_READ):
75         if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
76             err = -EFAULT;
77         break;
78     }
79 
80 out:
81     kfree(mbuf);
82     return err;
83 }
84 EXPORT_SYMBOL(video_ioctl2);

然後我們在 struct v4l2_file_operations 中將 ioctl 成員設置為 video_ioctl2 即可

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、預設許可權 每一個終端都有一個 umask 屬性,是用來確定新建文件或目錄的預設許可權的許可權“掩碼”(mask 有“掩碼”的含義,至於 u,後面說)。 Linux 中一般有預設的許可權掩碼,使用命令 umask 用以查看或設置: 一般地,普通用戶(uid 為 500 以上)的許可權掩碼預設為 0002, ...
  • 轉載http://bgutech.blog.163.com/blog/static/18261124320116181119889/ 1. 什麼是workqueue Linux中的Workqueue機制就是為了簡化內核線程的創建。通過調用workqueue的介面就能創建內核線程。並且可以根據當前系統 ...
  • 1、PIC單片機匯流排結構——哈佛結構:即指令和數據空間是完全分開的,所以與常見的微控制器不同的一點是,程式和數據匯流排可以採用不同的寬度。以PIC16F684單片機為例,數據匯流排是8位的,但指令匯流排位數是14位。 2、在PIC單片機中,我們將RAM存儲器稱作文件寄存器(F寄存器)。 3、PIC中程式寄 ...
  • 第1章 許可權相關錯誤 1.1 普通用戶 ls /root/ /root 屬於root 普通用戶沒有任何許可權,所以無法查看 [oldboy@znix ~]$ ls /root/ ls: cannot open directory /root/: Permission denied [oldboy@zn ...
  • 用戶和組 su和sudo 當前用戶登錄環境特征 用戶操作 一個用戶只能在一個基本組,可以在多個附加組 用戶賬號的初始配置文件 組操作 管理用戶密碼 ...
  • ...
  • SSH: (Secure Shell)的縮寫,是建立在應用層和傳輸層基礎上的安全協議,SSH是目前 較為可靠的專為遠程登錄會話和其他網路服務提供安全性的協議,數據在使用ssh方式傳輸的時候是加密的,即使別人截獲也不知道是什麼數據;為客戶端提供安全的Shell環境,用於遠程管理,預設埠:TCP 22 ...
  • 我在使用atheros板子的過程中,在使用同一個CPU晶元的基礎上,需要把flash從8MB更換為16MB,把我的舊的內核和文件系統套在新的uboot上面,內核啟動的時候出現了以下錯誤,文件系統掛載不了。 JFFS2 warning: (1) jffs2_sum_process_sum_data: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...