Linux嵌入式系统下编程
嵌入式系统编程在Linux平台上具有独特的要求和技术。以下是一些关键方面及相关示例代码。
GNU C和标准C的差异
GNU C是GNU Compiler Collection(GCC)中实现的C语言标准。与标准C(如C89、C99、C11)相比,GNU C提供了许多扩展和额外的功能。
-
内联汇编:GNU C允许在C代码中嵌入汇编代码。
asm ("movl %1, %0" : "=r" (result) : "r" (input));
-
变量长度数组:标准C99也支持,但GNU C在C99之前就支持了。
void func(int n) { int array[n]; }
-
嵌套函数:GNU C允许在一个函数内部定义另一个函数。
void outer_function() { void inner_function() { // Inner function code } inner_function(); }
C语言文件操作
在C语言中,文件操作通过标准库函数进行,主要包括打开、读取、写入和关闭文件。
-
打开文件:
FILE *fp = fopen("file.txt", "r");
-
读取文件:
char buffer[100]; fgets(buffer, 100, fp);
-
写入文件:
fprintf(fp, "Hello, World!\n");
-
关闭文件:
fclose(fp);
C语言的队列操作
队列是一种先进先出的数据结构。以下是一个简单的队列实现示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
typedef struct Queue {
Node *front, *rear;
} Queue;
Queue* createQueue() {
Queue *q = (Queue*)malloc(sizeof(Queue));
q->front = q->rear = NULL;
return q;
}
void enqueue(Queue *q, int data) {
Node *temp = (Node*)malloc(sizeof(Node));
temp->data = data;
temp->next = NULL;
if (q->rear == NULL) {
q->front = q->rear = temp;
return;
}
q->rear->next = temp;
q->rear = temp;
}
int dequeue(Queue *q) {
if (q->front == NULL) {
return -1;
}
int data = q->front->data;
Node *temp = q->front;
q->front = q->front->next;
if (q->front == NULL) {
q->rear = NULL;
}
free(temp);
return data;
}
C语言的链表操作
链表是一种动态数据结构。以下是一个单链表的实现示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
Node* createNode(int data) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void append(Node **head, int data) {
Node *newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
return;
}
Node *temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
void display(Node *head) {
Node *temp = head;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
C语言的排序算法
以下是一个快速排序(Quick Sort)的实现示例:
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int arr[], int low, int high) {
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (arr[j] < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
int main() {
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr) / sizeof(arr[0]);
quickSort(arr, 0, n - 1);
printf("Sorted array: \n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
C语言网络IO操作
在Linux系统中,使用套接字(socket)进行网络IO操作。以下是一个简单的客户端和服务器的实现示例:
-
服务器端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[1024] = {0}; char *hello = "Hello from server"; // 创建套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 绑定套接字 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听 if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } // 接受客户端连接 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept"); exit(EXIT_FAILURE); } read(new_socket, buffer, 1024); printf("Message from client: %s\n", buffer); send(new_socket, hello, strlen(hello), 0); printf("Hello message sent\n"); close(new_socket); close(server_fd); return 0; }
-
客户端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> int main() { struct sockaddr_in address; int sock = 0; struct sockaddr_in serv_addr; char *hello = "Hello from client"; char buffer[1024] = {0}; // 创建套接字 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n"); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); // 将地址转换为二进制形式 if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { printf("\nInvalid address/ Address not supported \n"); return -1; } // 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); return -1; } send(sock, hello, strlen(hello), 0); printf("Hello message sent\n"); read(sock, buffer, 1024); printf("Message from server: %s\n", buffer); close(sock); return 0; }
案例[C语言点对点通信系统]
下面是一个简单的点对点通信系统的实现示例,其中两个进程可以通过套接字通信:
-
服务器端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[1024] = {0}; // 创建套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 绑定套接字 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听 if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } printf("Waiting for connections...\n"); // 接受客户端连接 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept"); exit(EXIT_FAILURE); } printf("Connection accepted\n"); while (1) { memset(buffer, 0, sizeof(buffer)); read(new_socket, buffer, 1024); printf("Client: %s\n", buffer); if (strcmp(buffer, "exit") == 0) { printf("Connection closed by client\n"); break; } printf("Enter message: "); fgets(buffer, 1024, stdin); buffer[strcspn(buffer, "\n")] = 0; // 移除换行符 send(new_socket, buffer, strlen(buffer), 0); if (strcmp(buffer, "exit") == 0) { printf("Connection closed\n"); break; } } close(new_socket); close(server_fd); return 0; }
-
客户端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> int main() { struct sockaddr_in address; int sock = 0; struct sockaddr_in serv_addr; char buffer[1024] = {0}; // 创建套接字 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n"); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); // 将地址转换为二进制形式 if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { printf("\nInvalid address/ Address not supported \n"); return -1; } // 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); return -1; } printf("Connected to server\n"); while (1) { printf("Enter message: "); fgets(buffer, 1024, stdin); buffer[strcspn(buffer, "\n")] = 0; // 移除换行符 send(sock, buffer, strlen(buffer), 0); if (strcmp(buffer, "exit") == 0) { printf("Connection closed\n"); break; } memset(buffer, 0, sizeof(buffer)); read(sock, buffer, 1024); printf("Server: %s\n", buffer); if (strcmp(buffer, "exit") == 0) { printf("Connection closed by server\n"); break; } } close(sock); return 0; }