skaiuijing

程序的的精髓在于数据结构

程序 = 数据结构 + 算法。借用linus的一句话:“Bad programmers worry about the code. Good programmers worry about data structures and their relationships.”

为了说明数据结构是怎样构成一个操作系统坚不可摧的基石的,笔者将调试FreeRTOS内核的消息队列,看看数据结构在其中发挥了怎样的作用。

从消息队列深入到FreeRTOS内核数据结构设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

struct AMessage
{
char ucMessageID;
char ucData[ 20 ];
} xMessage;


QueueHandle_t xStructQueue = NULL;


void vCreateQueues( void )
{
xMessage.ucMessageID = 0xab;
memset( &( xMessage.ucData ), 0x12, 20 );

/* Create the queue used to send complete struct AMessage structures. This can
also be created after the schedule starts, but care must be task to ensure
nothing uses the queue until after it has been created. */
xStructQueue = xQueueCreate(
/* The number of items the queue can hold. */
1,
/* Size of each item is big enough to hold the<br /> whole structure. */
sizeof( xMessage ) );

}

/* Task that writes to the queues. */
void vATask( void *pvParameters )
{
struct AMessage *pxPointerToxMessage;

/* Send the entire structure to the queue created to hold 10 structures. */
xQueueSend( /* The handle of the queue. */
xStructQueue,
/* The address of the xMessage variable. sizeof( struct AMessage )
bytes are copied from here into the queue. */
( void * ) &xMessage,
/* Block time of 0 says don't block if the queue is already full.
Check the value returned by xQueueSend() to know if the message
was sent to the queue successfully. */
( TickType_t ) 0 );

/* Store the address of the xMessage variable in a pointer variable. */
pxPointerToxMessage = &xMessage;

/* Send the address of xMessage to the queue created to hold 10 pointers. */
xQueueSend( /* The handle of the queue. */
xStructQueue,

( void * ) &pxPointerToxMessage,
( TickType_t ) 5 );

/* ... Rest of task code goes here. */
}

/* Task that reads from the queues. */
void vADifferentTask( void *pvParameters )
{



}





void *a = NULL;
void led_bright( )
{
while (1) {
vATask( a );

/*
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
vTaskDelay(1000);
*/
}
}

void led_extinguish()
{ struct AMessage pxRxedPointer;
while (1) {


xQueueReceive( xStructQueue,
&( pxRxedPointer ),
( TickType_t ) 10 ) ;

/*
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
vTaskDelay(500);
*/

}
}

void APP( )
{
vCreateQueues();
handle1 = xTaskCreate( led_bright,
"led_bright",
256,
NULL,
3,
&led_bright_handle
);

handle2 = xTaskCreate( led_extinguish,
"led_extinguish",
256,
NULL,
2,
&led_extinguish_handle
);


}

1
2
3
4
5
6
7
8
9

p self->IPC_node->thelist
p SendTask->IPC_node.thelist

p CurrentTCB->IPC_node.thelist
p queue->SendList.head->thelist
p queue->SendList.tail
p SendTask->IPC_node
p queue->SendList.head->value