《嵌入式系统原理与应用》习题

更新时间: 试题数量: 购买人数: 提供作者:

有效期: 个月

章节介绍: 共有个章节

收藏
搜索
题库预览
下面是一段UDP服务器端程序,请补齐代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
static unsigned short port = 8000;
int main(int argc, char *argv[])
{
int recvNum = 0; //接收数据包计数器
char *recvBuffer = (char *)malloc(4002); //接收缓冲区(4000字节+2字节冗余)
int listenfd;
struct sockaddr_in serverAddr, clientAddr; //服务器和客户端地址结构
printf("TCP Echo Server Started\n"); //提示信息
listenfd = socket(AF_INET, SOCK_DGRAM, 0);
if (listenfd == -1)
{
printf("Invalid socket\n");
exit(1);
}
bzero(&serverAddr, sizeof(serverAddr)); //清零结构体
serverAddr.sin_family = AF_INET; //地址族:IPv4
serverAddr.sin_port = htons(port); //端口号(主机字节序转网络字节序)
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); //绑定到所有网络接口
printf("Binding server socket to port %d\n", port);
if (bind(listenfd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1)
{
printf("Bad bind\n");
exit(1);
}
for (;;) //无限循环
{
ssize_t len; //接收到的数据长度
socklen_t clientAddrLen = sizeof(clientAddr); //客户端地址结构长度
printf("(%03d)================================\n", recvNum++);
printf("Waiting for data...\n");
//接收数据
len = recvfrom(listenfd, recvBuffer, 4000, 0,
(struct sockaddr *)&clientAddr, &clientAddrLen);
recvBuffer[len] = '\0'; //添加字符串结束符,方便打印
printf("Received: %s\n", recvBuffer);
//发送回同样数据(回声)
sendto(listenfd, recvBuffer, len, 0,
(struct sockaddr *)&clientAddr, sizeof(clientAddr));
//如果收到"exit",则退出循环
if (strcmp(recvBuffer, "exit") == 0)
break;
}
close(listenfd); //关闭套接字
exit(0); //正常退出
}
驱动源码 led.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/device.h> //class_create
#define DEVICE_NAME "LED"
#define SSPV210_GPJ2_0_OUTP (1<<0)
#define SSPV210_GPJ2_1_OUTP (1<<4)
#define SSPV210_GPJ2_2_OUTP (1<<8)
#define SSPV210_GPJ2_3_OUTP (1<<12)
static struct class *led_class;
static struct device *led_device;
int major;
static volatile unsigned long *gpj2con = NULL;
static volatile unsigned long *gpj2dat = NULL;
/* 应用程序执行 open 时,最终调用到驱动程序的 webee210_led_open 函数 */
static int webee210_led_open(
struct inode *inode,
struct file *filp)
{
printk("webee210_led_open\n");
/* Webee210 开发板上的 LED1,LED2,LED3,LED4
* 对应 GPJ2_0、GPJ2_1、GPJ2_2、GPJ2_3 引脚
* 配置 GPJ2_0、GPJ2_1、GPJ2_2、GPJ2_3 为输出
*/
*gpj2con |= SSPV210_GPJ2_0_OUTP
|SSPV210_GPJ2_1_OUTP
|SSPV210_GPJ2_2_OUTP
|SSPV210_GPJ2_3_OUTP;
return 0;
}
/* 应用程序执行 write 时,最终调用到驱动程序的 webee210_led_write 函数 */
static int webee210_led_write(
struct file *file,
const char __user *buffer,
size_t count,
loff_t *ppos)
{
int val;
printk("webee210_led_write\n");
copy_from_user(&val, buffer, count);
if (val == 1)
{/*点灯*/
*gpj2dat &= ~( (1<<0) | (1<<1) | (1<<2) | (1<<3));
}
else
{/*灭灯*/
*gpj2dat |= (1<<0) | (1<<1) | (1<<2) | (1<<3);
}
return 0;
}
static const struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = webee210_led_open,
.write = webee210_led_write,
};
/* 驱动程序的入口函数 */
static int __init Webee210_led_init(void)
{
/* 注册字符设备,第一个参数设置为 0 表示由系统自动分配主设备号 */
major = register_chrdev(0, "led_drv", &led_fops);
/* 创建 led_drv 类 */
led_class = class_create(THIS_MODULE, "led_drv");
/* 在 led_drv 类下创建/dev/LED 设备,供应用程序打开设备*/
led_device = device_create(led_class,NULL, MKDEV(major, 0), NULL,
DEVICE_NAME);
/* 将物理地址映射为虚拟地址 */
gpj2con = (volatile unsigned long *)ioremap(0xE0200280, 16);
gpj2dat = gpj2con + 1;
return 0;
}
/* 驱动程序的出口函数 */
static void __exit Webee210_led_exit(void)
{
unregister_chrdev(major,"led_drv"); /* 注销字符设备 */
device_unregister(led_device); /* 卸载类下的设备 */
class_destroy(led_class); /* 卸载类 */
iounmap(gpj2con); /* 解除映射 */
}
/* 用于修饰入口/出口函数,换句话说,相当于
* 告诉内核驱动程序的入口/出口函数在哪里
*/
module_init(Webee210_led_init);
module_exit(Webee210_led_exit);
/* 该驱动支持的协议、作者、描述 */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("webee");
MODULE_DESCRIPTION("Character drivers for leds");
测试程序源码 led_test.c
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
/* led_test on
* led_test off
*/
int main(int argc ,char *argv[])
{
int fd;
int val = 0;
fd = open("/dev/LED",O_RDWR);
if (fd < 0)
{
printf("open error\n");
}
if (argc != 2)
{
printf("Usage:\n");
printf("%s <on|off>\n",argv[0]);
return 0;
}
if (strcmp(argv[1],"on",2) == 0)
val = 1;
else if (strcmp(argv[1],"off",3) == 0)
val = 0;
write(fd,&val,4);
return 0;
}【缺少答案,请补充】
以下是led-driver程序,请分别解释ssize_t gpio_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);ssize_t gpio_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)函数的功能并说明每一个参数的含义。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/vmalloc.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank.h>
#include <mach/gpio.h>
#include <linux/device.h>
/* class_create, device_create */
#define GPIO_DEV_NAME "s5pv210-led"
#define GPJ2CON (S5PV210_GPJ2_BASE + 0x00)
#define GPJ2DAT (S5PV210_GPJ2_BASE + 0x04)
#define GPJ2PUD (S5PV210_GPJ2_BASE + 0x08)
#define GPJ2DRV (S5PV210_GPJ2_BASE + 0x0C)
ssize_t gpio_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
unsigned long val = 0;
val = __raw_readl(GPJ2DAT);
val &= 0xFF;
copy_to_user(buf, &val, 1);
return 1;
}
ssize_t gpio_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
unsigned long val = 0;
copy_from_user(&val, buf, 1);
__raw_writel(val, GPJ2DAT);
return 1;
}
struct file_operations gpio_fops = {
.owner = THIS_MODULE,
.read = gpio_read,
.write = gpio_write,
};
static int gpioMajor = 0;
static struct class *gpioClass;
static struct device *gpioDevice;
int led_init(void)
{
gpioMajor = register_chrdev(0, GPIO_DEV_NAME, &gpio_fops);
if(gpioMajor < 0)
return gpioMajor;
gpioClass = class_create(THIS_MODULE, "led");
if(gpioClass == NULL)
{
unregister_chrdev(gpioMajor, GPIO_DEV_NAME);
return -1;
}
gpioDevice = device_create(gpioClass, NULL, MKDEV(gpioMajor, 0), NULL, "led");
if(gpioDevice == NULL)
{
class_destroy(gpioClass);
unregister_chrdev(gpioMajor, GPIO_DEV_NAME);
return -1;
}
//设置GPJ2的8个I/O口为输出
__raw_writel(0x11111111, GPJ2CON);
return 0;
}
void led_exit(void)
{
device_destroy(gpioClass, MKDEV(gpioMajor, 0));
class_destroy(gpioClass);
unregister_chrdev(gpioMajor, GPIO_DEV_NAME);
return;
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("Dual BSD/GPL");
功能:gpio_write()从用户空间接收数据,写入GP10数据寄存器以控制LED状态。gpio_read()从GP10数据寄存器读取当前状态,并将数据传递给用户空间。