一、结构体,枚举,共用体
1、结构体的定义,结构体类似数组,一段连续的地址空间,定义后,空间大小不可更改,但是比数组不同的是,结构体数据类型,可以都不一样,可以定义任何类型,嵌套各种指针。
struct pnode {
unsigned int sn;
NODEINFO nodeinfo;
BOOL loop;
struct pnode *next;
struct pnode *previous;
};
typedef struct { // typedef 重命名一个结构体类型,结构体大多数是这么用,
struct pnode *head;
struct pnode *tail;
struct pnode *cur;
WORD mode;
WORD MaxFile;
} list_info ,*_p_list_info ;
list_info my_list_info ; //定义一个list_info 类型的 结构体
_p_list_info p_list_info; //定义一个结构体指针
p_list_info = &my_list_info; //指向这个结构体
结构体赋值,结构体数组,成员赋值
typedef struct {
WORD menu_id;
const WORD* icon;
BYTE val;
next_menu next;
menu_title title;
BOOL corr_sys_paras;
}menu_format;
menu_format const menu_app_photocap[] = {//在定义结构体变量时,可以这样全部成员赋值
{
.menu_id = MENU_ID_PHOTOCAP_SET,
.icon = (WORD*)IconMenuPhotoCap,
.next.menu = menu_photocap_item,
.next.menu_size = sizeof(menu_photocap_item)/sizeof(menu_recorder_item[0]),
.title.icon_str_id = ICON_ST_PHOTOCAP,
},
{
.menu_id = MENU_ID_SYS_SET,
.icon = (WORD*)IconMenuSetup,
.next.menu = menu_sys_item,
.next.menu_size = sizeof(menu_sys_item)/sizeof(menu_sys_item[0]),
.title.icon_str_id = ICON_ST_SYS_SET,
},
};
在定义结构体变量时,可以这样全部成员赋值,和数组一样,定义后,使用时,不能全部一起赋值,需要一个一个成员赋值,a[1] = b[1],
SX_S8 * pszSendBuf = (SX_S8 *)malloc( UDP_MAX_LEN );//申请一大段内存
memset(pszSendBuf,0,UDP_MAX_LEN);
PT_DataPkt_1 pkt = (PT_DataPkt_1)(pszSendBuf); //将这段内存,强制类型转换成结构体类型,按结构体来解析
pkt->u32Sync = PKT_SYNC;
pkt->u8Cmd = CMD_ACK_BIT1;
pkt->u32DataLen = sizeof(T_BIT_1);
pkt->u32totalPktNum = 1;
pkt->u32currretPkt = 1;
pkt->CRC32 = 0xC4C3C2C1;
//file data
memset((SX_U8 *)(&pkt->BITData), 0, sizeof(T_BIT_1) );
pkt->BITData.u8head = 12;
pkt->BITData.u8SoftwareRev = (SX_U8)software_reversion;
pkt->BITData.u8reserv0 = 0;
pkt->BITData.u8reserv1 = 0;
pkt->BITData.u8devicetype = (SX_U8)U8DeviceType;
pkt->BITData.u8devicestatus = (SX_U8)client_fpga_status;
pkt->BITData.u16packnum = u16packnum;
memset( pkt->BITData.u8reserver2, 0, sizeof(pkt->BITData.u8reserver2) );
ret = Bit_Server_Send1(handle->ptClientBIT1, (SX_S8 *)pkt, sizeof(T_DataPkt_1));//将结构体,类型强制成一个字节,通过网络发送出去,发送字符时,都一个一个字节传送,对方收到时,用结构体类型,解析,就可以还原了
SX_S32 Bit_Server_Send1(PT_CLIENT handle, void *buf, SX_S32 len)
{
if( handle == NULL || len <= 0 || len > UDP_MAX_LEN )
{
TRACE(DL_ERROR, "DL_ERROR\n");
return 0;
}
SX_S32 length;
if( buf )
{
length = MIN(len, UDP_MAX_LEN);
return sendto( handle->sockfd, (const SX_S8 *)buf, length, 0, (struct sockaddr *)&(handle->cliaddr2), sizeof(handle->cliaddr2) );
}
}
2、枚举enum,将所有的值,列举出来,比如,各种可以操作的id,返回给系统
定义一个enum变量的,规则
enum myenum{
aaa,
bbb,
ccc
}
enum myenum my_num ;
枚举变量,占用4个字节,有的是占用8个字节,字符串常量,分配在特定区域,定义枚举是,就是一个指针变量,在编译,将代码里枚举出来的,字符串,全部进行替换,0,1,2,3,4,,,定义的枚举,变量,绑定到一个起始地址,这个地址,存放,1.2.3.4.5,6.,而不是下面这些字符串,这只是给人看的,这个地址可以很长,向数组一样,看初始化的值了,如果是655536,一个就是int型,10个,就需要10个int型
typedef enum {
MENU_ID_NONE = 0, //系统默认第一个是0,其他是1,2。。。,也可以自己定义,随便一个数
MENU_ID_REC_SET,
MENU_ID_PHOTOCAP_SET,
MENU_ID_PLAYBACK_SET,
MENU_ID_SYS_SET,
MENU_ID_WIFI_ID,
MENU_ID_WIFI_PASSWORD,
}enum
第一种,是枚举,进行配置,在不同项目,可以值修改enum的配置初始值,
typedef enum {
UDP_PORT_LOCAL = 10001,
UDP_PORT_BIT2 = 10002,
UDP_PORT_CFG = 10003,
}E_UDP_PORT;
typedef enum {
VIDEO_BITRATE_500K = 0,
VIDEO_BITRATE_1M = 1,
VIDEO_BITRATE_2M = 2,
VIDEO_BITRATE_3M = 3,
VIDEO_BITRATE_4M = 4,
VIDEO_BITRATE_5M = 5,
}E_VIDEO_BITRATE;
typedef enum {
SW_OFF = 0,
SW_ON= 1,
}E_SW;
menu_format const menu_app_recorder[] = {
#ifndef LCD_320_240
{
.menu_id = MENU_ID_REC_SET, //进行赋值配置
.icon = (WORD*)IconMenuSetup,
.next.menu = menu_DVR_item,
.next.menu_size = sizeof(menu_DVR_item)/sizeof(menu_DVR_item[0]),
.title.icon_str_id = NULL,
},
#else
{
.menu_id = MENU_ID_REC_SET, //进行赋值
.icon = (WORD*)IconMenuRecorder,
.next.menu = menu_DVR_320_240_item,
.next.menu_size = sizeof(menu_DVR_320_240_item)/sizeof(menu_DVR_320_240_item[0]),
.title.icon_str_id = ICON_ST_RECORDER,
},
#endif
第二种是根据枚举返回的,状态,选择对应操作
state =
switch(state) {
default:
case 0:
pTireIcon = IconTpmsTireFull;
break;
case 1:
pTireIcon = IconTpmsTireOverflow;
break;
case 2:
pTireIcon = IconTpmsTireLow85;
break;
case 3:
pTireIcon = IconTpmsTireLow75;
break;
case 4:
pTireIcon = IconTpmsTireLow50;
break;
case 5:
3、共用体 union,所有变量,共用一块内存地址,用其中一个字节最大的成员,进行分配地址,之所以共用,是不知道数据类型,char,int,double都可以用,强制类型转换,就可以接受各种数据类型了,
定义规则
union myunion {
}
union myunion dat_union
typedef union MediumEmifHead //struct
{
struct{
char u8Cmd;
long long LenH;
}BITS;
int s32Value;
long long LenH;
char u8LenH[13];
}T_MediumEmifHead, *PT_MediumEmifHead;
最大的是结构体,所以这个union的大小,就是结构体大小,16个字节
三、嵌套
typedef struct {
combo_dev_t devno; /* device number */
input_mode_t input_mode; /* input mode: MIPI/LVDS/SUBLVDS/HISPI/DC */
mipi_data_rate_t data_rate;
/* MIPI Rx device crop area (corresponding to the oringnal sensor input image size) */
img_rect_t img_rect;
union {
mipi_dev_attr_t mipi_attr;
lvds_dev_attr_t lvds_attr;
slvs_dev_attr_t slvs_attr;
lvds_dev_attr_ex_t lvds_attr_ex;
};
} combo_dev_attr_t;
typedef struct {
data_type_t input_data_type; /* data type: 8/10/12/14/16 bit */
mipi_wdr_mode_t wdr_mode; /* MIPI WDR mode */
short lane_id[MIPI_LANE_NUM]; /* lane_id: -1 - disable */
union {
short data_type[WDR_VC_NUM]; 数据也可以枚举,不用事先定义大小,
};
} mipi_dev_attr_t;
combo_dev_attr_t MIPI_1lane_CHN0_ADV7280AWBCPZ_M_NOWDR_ATTR =
{
.devno = 0,
.input_mode = INPUT_MODE_MIPI,
.data_rate = MIPI_DATA_RATE_X1,
.img_rect = {0, 0, 720, 576},
{
.mipi_attr =
{
DATA_TYPE_YUV422_8BIT, //DATA_TYPE_YUV422_8BIT, //DATA_TYPE_YUV420_8BIT_NORMAL DATA_TYPE_RAW_8BIT
HI_MIPI_WDR_MODE_NONE,
{0, -1, -1, -1, -1, -1, -1, -1}
}
}
};
**四、模仿 linux驱动代码,结构体,实现面向对象**
```c
struct wm8350_gpio_data {
struct wm8350 *wm8350;
struct gpio_chip gpio_chip;
};
static inline struct wm8350_gpio_data *to_wm8350_gpio(struct gpio_chip *chip)
{
return container_of(chip, struct wm8350_gpio_data, gpio_chip);
}
static int wm8350_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
{
struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
struct wm8350 *wm8350 = wm8350_gpio->wm8350;
return wm8350_set_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
1 << offset);
}
static int wm8350_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
struct wm8350 *wm8350 = wm8350_gpio->wm8350;
int ret;
ret = wm8350_reg_read(wm8350, WM8350_GPIO_LEVEL);
if (ret < 0)
return ret;
if (ret & (1 << offset))
return 1;
else
return 0;
}
static void wm8350_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
struct wm8350 *wm8350 = wm8350_gpio->wm8350;
if (value)
wm8350_set_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
else
wm8350_clear_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
}
static int wm8350_gpio_direction_out(struct gpio_chip *chip,
unsigned offset, int value)
{
struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
struct wm8350 *wm8350 = wm8350_gpio->wm8350;
int ret;
ret = wm8350_clear_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
1 << offset);
if (ret < 0)
return ret;
/* Don't have an atomic direction/value setup */
wm8350_gpio_set(chip, offset, value);
return 0;
}
static int wm8350_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
struct wm8350 *wm8350 = wm8350_gpio->wm8350;
if (!wm8350->irq_base)
return -EINVAL;
return wm8350->irq_base + WM8350_IRQ_GPIO(offset);
}
static struct gpio_chip template_chip = {
.label = "wm8350",
.owner = THIS_MODULE,
.direction_input = wm8350_gpio_direction_in,
.get = wm8350_gpio_get,
.direction_output = wm8350_gpio_direction_out,
.set = wm8350_gpio_set,
.to_irq = wm8350_gpio_to_irq,
.can_sleep = true,
};
static int wm8350_gpio_probe(struct platform_device *pdev)
{
struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent);
struct wm8350_platform_data *pdata = dev_get_platdata(wm8350->dev);
struct wm8350_gpio_data *wm8350_gpio;
int ret;
wm8350_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm8350_gpio),
GFP_KERNEL);
if (wm8350_gpio == NULL)
return -ENOMEM;
wm8350_gpio->wm8350 = wm8350;
wm8350_gpio->gpio_chip = template_chip;
wm8350_gpio->gpio_chip.ngpio = 13;
wm8350_gpio->gpio_chip.dev = &pdev->dev;
if (pdata && pdata->gpio_base)
wm8350_gpio->gpio_chip.base = pdata->gpio_base;
else
wm8350_gpio->gpio_chip.base = -1;
ret = gpiochip_add(&wm8350_gpio->gpio_chip);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, wm8350_gpio);
return ret;
}
static int wm8350_gpio_remove(struct platform_device *pdev)
{
struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev);
gpiochip_remove(&wm8350_gpio->gpio_chip);
return 0;
}
static struct platform_driver wm8350_gpio_driver = {
.driver.name = "wm8350-gpio",
.driver.owner = THIS_MODULE,
.probe = wm8350_gpio_probe,
.remove = wm8350_gpio_remove,
};
static int __init wm8350_gpio_init(void)
{
return platform_driver_register(&wm8350_gpio_driver);
}
subsys_initcall(wm8350_gpio_init);
static void __exit wm8350_gpio_exit(void)
{
platform_driver_unregister(&wm8350_gpio_driver);
}
module_exit(wm8350_gpio_exit);
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_DESCRIPTION("GPIO interface for WM8350 PMICs");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:wm8350-gpio");
2、
/* linux/drivers/char/scx200_gpio.c
National Semiconductor SCx200 GPIO driver. Allows a user space
process to play with the GPIO pins.
Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/scx200_gpio.h>
#include <linux/nsc_gpio.h>
#define DRVNAME "scx200_gpio"
static struct platform_device *pdev;
MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
MODULE_DESCRIPTION("NatSemi/AMD SCx200 GPIO Pin Driver");
MODULE_LICENSE("GPL");
static int major = 0; /* default to dynamic major */
module_param(major, int, 0);
MODULE_PARM_DESC(major, "Major device number");
#define MAX_PINS 32 /* 64 later, when known ok */
struct nsc_gpio_ops scx200_gpio_ops = {
.owner = THIS_MODULE,
.gpio_config = scx200_gpio_configure,
.gpio_dump = nsc_gpio_dump,
.gpio_get = scx200_gpio_get,
.gpio_set = scx200_gpio_set,
.gpio_change = scx200_gpio_change,
.gpio_current = scx200_gpio_current
};
EXPORT_SYMBOL_GPL(scx200_gpio_ops);
static int scx200_gpio_open(struct inode *inode, struct file *file)
{
unsigned m = iminor(inode);
file->private_data = &scx200_gpio_ops;
if (m >= MAX_PINS)
return -EINVAL;
return nonseekable_open(inode, file);
}
static int scx200_gpio_release(struct inode *inode, struct file *file)
{
return 0;
}
static const struct file_operations scx200_gpio_fileops = {
.owner = THIS_MODULE,
.write = nsc_gpio_write,
.read = nsc_gpio_read,
.open = scx200_gpio_open,
.release = scx200_gpio_release,
.llseek = no_llseek,
};
static struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */
static int __init scx200_gpio_init(void)
{
int rc;
dev_t devid;
if (!scx200_gpio_present()) {
printk(KERN_ERR DRVNAME ": no SCx200 gpio present\n");
return -ENODEV;
}
/* support dev_dbg() with pdev->dev */
pdev = platform_device_alloc(DRVNAME, 0);
if (!pdev)
return -ENOMEM;
rc = platform_device_add(pdev);
if (rc)
goto undo_malloc;
/* nsc_gpio uses dev_dbg(), so needs this */
scx200_gpio_ops.dev = &pdev->dev;
if (major) {
devid = MKDEV(major, 0);
rc = register_chrdev_region(devid, MAX_PINS, "scx200_gpio");
} else {
rc = alloc_chrdev_region(&devid, 0, MAX_PINS, "scx200_gpio");
major = MAJOR(devid);
}
if (rc < 0) {
dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc);
goto undo_platform_device_add;
}
cdev_init(&scx200_gpio_cdev, &scx200_gpio_fileops);
cdev_add(&scx200_gpio_cdev, devid, MAX_PINS);
return 0; /* succeed */
undo_platform_device_add:
platform_device_del(pdev);
undo_malloc:
platform_device_put(pdev);
return rc;
}
static void __exit scx200_gpio_cleanup(void)
{
cdev_del(&scx200_gpio_cdev);
/* cdev_put(&scx200_gpio_cdev); */
unregister_chrdev_region(MKDEV(major, 0), MAX_PINS);
platform_device_unregister(pdev);
}
module_init(scx200_gpio_init);
module_exit(scx200_gpio_cleanup);