@@ -5,7 +5,7 @@ categories:
55 - 内核层
66abbrlink : 4936fe45
77date : 2025-05-19 12:50:00
8- updated : 2025-06-02 17:15 :00
8+ updated : 2025-06-03 12:20 :00
99---
1010
1111<meta name =" referrer " content =" no-referrer " />
@@ -26,38 +26,21 @@ RTEMS(Real‑Time Executive for Multiprocessor Systems)是一款始于 1988
2626
2727### open()
2828
29- open() 函数的源码如下:
30-
31- ``` c
32- int open (const char * path, int oflag, ...)
33- {
34- int rv = 0;
35- va_list ap;
36- mode_t mode = 0;
37- rtems_libio_t * iop = NULL;
38-
39- // 处理可变参数,获取文件创建模式(mode)。
40- va_start(ap, oflag);
41- mode = va_arg(ap, mode_t);
42-
43- // 分配一个文件描述符结构。
44- iop = rtems_libio_allocate();
45- if (iop != NULL)
46- {
47- // 调用底层实现打开文件。
48- rv = do_open(iop, path, oflag, mode);
49- }
50- else
51- {
52- // 文件描述符耗尽,设置错误码。
53- errno = ENFILE;
54- rv = -1;
55- }
56-
57- va_end(ap);
58-
59- return rv;
60- }
29+ open() 函数的调用流程图如下:
30+
31+ ``` mermaid
32+ flowchart TD
33+ A[开始 open 函数] --> B[初始化变量 rv=0, mode=0, iop=NULL]
34+ B --> C[va_start 开始处理可变参数]
35+ C --> D[获取 mode 参数]
36+ D --> E{是否成功分配 iop}
37+ E -- 是 --> F[调用 do_open 打开文件]
38+ F --> G[设置 rv 为 do_open 返回值]
39+ E -- 否 --> H[设置 errno = ENFILE]
40+ H --> I[rv = -1]
41+ G --> J[va_end 结束可变参数处理]
42+ I --> J
43+ J --> K[返回 rv]
6144```
6245
6346#### struct rtems_libio_t
@@ -121,23 +104,57 @@ typedef struct rtems_filesystem_location_info_tt
121104比较重要的成员是 ` const rtems_filesystem_file_handlers_r *handlers ` ,该结构类似于 Linux 内核中的 file_operations,定义如下:
122105
123106``` c
107+ /* *
108+ * @brief File system node operations table.
109+ */
124110struct _rtems_filesystem_file_handlers_r
125111{
112+ // 打开文件的处理函数指针。
126113 rtems_filesystem_open_t open_h;
114+
115+ // 关闭文件的处理函数指针。
127116 rtems_filesystem_close_t close_h;
117+
118+ // 读取文件的处理函数指针。
128119 rtems_filesystem_read_t read_h;
120+
121+ // 写入文件的处理函数指针。
129122 rtems_filesystem_write_t write_h;
123+
124+ // 控制操作(如设备控制)的处理函数指针。
130125 rtems_filesystem_ioctl_t ioctl_h;
126+
127+ // 文件位置指针移动(如 lseek)的处理函数指针。
131128 rtems_filesystem_lseek_t lseek_h;
129+
130+ // 获取文件状态信息的处理函数指针。
132131 rtems_filesystem_fstat_t fstat_h;
132+
133+ // 截断文件大小的处理函数指针。
133134 rtems_filesystem_ftruncate_t ftruncate_h;
135+
136+ // 将文件缓冲区数据同步到存储设备的处理函数指针。
134137 rtems_filesystem_fsync_t fsync_h;
138+
139+ // 同步文件数据(但不一定包括元数据)的处理函数指针。
135140 rtems_filesystem_fdatasync_t fdatasync_h;
141+
142+ // 文件控制(如修改文件描述符属性)的处理函数指针。
136143 rtems_filesystem_fcntl_t fcntl_h;
144+
145+ // 轮询文件状态(如是否可读写)的处理函数指针。
137146 rtems_filesystem_poll_t poll_h;
147+
148+ // 用于事件过滤(BSD kqueue)的处理函数指针。
138149 rtems_filesystem_kqfilter_t kqfilter_h;
150+
151+ // 读取多个缓冲区(向量读)的处理函数指针。
139152 rtems_filesystem_readv_t readv_h;
153+
154+ // 写入多个缓冲区(向量写)的处理函数指针。
140155 rtems_filesystem_writev_t writev_h;
156+
157+ // 内存映射文件的处理函数指针。
141158 rtems_filesystem_mmap_t mmap_h;
142159};
143160```
@@ -266,42 +283,22 @@ struct _rtems_filesystem_operations_table
266283
267284#### rtems_libio_allocate()
268285
269- open 函数中分配文件描述符结构使用的函数是 rtems_libio_allocate(),定义如下:
270-
271- ``` c
272- rtems_libio_t *rtems_libio_allocate (void)
273- {
274- rtems_libio_t * iop;
275-
276- // 加锁,保护全局空闲链表。
277- rtems_libio_lock();
278-
279- // 从空闲链表头获取一个可用的文件描述符结构。
280- iop = rtems_libio_iop_free_head;
281-
282- if (iop != NULL)
283- {
284- void *next;
285-
286- // 获取下一个空闲节点。
287- next = iop->data1;
288-
289- // 更新空闲链表头指针。
290- rtems_libio_iop_free_head = next;
291-
292- // 如果空闲链表已空,更新尾指针。
293- if (next == NULL)
294- {
295- rtems_libio_iop_free_tail = &rtems_libio_iop_free_head;
296- }
297- }
298-
299- // 解锁,释放对空闲链表的访问。
300- rtems_libio_unlock();
301-
302- // 返回分配到的文件描述符结构(可能为 NULL)。
303- return iop;
304- }
286+ open 函数中分配文件描述符结构使用的函数是 rtems_libio_allocate(),执行流程图如下:
287+
288+ ``` mermaid
289+ flowchart TD
290+ A[开始 rtems_libio_allocate 函数] --> B[加锁保护空闲链表]
291+ B --> C[从空闲链表头获取 iop]
292+ C --> D{iop 是否为 NULL?}
293+ D -- 否 --> E[获取 iop->data1 到 next]
294+ E --> F[更新空闲链表头指针为 next]
295+ F --> G{next 是否为 NULL}
296+ G -- 是 --> H[更新尾指针为 &rtems_libio_iop_free_head]
297+ G -- 否 --> I[不操作]
298+ D -- 是 --> I
299+ H --> J[解锁释放访问]
300+ I --> J
301+ J --> K[返回 iop]
305302```
306303
307304##### rtems_libio_iop_free_head
@@ -314,29 +311,19 @@ rtems_libio_iop_free_head 是一个全局变量,用于维护 Rtems 文件描
314311
315312初始化阶段的函数逻辑如下:
316313
317- ```c
318- static void rtems_libio_init(void)
319- {
320- uint32_t i;
321- rtems_libio_t *iop;
322-
323- // 如果 I/O 对象数量大于 0,才进行初始化。
324- if (rtems_libio_number_iops > 0)
325- {
326- // 把空闲链表的头指针指向数组中第一个 I/O 对象。
327- iop = rtems_libio_iop_free_head = &rtems_libio_iops[0];
328-
329- // 把当前 I/O 对象的 data1 成员指向数组中的下一个 I/O 对象,实现链表链接。
330- for (i = 0; (i + 1) < rtems_libio_number_iops; i++, iop++)
331- iop->data1 = iop + 1;
332-
333- // 最后一个 I/O 对象的 data1 设置为 NULL,表示链表末尾。
334- iop->data1 = NULL;
335-
336- // 记录链表尾部指针,指向最后一个 I/O 对象的 data1 成员地址。
337- rtems_libio_iop_free_tail = &iop->data1;
338- }
339- }
314+ ``` mermaid
315+ flowchart TD
316+ A[开始 rtems_libio_init 函数] --> B{rtems_libio_number_iops > 0?}
317+ B -- 否 --> Z[结束函数]
318+ B -- 是 --> C[设置空闲链表头指针]
319+ C --> D[初始化循环变量 i = 0]
320+ D --> E{i + 1 < rtems_libio_number_iops?}
321+ E -- 是 --> F[设置 iop->data1 = iop + 1]
322+ F --> G[i++, iop++]
323+ G --> E
324+ E -- 否 --> H[设置最后一个 iop->data1 = NULL]
325+ H --> I[设置链表尾指针 rtems_libio_iop_free_tail = &iop->data1]
326+ I --> Z
340327```
341328
342329rtems_libio_iops 是 Rtems 预先分配的 I/O 控制块数组,配置了 CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 以后,会预先创建出这个数组。
0 commit comments