#ifndef __SHMEM_H

//T536 共享内存地址
//1. linux核->裸核空间定义如下：
#define SHM_ADDR_D_FREQ_TR              	0x00000000 //频率跟踪
#define SHM_ADDR_D_RFV_1              		0x00000040 //第一片AD7616参考电压范围
#define SHM_ADDR_D_RFV_2              		0x00000080 //第二片AD7616参考电压范围
#define SHM_ADDR_D_RFV_3              		0x000000C0 //第三片AD7616参考电压范围
#define SHM_ADDR_D_RFV_4              		0x00000100 //第四片AD7616参考电压范围
#define SHM_ADDR_D_TIME              		0x00001000 //系统时间 linux向裸核校时
#define SHM_ADDR_D_HB              			0x00001040 //心跳

struct shmem_block {
	unsigned short flag;
	unsigned short crc;
	unsigned int len;
	unsigned char data[];
} __attribute__((__packed__));

struct shmem_fd {
	int fd;
	int shmem_len;
	
	struct shmem_block *linux_write;
	struct shmem_block *linux_read;

	int linux_write_len, linux_read_len;
	int linux_write_data_len, linux_read_data_len;
};

extern struct shmem_fd shmem_fd;

#define shmem_code_len			8	/* 8 = flag(2) + crc(2) + len(4) */

#define max_shmem_wr_len(s)		((s) / 2)
#define max_shmem_rd_len(s)		((s) / 2)
#define max_shmem_wr_data_len(s)	(max_shmem_wr_len(s) - shmem_code_len)	
#define max_shmem_rd_data_len(s)	(max_shmem_rd_len(s) - shmem_code_len)

/**
 * 参数 waiting 说明：
 * waiting 的单位为“微秒”
 * 如果 waiting < 0 ，则会一直等待，直到数据可读/可写
 * 如果 waiting == 0 ，则仅检查一次数据是否可读/可写，不可以则返回 -ETIMEOUT
 * 如果 waiting > 0 ，则检查一次数据是否可读/可写，等待 waiting 后，再检查一次，
 * 不可以则返回 -ETIMEOUT
 */

int shmem_read_crc(struct shmem_fd *shmem_fd, void *buf, int len, 
		   int waiting, unsigned short *crc);
int shmem_write_crc(struct shmem_fd *shmem_fd, void *buf, int len,
		    int waiting, unsigned short *crc);
int shmem_read(struct shmem_fd *shmem_fd, void *buf, int len, int waiting);
int shmem_write(struct shmem_fd *shmem_fd, void *buf, int len, int waiting);

int shmem_init(struct shmem_fd *shmem_fd);
void shmem_exit(struct shmem_fd *shmem_fd);

#endif // !__SHMEM_H

