精华内容
下载资源
问答
  • CSS 列表属性允许你放置、改变列表项标志,或者将图像作为列表项标志
    千次阅读
    2019-02-26 14:14:53

    CSS 列表

    从某种意义上讲,不是描述性的文本的任何内容都可以认为是列表。人口普查、太阳系、家谱、参观菜单,甚至你的所有朋友都可以表示为一个列表或者是列表的列表。

    由于列表如此多样,这使得列表相当重要,所以说,CSS 中列表样式不太丰富确实是一大憾事。

    列表类型

    要影响列表的样式,最简单(同时支持最充分)的办法就是改变其标志类型。

    例如,在一个无序列表中,列表项的标志 (marker) 是出现在各列表项旁边的圆点。在有序列表中,标志可能是字母、数字或另外某种计数体系中的一个符号。

    要修改用于列表项的标志类型,可以使用属性 list-style-type

    ul {list-style-type : square}

    上面的声明把无序列表中的列表项标志设置为方块。

    列表项图像

    有时,常规的标志是不够的。你可能想对各标志使用一个图像,这可以利用 list-style-image 属性做到:

    ul li {list-style-image : url(xxx.gif)}

    只需要简单地使用一个 url() 值,就可以使用图像作为标志。

    列表标志位置

    CSS2.1 可以确定标志出现在列表项内容之外还是内容内部。这是利用 list-style-position 完成的。

    简写列表样式

    为简单起见,可以将以上 3 个列表样式属性合并为一个方便的属性:list-style,就像这样:

    li {list-style : url(example.gif) square inside}

    list-style 的值可以按任何顺序列出,而且这些值都可以忽略。只要提供了一个值,其它的就会填入其默认值。

    CSS 列表实例:

    在无序列表中的不同类型的列表标记

    本例演示在CSS中不同类型的列表项标记。

    在有序列表中不同类型的列表项标记

    本例演示在CSS中不同类型的列表项标记。

    所有的列表样式类型

    本例演示在CSS中所有不同类型的列表项标记。

    将图像作为列表项标记

    本例演示如何将图像作为列表项标记。

    放置列表标记

    本例演示在何处放置列表标记。

    在一个声明中定义所有的列表属性

    本例演示将所有针对列表的属性设置于一个简写属性。

    更多相关内容
  • 要想看懂FreeRTOS 源码并学习其原理,有一个东西绝对跑不了,那就是FreeRTOS 的列表和列表项。列表和列表项是FreeRTOS 的一个数据结构,FreeRTOS 大量使用到了列表和列表项,它是FreeRTOS 的基石。要想深入学习并...
    要想看懂FreeRTOS 源码并学习其原理,有一个东西绝对跑不了,那就是FreeRTOS 的列表和列表项。列表和列表项是FreeRTOS 的一个数据结构,FreeRTOS 大量使用到了列表和列表项,它是FreeRTOS 的基石。要想深入学习并理解FreeRTOS,那么列表和列表项就必须首先掌握,否则后面根本就没法进行。本章我们就来学习一下FreeRTOS 的列表和列表项,包括对列表和列表项的操作,本章分为如下几部分:
    7.1 什么是列表和列表项
    7.2 列表和列表项的初始化
    7.3 列表项的插入
    7.4 列表项末尾插入
    7.5 列表项的删除
    7.6 列表项的遍历

    7.7 列表项的插入和删除实验

    7.1 什么是列表和列表项?
    7.1.1 列表
    列表是FreeRTOS 中的一个数据结构,概念上和链表有点类似,列表被用来跟踪FreeRTOS中的任务。与列表相关的全部东西都在文件list.c 和list.h 中。在list.h 中定义了一个叫List_t 的结构体,如下:


    (1) 和(5) 、这两个都是用来检查列表完整性的, 需要将宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为1,开启以后会向这两个地方分别添加一个变量xListIntegrityValue1 和xListIntegrityValue2,在初始化列表的时候会这两个变量中写入一个特殊的值,默认不开启这个功能。以后我们在学习列表的时候不讨论这个功能!
    (2)、uxNumberOfItems 用来记录列表中列表项的数量。
    (3)、pxIndex 用来记录当前列表项索引号,用于遍历列表。
    (4)、列表中最后一个列表项,用来表示列表结束,此变量类型为MiniListItem_t,这是一个迷你列表项,关于列表项稍后讲解。列表结构示意图如图7.1.1.1 所示:


    注意!图7.1.1.1 中并未列出用于列表完整性检查的成员变量。
    7.1.2 列表项
    列表项就是存放在列表中的项目,FreeRTOS 提供了两种列表项:列表项和迷你列表项。这两个都在文件list.h 中有定义,先来看一下列表项,定义如下:



    (1)和(7)、用法和列表一样,用来检查列表项完整性的。以后我们在学习列表项的时候不讨论这个功能!
    (2)、xItemValue 为列表项值。
    (3)、pxNext 指向下一个列表项。
    (4)、pxPrevious 指向前一个列表项,和pxNext 配合起来实现类似双向链表的功能。
    (5)、pvOwner 记录此链表项归谁拥有,通常是任务控制块。
    (6)、pvContainer 用来记录此列表项归哪个列表。注意和pvOwner 的区别,在前面讲解任务控制块TCB_t 的时候说了在TCB_t 中有两个变量xStateListItem 和xEventListItem,这两个变量的类型就是ListItem_t,也就是说这两个成员变量都是列表项。以xStateListItem 为例,当创建一个任务以后xStateListItem 的pvOwner 变量就指向这个任务的任务控制块,表示xSateListItem属于此任务。当任务就绪态以后xStateListItem 的变量pvContainer 就指向就绪列表,表明此列表项在就绪列表中。举个通俗一点的例子:小王在上二年级,他的父亲是老王。如果把小王比作列表项,那么小王的pvOwner 属性值就是老王,小王的pvContainer 属性值就是二年级。列表项结构示意图如图7.1.2.1 所示:

    注意!图7.1.2.1 中并未列出用于列表项完整性检查的成员变量!
    7.1.3 迷你列表项
    上面我们我们说了列表项,现在来看一下迷你列表项,迷你列表项在文件list.h 中有定义,如下:


    (1)、用于检查迷你列表项的完整性。

    (2)、xItemValue 记录列表列表项值。
    (3)、pxNext 指向下一个列表项。
    (4)、pxPrevious 指向上一个列表项。
    可以看出迷你列表项只是比列表项少了几个成员变量,迷你列表项有的成员变量列表项都有的,没感觉有什么本质区别啊?那为什么要弄个迷你列表项出来呢?那是因为有些情况下我们不需要列表项这么全的功能,可能只需要其中的某几个成员变量,如果此时用列表项的话会造成内存浪费!比如上面列表结构体List_t 中表示最后一个列表项的成员变量xListEnd 就是MiniListItem_t 类型的。迷你列表项结构示意图如图7.1.3.1 所示:


    注意!图7.1.3.1 中并未列出用于迷你列表项完整性检查的成员变量!
    7.2 列表和列表项初始化
    7.2.1 列表初始化
    新创建或者定义的列表需要对其做初始化处理,列表的初始化其实就是初始化列表结构体List_t 中的各个成员变量,列表的初始化通过使函数vListInitialise()来完成,此函数在list.c 中有定义,函数如下:


    (1)、xListEnd 用来表示列表的末尾,而pxIndex 表示列表项的索引号,此时列表只有一个列表项,那就是xListEnd,所以pxIndex 指向xListEnd。
    (2)、xListEnd 的列表项值初始化为portMAX_DELAY, portMAX_DELAY 是个宏,在文件portmacro.h 中有定义。根据所使用的MCU 的不同,portMAX_DELAY 值也不相同,可以为0xffff或者0xffffffffUL,本教程中为0xffffffffUL。
    (3)、初始化列表项xListEnd 的pxNext 变量,因为此时列表只有一个列表项xListEnd,因此pxNext 只能指向自身。

    (4)、同(3)一样,初始化xListEnd 的pxPrevious 变量,指向xListEnd 自身。
    (5)、由于此时没有其他的列表项,因此uxNumberOfItems 为0,注意,这里没有算xListEnd。
    (6) 和(7) 、初始化列表项中用于完整性检查字段, 只有宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 为1 的时候才有效。同样的根据所选的MCU 不同其写入的值也不同,可以为0x5a5a 或者0x5a5a5a5aUL。STM32 是32 位系统写入的是0x5a5a5a5aUL,列表初始化完以后如图7.2.1.1 所示:


    注意,图7.2.1.1 为了好分析,将xListEnd 中的各个成员变量都写了出来!
    7.2.2 列表项初始化
    同列表一样,列表项在使用的时候也需要初始化,列表项初始化由函数vListInitialiseItem()来完成,函数如下:


    列表项的初始化很简单,只是将列表项成员变量pvContainer 初始化为NULL,并且给用于完整性检查的变量赋值。有朋友可能会问,列表项的成员变量比列表要多,怎么初始化函数就这么短?其他的成员变量什么时候初始化呢?这是因为列表项要根据实际使用情况来初始化,比如任务创建函数xTaskCreate()就会对任务堆栈中的xStateListItem 和xEventListItem 这两个列表项中的其他成员变量在做初始化,任务创建过程后面会详细讲解。
    7.3 列表项插入
    7.3.1 列表项插入函数分析

    列表项的插入操作通过函数vListInsert()来完成,函数原型如下:


    参数:
    pxList: 列表项要插入的列表。
    pxNewListItem: 要插入的列表项。
    返回值:

    函数vListInsert()的参数pxList 决定了列表项要插入到哪个列表中,pxNewListItem 决定了要插入的列表项,但是这个列表项具体插入到什么地方呢?要插入的位置由列表项中成员变量xItemValue 来决定。列表项的插入根据xItemValue 的值按照升序的方式排列!接下来我们来具体看一下函数vListInsert()的整个运行过程,函数代码如下:


    (1)、获取要插入的列表项值,即列表项成员变量xItemValue 的值,因为要根据这个值来确定列表项要插入的位置。

    (2)、这一行和下一行代码用来检查列表和列表项的完整性的。其实就是检查列表和列表项中用于完整性检查的变量值是否被改变。这些变量的值在列表和列表项初始化的时候就被写入了,这两行代码需要实现函数configASSERT()!

    (3)、要插入列表项,第一步就是要获取该列表项要插入到什么位置!如果要插入的列表项的值等于portMAX_DELAY,也就是说列表项值为最大值,这种情况最好办了,要插入的位置就是列表最末尾了。
    (4)、获取要插入点,注意!列表中的xListEnd 用来表示列表末尾,在初始化列表的时候xListEnd 的列表值也是portMAX_DELAY,此时要插入的列表项的列表值也是portMAX_DELAY。这两个的顺序该怎么放啊?通过这行代码可以看出要插入的列表项会被放到xListEnd 前面。
    (5)、要插入的列表项的值如果不等于portMAX_DELAY 那么就需要在列表中一个一个的找自己的位置,这个for 循环就是找位置的过程,当找到合适列表项的位置的时候就会跳出。由于这个for 循环是用来寻找列表项插入点的,所以for 循环体里面没有任何东西。这个查找过程是按照升序的方式查找列表项插入点的。
    (6)、经过上面的查找,我们已经找到列表项的插入点了,从本行开始接下来的四行代码就是将列表项插入到列表中,插入过程和数据结构中双向链表的插入类似。像FreeRTOS 这种RTOS 系统和一些协议栈都会大量用到数据结构的知识,所以建议大家没事的时候多看看数据结构方面的书籍,否则的话看源码会很吃力的。
    (7)、列表项已经插入到列表中了,那么列表项的成员变量pvContainer 也该记录此列表项属于哪个列表的了。
    (8)、列表的成员变量uxNumberOfItems 加一,表示又添加了一个列表项。
    7.3.2 列表项插入过程图示
    上一小节我们分析了列表项插入函数vListInsert(),本小节我们就通过图片来演示一下这个插入过程,本小节我们会向一个空的列表中插入三个列表项,这三个列表项的值分别为40,60和50。
    1、插入值为40 的列表项
    在一个空的列表List 中插入一个列表值为40 的列表项ListItem1,插入完成以后如图7.3.2.1所示:


    注意观察插入完成以后列表List 和列表项ListItem1 中各个成员变量之间的变化,比如列表List 中的uxNumberOfItems 变为了1,表示现在列表中有一个列表项。列表项ListItem1 中的pvContainer 变成了List,表示此列表项属于列表List。通过图7.3.2.1 可以看出,列表是一个环形的,即环形列表!

    2、插入值为60 的列表项

    接着再插入一个值为60 的列表项ListItem2,插入完成以后如图7.3.2.2 所示:


    上面再讲解函数vListInsert()的时候说过了列表项是按照升序的方式插入的,所以ListItem2肯定是插入到ListItem1 的后面、xListEnd 的前面。同样的,列表List 的uxNumberOfItems 再次加一变为2 了,说明此时列表中有两个列表项。
    3、插入值为50 的列表项

    在上面的列表中再插入一个值为50 的列表项ListItem3,插入完成以后如图7.3.2.3 所示:


    按照升序排列的方式,ListItem3 应该放到ListItem1 和ListItem2 中间,大家最好通过对照这三幅图片来阅读函数vListInsert()的源码,这样就会对函数有一个直观的认识。
    7.4 列表项末尾插入
    7.4.1 列表项末尾插入函数分析

    列表末尾插入列表项的操作通过函数vListInsertEnd ()来完成,函数原型如下:


    参数:
    pxList: 列表项要插入的列表。

    pxNewListItem: 要插入的列表项。

    返回值:

    函数vListInsertEnd()源码如下:


    (1)、与下面的一行代码完成对列表和列表项的完整性检查。
    (2)、从本行开始到(3)之间的代码就是将要插入的列表项插入到列表末尾。使用函数vListInsert()向列表中插入一个列表项的时候这个列表项的位置是通过列表项的值,也就是列表项成员变量xItemValue 来确定。vListInsertEnd()是往列表的末尾添加列表项的,我们知道列表中的xListEnd 成员变量表示列表末尾的,那么函数vListInsertEnd()插入一个列表项是不是就是插到xListEnd 的前面或后面啊?这个是不一定的,这里所谓的末尾要根据列表的成员变量pxIndex 来确定的!前面说了列表中的pxIndex 成员变量是用来遍历列表的,pxIndex 所指向的列表项就是要遍历的开始列表项,也就是说pxIndex 所指向的列表项就代表列表头!由于是个环形列表,所以新的列表项就应该插入到pxIndex 所指向的列表项的前面。
    (3)、标记新的列表项pxNewListItem 属于列表pxList。
    (4)、记录列表中的列表项数目的变量加一,更新列表项数目。
    7.4.2 列表项末尾插入图示
    跟函数vListInsert()一样,我们也用图片来看一下函数vListInsertEnd()的插入过程。
    1、默认列表

    在插入列表项之前我们先准备一个默认列表,如图7.4.2.1 所示:


    注意图7.4.2.1 中列表的pxIndex 所指向的列表项,这里为ListItem1,不再是xListEnd 了。
    3、插入值为50 的列表项

    在上面的列表中插入一个值为50 的列表项ListItem3,插入完成以后如图7.4.2.2 所示:


    列表List 的pxIndex 指向列表项ListItem1,因此调用函数vListInsertEnd()插入ListItem3 的话就会在ListItem1 的前面插入。

    7.5 列表项的删除
    有列表项的插入,那么必然有列表项的删除,列表项的删除通过函数uxListRemove()来完成,函数原型如下:


    参数:
    pxItemToRemove: 要删除的列表项。
    返回值: 返回删除列表项以后的列表剩余列表项数目。
    注意,列表项的删除只是将指定的列表项从列表中删除掉,并不会将这个列表项的内存给释放掉!如果这个列表项是动态分配内存的话。函数uxListRemove()的源码如下:


    (1)、要删除一个列表项我们得先知道这个列表项处于哪个列表中,直接读取列表项中的成员变量pvContainer 就可以得到此列表项处于哪个列表中。
    (2)、与下面一行完成列表项的删除,其实就是将要删除的列表项的前后两个列表项“连接”在一起。
    (3)、如果列表的pxIndex 正好指向要删除的列表项,那么在删除列表项以后要重新给
    pxIndex 找个“对象”啊,这个新的对象就是被删除的列表项的前一个列表项。
    (4)、被删除列表项的成员变量pvContainer 清零。
    (5)、返回新列表的当前列表项数目。
    7.6 列表的遍历
    介绍列表结构体的时候说过列表List_t 中的成员变量pxIndex 是用来遍历列表的,FreeRTOS提供了一个函数来完成列表的遍历,这个函数是listGET_OWNER_OF_NEXT_ENTRY()。每调用一次这个函数列表的pxIndex 变量就会指向下一个列表项,并且返回这个列表项的pxOwner变量值。这个函数本质上是一个宏,这个宏在文件list.h 中如下定义:



    (1)、pxTCB 用来保存pxIndex 所指向的列表项的pvOwner 变量值,也就是这个列表项属于谁的?通常是一个任务的任务控制块。pxList 表示要遍历的列表。
    (2)、列表的pxIndex 变量指向下一个列表项。
    (3)、如果pxIndex 指向了列表的xListEnd 成员变量,表示到了列表末尾。
    (4)、如果到了列表末尾的话就跳过xListEnd,pxIndex 再一次重新指向处于列表头的列表项,这样就完成了一次对列表的遍历。
    (5)、将pxIndex 所指向的新列表项的pvOwner 赋值给pxTCB。此函数用于从多个同优先级的就绪任务中查找下一个要运行的任务。
    7.7 列表项的插入和删除实验
    上面我们通过分析源码的方式了解了FreeRTOS 的列表和列表项的操作过程,但是实际上究竟是不是这样的、我们的分析有没有错误?最好的检验方法就是写一段测试代码测试一下,观察在对列表和列表项操作的时候其变化情况和我们分析的是否一致。
    7.7.1 实验程序设计
    1、实验目的
    学习使用FreeRTOS 列表和列表项相应的操作函数的使用,观察这些操作函数的运行结果和我们理论分析的是否一致。
    2、实验设计
    本实验设计3 个任务:start_task、task1_task 和list_task,这三个任务的任务功能如下:start_task:用来创建其他2 个任务。task1_task:应用任务1,控制LED0 闪烁,用来提示系统正在运行。task2_task: 列表和列表项操作任务,调用列表和列表项相关的API 函数,并且通过串口输出相应的信息来观察这些API 函数的运行过程。实验需要用到KEY_UP 按键,用于控制任务的运行。
    3、实验工程

    FreeRTOS 实验7-1 FreeRTOS 列表项的插入和删除实验。

    点击下载代码

    4、实验程序与分析
    ● 任务设置

    实验中任务优先级、堆栈大小和任务句柄等的设置如下:


    ● 列表和列表项的定义


    ● main()函数


    ● 任务函数
    任务函数start_task()和task1_task()都比较简单,这里为了缩减篇幅就不列出来了,重点看一下任务函数list_task(),函数如下:




    任务函数list_task()通过调用与列表和列表项相关的API 函数来对列表和列表项做相应的操作,并且通过串口打印出每调用一个API 函数以后列表和列表项的连接信息,通过这些信息我们可以直观的判断出列表项在插入、删除和末尾插入的时候这个列表的变化情况。
    7.7.2 程序运行结果分析
    编译并下载实验代码到开发板中,打开串口调试助手,然后按照任务函数list_task()中的步骤一步步的测试分析。
    ● 第一步和第二步
    第一步和第二步是用来初始化列表和列表项的,并且通过串口输出列表和列表项的地址,这一步是开发板复位后默认运行的,串口调试助手信息如下所示:


    由于这些列表和列表项地址前六位都为0X200000,只有最低2 位不同,所以我们就用最低2 位代表这些列表和列表项的地址。注意!列表和列表项的地址在不同的硬件平台或编译软件上是不同的,以自己的实际实验结果为准!简单的分析一下图7.7.2.1 可以得到如下信息:
    1、列表TestList 地址为b4。
    2、列表项ListItem1、ListItem2 和ListItem3 的地址分别为c8、dc 和f0。
    3、列表TestList 的xListEnd 地址为bc。
    4、列表TestList 的pxIndex 指向地址bc,而这个地址正是迷你列表项xListEnd,说明pxIndex指向xListEnd,这个和我们分析列表初始化函数vListInitialise()的时候得到的结果是一致的。
    ● 第三步
    按一下KEY_UP 键,执行第三步,第三步是向列表TestList 中插入列表项ListItem1,列表项ListItem1 的成员变量xItemValue 的值为40。第三步执行完以后串口调试助手输出如图7.7.2.2所示:


    分析图7.7.2.2 可以得出一下信息:
    1、xListEnd 的pxNext 指向地址c8,而c8 是ListItem1 的地址,说明xListEnd 的pxNext 指向ListItem1。
    2、列表项ListItem1 的pxNext 指向地址bc,而bc 是xListEnd 的地址,说明ListItem1 的pxNext 指向xListEnd。
    3、xListEnd 的pxPrevious 指向地址c8,而c8 是ListItem1 的地址,说明xListEnd 的pxPrevious指向ListItem2。
    4、ListItem1 的pxPrevious 指向地址bc,bc 是xListEnd 的地址,说明ListItem1 的pxPrevious指向xListEnd。

    用简易示意图表示这一步的话如图7.7.2.3 所示:


    ●第四步
    按一下KEY_UP 键,执行第四步,第四步是向列表TestList 中插入列表项ListItem2,列表项ListItem2 的成员变量xItemValue 的值为60。第四步执行完以后串口调试助手输出如图7.7.2.4所示:


    分析图7.7.2.4 可以得出一下信息:
    1、xListEnd 的pxNext 指向ListItem1。
    2、ListItem1 的pxNext 指向ListItem2。
    3、ListItem2 的pxNext 指向xListEnd。
    4、列表项的pxPrevious 分析过程类似,后面的步骤中就不做分析了,只看pxNext 成员变量。用简易示意图表示这一步的话如图7.7.2.5 所示:


    ●第五步
    按一下KEY_UP 键,执行第五步,第五步是向列表TestList 中插入列表项ListItem3,列表项ListItem3 的成员变量xItemValue 的值为50。第四步执行完以后串口调试助手输出如图7.7.2.6所示:


    分析图7.7.2.6 可以得出一下信息:
    1、xListEnd 的pxNext 指向ListItem1。
    2、ListItem1 的pxNext 指向ListItem3。
    3、ListItem3 的pxNext 指向ListItem2。
    4、ListItem2 的pxNext 指向xListEnd。

    用简易示意图表示这一步的话如图7.7.2.7 所示:


    通过这几步可以看出列表项的插入是根据xItemValue 的值做升序排列的,这个和我们分析函数vListInsert()得到的结果一样,说明我们的分析是对的!
    ●第六步和第七步
    这两步是观察函数uxListRemove()和vListInsertEnd()的运行过程的,分析过程和前五步一样。这里就不做分析了,大家自行根据串口调试助手输出的信息做分析。


    展开全文
  • 列表和列表项

    千次阅读 2017-01-17 14:32:04
    FreeRTOS内核调度大量使用了列表(list)和列表项(list item)数据结构。我们如果想一探FreeRTOS背后的运行机制,首先遇到的拦路虎就是列表和列表项。对于FreeRTOS内核来说,列表就是它最基础的部分。我们在这一章...

      FreeRTOS内核调度大量使用了列表(list)和列表项(list item)数据结构。我们如果想一探FreeRTOS背后的运行机制,首先遇到的拦路虎就是列表和列表项。对于FreeRTOS内核来说,列表就是它最基础的部分。我们在这一章集中讲解列表和列表项的结构以及操作函数,在下一章讲解任务创建时,会用到本章的知识点。

          列表被FreeRTOS调度器使用,用于跟踪任务,处于就绪、挂起、延时的任务,都会被挂接到各自的列表中。用户程序如果有需要,也可以使用列表。

          FreeRTOS列表使用指针指向列表项。一个列表(list)下面可能有很多个列表项(list item),每个列表项都有一个指针指向列表。如图1-1所示。


    图1-1:列表与列表项

          列表项有两种形式,全功能版的列表项xLIST_ITEM和迷你版的列表项xMINI_LIST_ITEM。我们来看一下它们具体的定义,先看全功能版。

    [objc]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. struct xLIST_ITEM  
    2. {  
    3.      listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           /*用于检测列表项数据是否完整*/  
    4.      configLIST_VOLATILETickType_t xItemValue;           /*列表项值*/  
    5.      struct xLIST_ITEM * configLIST_VOLATILE pxNext;      /*指向列表中下一个列表项*/  
    6.      struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;  /*指向列表中上一个列表项*/  
    7.      voidvoid * pvOwner;                                     /*指向一个任务TCB*/  
    8.      voidvoid * configLIST_VOLATILE pvContainer;             /*指向包含该列表项的列表 */  
    9.      listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE          /*用于检测列表项数据是否完整*/  
    10. };  
    11. typedef struct xLIST_ITEM ListItem_t;  

          宏listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE用于检查列表项数据是否完整,在projdefs.h中,如果将宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1,则使能列表项数据完整性检查,则宏listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE会被两个已知的数值代替。

          xItemValue是列表项值,通常是一个被跟踪的任务优先级或是一个调度事件的计数器值。如果任务因为等待从队列取数据而进入阻塞状态,则任务的事件列表项的列表项值保存任务优先级有关信息,状态列表项的列表项值保存阻塞时间有关的信息。这个变量被configLIST_VOLATILE修饰,configLIST_VOLATILE被映射成C语言关键字volatile,表明这个变量是“易变的”,告诉编译器不得对这个变量进行代码优化,因为列表项的成员可能会在中断服务程序中被更新。关于volatile关键字,如果不是熟悉的话,可以参考我的博文《编写优质嵌入式C程序》第3.2.4节。

          pxNext和pxPrevious是列表项类型指针,用来指向列表中下一个和上一个列表项,通过这两个指针,列表项之间可以形成类似双向链表结构。

          指针pvOwner通常指向一个任务TCB。

          指针pvContainer指向包含该列表项的列表。

          迷你版的列表项xMINI_LIST_ITEM是全功能版列表项xLIST_ITEM的一个子集,定义如下所示:

    [objc]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. struct xMINI_LIST_ITEM  
    2. {  
    3.      listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           /*用于检测列表项数据是否完整*/  
    4.      configLIST_VOLATILE TickType_t xItemValue;  
    5.      struct xLIST_ITEM * configLIST_VOLATILE pxNext;  
    6.      struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;  
    7. };  
    8. typedef struct xMINI_LIST_ITEM MiniListItem_t;  

             既然有了全功能版的列表项,为什么还要声明迷你版的列表项呢?这是因为列表结构体需要一个列表项成员,但又不需要列表项中的所有字段,所以才有了迷你版列表项。列表结构体定义为:

    [objc]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. typedef struct xLIST  
    2. {  
    3.      listFIRST_LIST_INTEGRITY_CHECK_VALUE                        /*用于检测列表项数据是否完整*/  
    4.      configLIST_VOLATILE UBaseType_t uxNumberOfItems;  
    5.      ListItem_t * configLIST_VOLATILE pxIndex;                   /*用于遍历列表*/  
    6.      MiniListItem_t xListEnd;                                    /*列表项*/  
    7.      listSECOND_LIST_INTEGRITY_CHECK_VALUE                       /*用于检测列表项数据是否完整*/  
    8. }List_t;  

          和列表项定义相同,宏listFIRST_LIST_INTEGRITY_CHECK_VALUE和listSECOND_LIST_INTEGRITY_CHECK_VALUE用于检查列表项数据是否完整,在projdefs.h中,如果将宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1,则使能列表项数据完整性检查,则宏listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE会被两个已知的数值代替。

          uxNumberOfItems表示该列表中挂接的列表项数目,0表示列表为空。

          列表项类型指针用于遍历列表,列表初始化后,这个指针指向&xListEnd。通过宏listGET_OWNER_OF_NEXT_ENTRY()来获取列表中的下一个列表项。

          列表项xListEnd用于标记列表结束。xListEnd.xItemValue被初始化为一个常数,其值与硬件架构相关,为0xFFFF(16位架构)或者0xFFFFFFFF(32位架构)。

          下面我们看一下列表操作。FreeROTS提供了几个API函数,用于初始化列表和列表项以及列表项插入操作。

    1.初始化列表

          列表结构体中包含一个列表项成员,主要用于标记列表结束。初始化列表就是把这个列表项插入到列表中。
    [objc]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. void vListInitialise( List_t * const pxList )  
    2. {  
    3.      /*列表索引指向列表项*/  
    4.      pxList->pxIndex = ( ListItem_t * )&( pxList->xListEnd );                    
    5.      /* 设置为最大可能值 */  
    6.      pxList->xListEnd.xItemValue =portMAX_DELAY;  
    7.    
    8.      /* 列表项xListEnd的pxNext和pxPrevious指针指向了它自己 */  
    9.      pxList->xListEnd.pxNext = (ListItem_t * ) &( pxList->xListEnd );  
    10.      pxList->xListEnd.pxPrevious= ( ListItem_t * ) &( pxList->xListEnd );  
    11.      pxList->uxNumberOfItems = ( UBaseType_t) 0U;  
    12.    
    13.      /* 设置为已知值,用于检测列表数据是否完整*/  
    14.      listSET_LIST_INTEGRITY_CHECK_1_VALUE(pxList );  
    15.      listSET_LIST_INTEGRITY_CHECK_2_VALUE(pxList );  
    16. }  

          如果宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1,则使能列表项数据完整性检查,则宏listSET_LIST_INTEGRITY_CHECK_1_VALUE()和listSET_LIST_INTEGRITY_CHECK_2_VALUE被一个已知值代替,默认为0x5a5a(16位架构)或者0x5a5a5a5a(32位架构)。

          假设禁止列表数据完整性检查,初始化后的列表如图1-2所示,uxNumberOfItems被初始化为0,xListEnd.xItemValue初始化为0xffffffff,pxIndex、xListEnd.pxNext和xListEnd.pxPrevious初始化为指向列表项xListEnd。


    图1-2:初始化后的列表

    2.初始化列表项

          列表项的初始比较简单,只要确保列表项不在任何列表中即可。

    [objc]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. void vListInitialiseItem( ListItem_t * const pxItem )  
    2. {  
    3.      pxItem->pvContainer = NULL;  
    4.    
    5.      /*设置为已知值,用于检测列表项数据是否完整*/  
    6.      listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem );  
    7.      listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem );  
    8. }  

          如果宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1,则使能列表项数据完整性检查,则宏listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE会被两个已知的数值代替,默认为0x5a5a(16位架构)或者0x5a5a5a5a(32位架构)。

          假设禁止列表项数据完整性检查,初始化后的列表项如图1-3所示。仅是将指针pvContainer设置为空指针,该指针用于指向包含该列表项的列表,这里设置为NULL表示这个列表项不属于任何列表。


    图1-3:初始化后的列表项

    3.将列表项插入到列表中,列表项所在的位置取决于列表项的列表项值(xItemValue)。

          每个列表项对象都有一个列表项值(xItemValue),通常是一个被跟踪的任务优先级或是一个调度事件的计数器值。调用API函数vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem)可以将pxNewListItem指向的列表项插入到pxList指向的列表中,列表项在列表的位置由pxNewListItem->xItemValue决定,按照降序排列。

    [objc]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )  
    2. {  
    3. ListItem_t *pxIterator;  
    4. const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;  
    5.    
    6.          /* 检查列表和列表项数据的完整性,仅当configASSERT()定义时有效。*/  
    7.          listTEST_LIST_INTEGRITY( pxList );  
    8.          listTEST_LIST_ITEM_INTEGRITY(pxNewListItem );  
    9.    
    10.          /*将新的列表项插入到列表,根据xItemValue的值降序插入列表。*/  
    11.          if( xValueOfInsertion == portMAX_DELAY)  
    12.          {  
    13.                    pxIterator =pxList->xListEnd.pxPrevious;  
    14.          }  
    15.          else  
    16.          {  
    17.                    for( pxIterator = (ListItem_t * ) &( pxList->xListEnd );pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator =pxIterator->pxNext )  
    18.                    {  
    19.                             /* 这里为空 */  
    20.                    }  
    21.          }  
    22.    
    23.          pxNewListItem->pxNext =pxIterator->pxNext;  
    24.          pxNewListItem->pxNext->pxPrevious= pxNewListItem;  
    25.          pxNewListItem->pxPrevious =pxIterator;  
    26.          pxIterator->pxNext = pxNewListItem;  
    27.    
    28.          pxNewListItem->pvContainer = ( void* ) pxList;  
    29.    
    30.          ( pxList->uxNumberOfItems )++;  
    31. }  

          根据xItemValue的值将新的列表项插入到列表。如果列表中存在与新列表项xItemValue值相同的列表项,则新插入的列表项位于它之后。如果列表项的xItemValue值等于portMAX_DELAY(列表结束标记,我们在讲列表数据结构时,说到每个列表数据结构体中都有一个列表项成员xListEnd,用于标记列表结束。xListEnd.xItemValue被初始化为一个常数,其值与硬件架构相关,为0xFFFF或者0xFFFFFFFF。这个常数在移植层定义,即宏portMAX_DELAY),则表示到达了列表结束位置。

          我们用图示的方法来讲解这个函数,我们假设一个列表项值(xItemValue)为32的列表项插入到如图1-2所示的初始化后的列表中,调用vListInsert()函数后,列表和列表项的关系如图1-4所示。列表项xListItem_1的成员指针pxNext和pxPrevious都指向了xListEnd,而xListEnd的成员指针pxNext和pxPrevious都指向了列表项xListItem_1;列表项xListItem_1的成员指针pvContainer指向了列表xList_1;列表成员uxNumberOfItems为1。


    图1-4:将列表项插入到列表

          在此基础上,如果再将一个列表项值xItemValue)为40的列表项插入到列表中,调用vListInsert()函数后,列表和列表项的关系如图1-5所示。


    图1-5:将列表项插入到列表

     

    4.将列表项插入到列表末端

            第3节讲的API插入函数是根据列表项中的列表项值(xItemValue)来决定插入位置的,本节所讲的API函数vListInsertEnd()是简单的将列表项插入到列表的末端。在下一章任务创建分析的文章中,将会遇到这个API函数,到时再以图标的形式分析这个函数,现在给出这个函数的源码。

    [objc]  view plain  copy
     print ? 在CODE上查看代码片 派生到我的代码片
    1. void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )  
    2. {  
    3. ListItem_t* const pxIndex = pxList->pxIndex;  
    4.    
    5.          /*检查列表和列表项数据的完整性,仅当configASSERT()定义时有效。*/  
    6.          listTEST_LIST_INTEGRITY( pxList );  
    7.          listTEST_LIST_ITEM_INTEGRITY(pxNewListItem );  
    8.    
    9.          /*向列表中插入新的列表项*/  
    10.          pxNewListItem->pxNext = pxIndex;  
    11.          pxNewListItem->pxPrevious =pxIndex->pxPrevious;  
    12.    
    13.          mtCOVERAGE_TEST_DELAY();  
    14.    
    15.          pxIndex->pxPrevious->pxNext =pxNewListItem;  
    16.          pxIndex->pxPrevious = pxNewListItem;  
    17.    
    18.          pxNewListItem->pvContainer = ( void* ) pxList;  
    19.    
    20.          ( pxList->uxNumberOfItems )++;  
    21. }  
    展开全文
  • 去除列表项符号

    千次阅读 2019-12-26 17:16:17
    去除列表项符号 在CSS中,我们也是使用list-style-type属性来去除有序列表或无序列表的列表项符号的。 语法 list-style-type:none 说明 由于列表样式比较丑,因此在实际开发中,大多数情况下我们都需要使用...

    去除列表项符号

    在CSS中,我们也是使用list-style-type属性来去除有序列表或无序列表的列表项符号的。
    语法

    list-style-type:none

    说明
    由于列表样式比较丑,因此在实际开发中,大多数情况下我们都需要使用list-style-type:none;去掉。
    举例
    浏览器效果如图所示
    分析
    使用list-style-type:none 这个小技巧可以去除列表项默认的符号,在实际开发中我们会经常遇到。

    展开全文
  • 动态添加、删除ListView列表项

    热门讨论 2012-03-18 16:16:04
    动态添加、删除ListView列表项, 对ListView的动态操作通常通过一个自定义Adapter实现添加、删除被选中的列表项,以及清空所有的列表项
  • FreeRTOS高级篇1---FreeRTOS列表和列表项

    万次阅读 多人点赞 2016-04-19 14:34:13
    我们在这一章集中讲解列表和列表项的结构以及操作函数,在下一章讲解任务创建时,会用到本章的知识点。 列表被FreeRTOS调度器使用,用于跟踪任务,处于就绪、挂起、延时的任务,都会被挂接到各自的列表中。
  • 内容比较多,没贴完,但关键的地方都在上面,点击列表项能够把loadtext显示出来,但是上下滑动之后,显示的就不是我刚刚点击的那个列表项的TextView,而是其他列表项的Textview,应该是不能在这里用ViewHolder,...
  • QComboBox 隐藏列表项

    千次阅读 2019-06-13 17:38:19
    比如一个QComboBox有四个列表项,分别是 1 2 3 4 现在需要把3隐藏,需要的时候再显示出来。 方法1: 先删掉3,需要的时候再插入,这样可能导致index变化,有时候不是很实用。 方法2: QListView* ...
  • 标签设置,其中每一个列表项使用 <li>...</li> 标签设置。 具体实例如下:???????????? <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title...
  • ListView控件如果需要增加列表项,就是在对应数据存储中插入项,这又分两种情况,一种是已知列表数据存储,一种是未知数据存储。如果是未知数据存储,可以通过: ListView控件名.model() 语句获取数据存储。在知道...
  • java-swing-列表项选择事件监听器

    千次阅读 2019-06-23 20:45:16
    这是一个有关 JList类(列表框实现类)的事件监听 事件名称:ListSelectionEvent 列表选择事件 事件监听接口:...现在以 LJist类 创建一个列表框,但选择不同时,列表框框会做出一些反应 下面是分步...
  • uniapp点击改变列表项背景颜色,再次点击可取消htmljscss html <view class="cu-card article" v-for="(item,index) in dataList" :key="index" @click="select(item,index)" :class="{ active: item.isSelect }"&...
  • Flutter进阶—质感设计之列表项

    千次阅读 2017-01-10 10:51:01
    创建achievement_view_list_item.dart文件,具体的实现每一个列表项。import 'package:flutter/material.dart'; // 创建类,成就目标 class Target { // 常量,构建函数 const Target({ // 自变量,目标名称 ...
  • Android开发:ListView 长按删除列表项两种方式

    万次阅读 多人点赞 2014-07-20 19:22:13
    在今天的开发工作当中,怎么响应长按事件(setOnItemLongClickListener)去删除一个列表项困扰了我将近一天的时间,这是初学者必须经历的。 我总结出两种方式,分享给大家参考,也希望大家能够提出自己的看法。 ...
  • 在QtDesigner中设计的界面中添加ListView控件后,是没办法添加需要在ListView控件中显示的列表项。由于ListView控件只是一个展示列表项的视图控件,实现了界面与数据的分离,其要展示的数据是单独存储在对应类型如...
  • FreeRTOS列表和列表项

    千次阅读 2017-09-05 20:39:55
    FreeRTOS 列表和列表项
  • 我想设置的功能是,当点击列表项时,列表项的颜色会改变。 我按以下的方法设计: list_item_selector.xml <selector xmlns:android="http://schemas.android.com/apk/res/android"> Selected ...
  • 原理很简单:就是在点击到列表相应单元格的时候,在相应的位置生成一个跟单元格大小相当的编辑框或者下拉列表框并贴在单元格上面而已。 实现如下: 在对话框类声明中添加如下变量和函数:头文件中添加:int e_Item; ...
  •  在FreeRTOS中,列表与列表项使用得非常多,是FreeRTOS的一个数据结构,学习过数据结构的同学都知道,数据结构能使我们处理数据更加方便快速,能快速找到数据,在FreeRTOS中,这种列表与列表项更是必不可少的,能让...
  • Python小技巧 1:列表项的拼接

    千次阅读 2016-10-15 10:26:05
    典型代码: data_list = ['a', 'b', 'c', 'd', 'e', 'f'] separator = '\t' data_joined = separator.join(data_list) ...在实现很多业务需求的时候,需要将列表中的每一按照某种分隔符拼接成一个串,以完成某种序
  • LaTeX如何生成没有缩进的数字列表项

    千次阅读 2017-08-21 16:07:27
    在本科毕业论文中,经常会遇到很多需要用数字来计数的段落,这些段落索然需要计数,但又不需要悬挂缩进,默认的LaTeX格式定制复杂,使用enumitem宏包可以完成这工作。
  • 通过CSS 列表属性可以放置、改变列表项标志,或者将图像作为列表项标志。
  • //Spinner下拉列表(可以自定义列表项的样式,可带有图片和文字得搭配使用) public class MainActivity extends Activity { private Spinner sp = null;// 下拉列表 private TextView tv = null; private ...
  • 16. android dialog ——列表项带图标的列表对话框、模拟菜单项带图标 详情参考: http://blog.csdn.net/jamesliulyc/archive/2011/04/23/6347449.aspx
  • 这里是先显示一个listview,长按listview的一个列表项,弹出一个菜单来,菜单有两个条目, “更新该条”和“删除该条”,并且这两条都有监听事件,整体就像微信好友对话操作一样。 其中菜单项有一个获取上下文的...
  • ListView显示不同类型的列表项的例子

    千次下载 热门讨论 2013-01-23 08:28:30
    在同一个ListView显示不同类型的列表项
  • 原GRUB列表项如下: 可以看到有很多根本没有用的选项,现在要做的是删除这些无用列表项,即自定义配置列表项,即配置grub.cfg文件 步骤: 进入/boot目录下,查看grub是grub1(grub)还是grub2,选择最高的进行修改...
  • Vue实现table列表项上下移动

    万次阅读 2019-01-22 17:36:56
    el-tabel 列表项实现上移,下移,删除功能 结合Element组件,scope中有三个参数(row,cow,$index)分别表示行内容、列内容、以及此行索引值, table上绑定数组 :data=“newsList”。 上移和下调两个按钮,并绑定...
  • 效果图: 使用方法: 1、在布局文件中加入ListView控件: 2、新建一个列表项布局listView_item.xml,用于设计ListView条目的样式 3、自定义数据适配器继承BaseAdapter import android.content.Context; import ...
  • Vue中使用Element组件合并相同列表项

    千次阅读 2018-09-18 13:45:20
    所以如果列表项不是很复杂的且已知的话,可以直接列举法进行合并列表项,如下所示 objectSpanMethod({ row, column, rowIndex, columnIndex }) { if (columnIndex === 0) { if (rowIndex === 0) { return { ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 969,527
精华内容 387,810
关键字:

列表项

友情链接: 彩色分割.rar