本文主要是围绕数码管的显示、ADC温度采集、按键,eeprom,以太网,当温度的值超过
设定的阈值后,数码管闪烁,按键可以调节温度的上、下限,温度可以通过以太网的tcp协议传输,本机是server,只需要一个client进行连接接收数据。
其中,板载的按键可以加热发热电阻进行场景的测试。
注:涉及到驱动文件imx_key.ko lradc.ko可以自己编写或者在我的资源中下载。在编译过程中,对数函数的编译加上 -lm ,多线程的编译加上 -pthread
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <math.h>
#include "lradc.h"
#include <errno.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#define KEY_A 30
#define KEY_B 48
#define KEY_C 46
#define KEY_D 32
#define KEY_E 18
#define portnumber 8500
#define buffer_size 10
/* -------mutex valibale ---------*/
pthread_mutex_t mutex_r,mutex_w;
char read_flag,write_flag;
void read_pthread(void);
void write_pthread(void);
/*-------Glocal read/write data ----------------*/
char read_buffer[buffer_size];
char write_buffer[buffer_size];
/*-------Glocal conncetion ID-------------*/
int new_fd;
int sockfd;
int num ;
#define PORT 5000 // The port which is communicate with server
#define BACKLOG 10
#define LENGTH 512 // Buffer length
#define LRADC_DEV "/dev/magic-adc" /* adc设备文件名*/
#define CMD_VOLTAGE IMX28_ADC_CH0 /* 通道0读取命令*/
#define CMD_TEMPTURE IMX28_ADC_CH1 /* 通道1通读读取命令*/
#define R33 2000
#define V_ADC 3.3
//#define T1 (273.15 + 25)
#define R1 27600
#define B 3435*1000
#define I2C_SLAVE 0x0703
#define I2C_ADDR 0xA0 /* EEPROM的从机地址*/
#define I2C_DEV_NAME "/dev/i2c-1" /* I2C总线设备文件*/
#define DATA_ADDR 0x00 /* 保存温度的起始地址*/
#define SPI_DEVICE "/dev/spidev1.0"
#define GPIO_DEVICE "/sys/class/gpio/gpio117/value" // gpio3.21的属性文件
#define GPIO117_SET_VAL_H "1"
#define SYSFS_GPIO_EXPORT "/sys/class/gpio/export"
#define SYSFS_GPIO_RST_PIN_VAL "117"
#define SYSFS_GPIO_RST_DIR "/sys/class/gpio/gpio117/direction"
#define SYSFS_GPIO_RST_DIR_VAL "OUT"
#define SYSFS_GPIO_RST_VAL "/sys/class/gpio/gpio117/value"
#define ADC_DEV "/dev/magic-adc"
#define ADC_MODULE_PATH "/root/lradc.ko"/* ADC驱动模块的默认路径*/
#define DIGITRON_ON 1 /* 使能数码管显示*/
#define DIGITRON_OFF 0 /* 禁能数码管显示*/
#define DEV_NAME "/dev/input/event1"
#define KEY_MODULE_PATH "/root/imx_key.ko"
//#define DEVICE_NAME "/dev/input/event1"
#define TRIGGER "trigger"
#define BEEP_DEV "/sys/devices/platform/mxs-leds.0/leds/beep" /* 蜂鸣器设备属性文件路径*/
pthread_mutex_t numlock = PTHREAD_MUTEX_INITIALIZER;/* 静态初始化互斥量*/
pthread_mutex_t numlock1 = PTHREAD_MUTEX_INITIALIZER;/* 静态初始化互斥量*/
static int beep_fd;
static int fd;
static int show_value[4] ;/* 保存要显示的信息*/
static int is_show = DIGITRON_ON;/* 保存是否使能数码管显示*/
static int i2c_fd;
static pthread_mutex_t mutex;
static int fd;
static uint8_t mode= 0;
static uint8_t bits = 8;
static uint32_t speed = 10000;
static uint16_t delay = 0;
static int fd_spi;
static int fd_gpio;
uint8_t led_value_table[] = {0xC0, 0xF9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
uint16_t temp1[2];
typedef int (*key_callback)(int value);
int gpio117_up(void)
{
int fd;
//打开端口/sys/class/gpio# echo 117 > export
fd = open(SYSFS_GPIO_EXPORT, O_WRONLY);
if(fd == -1)
{
printf("ERR: Radio hard reset pin open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_GPIO_RST_PIN_VAL ,sizeof(SYSFS_GPIO_RST_PIN_VAL));
close(fd);
//设置端口方向/sys/class/gpio/gpio117# echo out > direction
fd = open(SYSFS_GPIO_RST_DIR, O_WRONLY);
if(fd == -1)
{
printf("ERR: Radio hard reset pin direction open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_GPIO_RST_DIR_VAL, sizeof(SYSFS_GPIO_RST_DIR_VAL));
close(fd);
//输出复位信号: 拉高>100ns
fd = open(SYSFS_GPIO_RST_VAL, O_RDWR);
if(fd == -1)
{
printf("ERR: Radio hard reset pin value open error.\n");
return EXIT_FAILURE;
}
while(1)
{
write(fd, GPIO117_SET_VAL_H, sizeof(GPIO117_SET_VAL_H));
usleep(100);
//write(fd, SYSFS_GPIO_RST_VAL_L, sizeof(SYSFS_GPIO_RST_VAL_L));
//usleep(1000000);
}
close(fd);
return 0;
}
int init_gpio117(void )
{
int ret;
pthread_t thread_gpio117;
ret = pthread_create(&thread_gpio117, PTHREAD_CREATE_JOINABLE, (void *)gpio117_up, NULL);
if (ret) {
printf("create gpio117 thread faile \n");
return -1;
}
}
int get_temperature_from_eeprom(int *min_temperature, int *max_temperature){
char buf[3];
int len;
int ret = 0;
pthread_mutex_lock(&mutex);
buf[0] = DATA_ADDR;
len = write(i2c_fd, buf, 1);
if (len < 0) {
printf("write data addr faile \n");
ret = -1;
goto out;
}
len = read(i2c_fd, buf, 3);
if (len < 0) {
printf("read data faile \n");
ret = -1;goto out;
}
*min_temperature = (int)buf[0];
*max_temperature = (int)buf[1];/* 如果在0x02地址没有读出0xAA表示EEPROM还没有写入最低/最高安全温度*/
if (buf[2] != 0xAA) {
ret = -2;
goto out;
}
out:
pthread_mutex_unlock(&mutex);
return ret;
}
int set_temperature_to_eeprom(int min_temperature, int max_temperature){
char buf[4];
int len;
int ret = 0;
pthread_mutex_lock(&mutex);
buf[0] = DATA_ADDR;
buf[1] = (char)min_temperature;
buf[2] = (char)max_temperature;
buf[3] = 0xAA;
len = write(i2c_fd, buf, 4);
if (len < 0) {
printf("write data faile \n");
ret = -1;
goto out;
}
usleep(1000);
out:
pthread_mutex_unlock(&mutex);
return ret;
}
int init_eeprom(void){
int ret;
int T1, T2;
i2c_fd = open(I2C_DEV_NAME, O_RDWR);/* 打开I2C1总线设备*/
if(i2c_fd < 0) {
printf("open %s failed\r\n", I2C_DEV_NAME);
return -1;
}
ret = ioctl(i2c_fd,I2C_SLAVE,I2C_ADDR>>1);
if(ret<0){
printf("setenv address faile ret:%x \n",ret );
return -1;
}
ret= get_temperature_from_eeprom(&T1,&T2);
if(ret == -1){
printf("read data from eeprom faile at %s \n",__FUNCTION__);
return -1;
}else if(ret == -2){
printf("init min & max temperature to eeprom \n");
ret = set_temperature_to_eeprom(25,40);
if(ret){
printf("write date to eeprom faile at %s \n", __FUNCTION__);
}
}
pthread_mutex_init(&mutex,NULL);
return 0;
}
int init_temperature_function(void){
if (access(ADC_DEV, F_OK)) {
/* 检查ADC设备文件是否存在*/
if (access(ADC_MODULE_PATH, F_OK) == 0) {
/* 检查ADC模块是否存在*/
system("insmod /root/lradc.ko");
while (access(ADC_DEV, F_OK)) {
/* 等待ADC设备文件生成完成*/
sleep(1);
}
} else {
printf("ADC module moust at /root/ \n");
return -1;
}
}
fd = open(ADC_DEV, 0);
if(fd < 0){
printf("open error by APP-%d\n",fd);
return -1;
}
//close(fd);
return 0;
}
double get_temperature(void){
int adc_value;
double voltage;
double RT = 0;
double temp = 0;
int ret;
fd = open (LRADC_DEV,O_RDONLY);/* 打开ADC设备*/
if (fd < 0) {
perror("open");
close(fd);//-----------------------can not put it out of the "( )".
return 0;
}
ret = ioctl(fd, IMX28_ADC_CH1, &adc_value); /* 读取通道1的ADC原始值*/
if (ret) {
printf("get adc value faile \n");
return -1;
}
close(fd);
voltage = (adc_value*1.85)/4096.0;/* 计算测量电压*/
RT = (V_ADC/voltage -1)*R33;/* 计算热敏电阻的阻值*/
temp = 3435/log(10*RT) -273.15;/* 计算热敏电阻的温度*/
return temp;
}
static void show_led(int fd_spi, int fd_gpio, int value, int num)
{
int ret;
uint8_t tx[] = {
led_value_table[value],
(1 << num),
};
struct spi_ioc_transfer tr_txrx[] = {
{
.tx_buf = (unsigned long)tx,
.rx_buf = 0,
.len = 2,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
},
};
ret = ioctl(fd_spi, SPI_IOC_MESSAGE(1), &tr_txrx[0]);
if (ret == 1) {
printf("can't revieve spi message");
return;
}
write(fd_gpio, "0", 1);
usleep(1);
write(fd_gpio, "1", 1);
}
int show_led_num(int VALUE, int NUM)
{
int ret = 0;
int fd_spi = 0;
int fd_gpio = 0;
int led_value = 0;
int led_num = 0;
pthread_mutex_lock(&mutex);//----------------------------------------------hu
led_value = VALUE;/* 获取程序输入参数的数码管的显示值*/
led_num = NUM;/* 获取程序输入参数的数字选择值*/
fd_spi = open(SPI_DEVICE, O_RDWR);/* 打开SPI总线的设备文件*/
if (fd_spi < 0) {
printf("can't open --led_num-- %s \n", SPI_DEVICE);
return -1;
}
fd_gpio = open(GPIO_DEVICE, O_RDWR);/* 打开GPIO设备的属性文件*/
if (fd_gpio < 0) {
printf("can't open %s device\n", GPIO_DEVICE);
return -1;
}
ret = ioctl(fd_spi, SPI_IOC_WR_MODE, &mode);
if (ret == -1) {
printf("can't set wr spi mode\n");
return -1;
}
ret = ioctl(fd_spi, SPI_IOC_WR_BITS_PER_WORD, &bits);/* 设置SPI的数据位*/
if (ret == -1) {
printf("can't set bits per word\n");
return -1;
}
ret = ioctl(fd_spi, SPI_IOC_WR_MAX_SPEED_HZ, &speed);/* 设置SPI的最大总线频率*/
if (ret == -1){
printf("can't set max speed hz\n");
return -1;
}
show_led(fd_spi, fd_gpio, led_value, led_num);
close(fd_spi);
close(fd_gpio);
pthread_mutex_unlock(&mutex);
return 0;
}
static int show_digitron(void){
static int i = 0;
//int show_value_led = 0;
while ( 1 ) {
if (is_show == DIGITRON_ON) {/* 当使能显示时*/
/*把show_value数组中各元素的信息,显示在数码管相应的位段上*/
show_led_num(show_value[i], i);
} else {/* 当禁能显示时*/
show_led_num(20, i);/* 在数码管的所有位段不显示任何信息*/
}
i++;
if (i == 4) i = 0;
usleep(1000);
}
return 0;
}
int init_digitron(void){
int ret;
pthread_t thread_show;
pthread_mutex_lock(&numlock1);
fd_spi = open(SPI_DEVICE, O_RDWR);/* 打开SPI总线设备文件*/
if (fd_spi < 0) {
printf("can not open %s \n", SPI_DEVICE);
return -1;
}
ret = ioctl(fd_spi, SPI_IOC_WR_MODE, &mode);/* 设置SPI 总线的相位和极性*/
if (ret == -1) {
printf("can't set wr spi mode\n");
return -1;
}
ret = ioctl(fd_spi, SPI_IOC_WR_BITS_PER_WORD, &bits);/* 设置SPI总线每字长度*/
if (ret == -1) {
printf("can't set bits per word\n");
return -1;
}
ret = ioctl(fd_spi, SPI_IOC_WR_MAX_SPEED_HZ, &speed);/* 设置SPI总线最高速率*/
if (ret == -1){
printf("can't set max speed hz\n");
return -1;
}
fd_gpio = open(GPIO_DEVICE, O_RDWR);/* 打开GPIO的设备属性文件*/
if (fd_gpio < 0) {
printf("can't open %s device\n", GPIO_DEVICE);
return -1;
}
close(fd_spi);
close(fd_gpio);
/* 启动线程*/
ret = pthread_create(&thread_show, PTHREAD_CREATE_JOINABLE, (void *)show_digitron, NULL);
if (ret) {
printf("create thread faile \n");
return -1;
}
pthread_mutex_unlock(&numlock1);
return 0;
}
void set_digitron_value(int value1, int value2, int value3, int value4){
show_value[0] = value1;
show_value[1] = value2 + 10;/* 在个位加上小数点*/
show_value[2] = value3;
show_value[3] = value4;
}
void set_digitron_on(int value){
is_show = value;
}
static key_callback key_callback_fun[5] = {NULL, NULL, NULL, NULL, NULL};
int install_key_function(key_callback p, int key)/* 注册回调函数*/{
if (p == NULL) {
return -1;
}
if (key_callback_fun[key]) {
/* 防止多次设置*/
return -1;
} else {
key_callback_fun[key] = p;
}
return 0;
}
enum{
KEY1,
KEY2,
KEY3,
KEY4,
KEY5
};
static int key_pthread(void){
#if 0
int fd,count;
struct input_event input_event_value;
char input_type[20];
//if (argc !=2 ) { /* 判断程序是否有输入参数,如果没有程序退出 */
// printf("usage : input_type /dev/input/eventX\n");
// return 0;
// }
fd = open (DEV_NAME, O_RDWR); /* 打开输入设备,设备的名称为程序的输入参数提供*/
if (fd < 0) {
printf ("open failed\n");
exit(0);
}
/* 循环读取输入事件,然后打印事件信息 */
while(1) {
count=read(fd, &input_event_value, sizeof(struct input_event));
if (count < 0) {
printf("read iput device event error \n");
return -1;
}
switch(input_event_value.type) { /* 判断事件的类型 */
case EV_SYN:
strcpy(input_type, "SYNC");
break;
case EV_REP:
strcpy(input_type, "REP");
break;
case EV_REL:
strcpy(input_type, "REL");
break;
case EV_ABS:
strcpy(input_type, "ABS");
break;
case EV_KEY:
strcpy(input_type, "KEY");
break;
default:
printf("even type unkown \n");
return -1;
}
/* 打印输入事件的时间 */
printf("time:%ld.%ld",input_event_value.time.tv_sec,input_event_value.time.tv_usec);
/* 打印输入事件的类型、码值、 value 值 */
printf(" type:%s code:%d value:%d\n",input_type,input_event_value.code,input_event_value.value);
}
return 0;
#endif
#if 1
int count;
struct input_event input_event_value;
while(1) {
fd = open (DEV_NAME, O_RDWR);
if (fd < 0) {
perror(DEV_NAME);
exit(0);
}/* start key conctol pthread */
count=read(fd, &input_event_value, sizeof(struct input_event));/* 监视按键输入事件*/
if (count < 0) {printf("read iput device event error \n");
return -1;
}
/* 判断是哪个键被按下/提起*/
switch (input_event_value.code) {
case KEY_A:/* KEY1按键*/
printf("time:%ld.%ld",input_event_value.time.tv_sec,input_event_value.time.tv_usec);
/* 打印输入事件的类型、码值、 value 值 */
printf("code:%d value:%d\n",input_event_value.code,input_event_value.value);
if (key_callback_fun[KEY1]) {
key_callback_fun[KEY1](input_event_value.value);
}
break;
case KEY_B:/* KEY2按键*/
printf("time:%ld.%ld",input_event_value.time.tv_sec,input_event_value.time.tv_usec);
/* 打印输入事件的类型、码值、 value 值 */
printf("code:%d value:%d\n",input_event_value.code,input_event_value.value);
if (key_callback_fun[KEY2]) {
key_callback_fun[KEY2](input_event_value.value);
}
break;
case KEY_C:/* KEY3按键*/
printf("time:%ld.%ld",input_event_value.time.tv_sec,input_event_value.time.tv_usec);
/* 打印输入事件的类型、码值、 value 值 */
printf("code:%d value:%d\n",input_event_value.code,input_event_value.value);
if (key_callback_fun[KEY3]) {
//key_callback_fun[KEY3](input_event_value.value);
}
break;
case KEY_D:/* KEY4按键*/
printf("time:%ld.%ld",input_event_value.time.tv_sec,input_event_value.time.tv_usec);
/* 打印输入事件的类型、码值、 value 值 */
printf("code:%d value:%d\n",input_event_value.code,input_event_value.value);
if (key_callback_fun[KEY4]) {
key_callback_fun[KEY4](input_event_value.value);
}
break;
case KEY_E:/* KEY5按键*/
printf("time:%ld.%ld",input_event_value.time.tv_sec,input_event_value.time.tv_usec);
/* 打印输入事件的类型、码值、 value 值 */
printf("code:%d value:%d\n",input_event_value.code,input_event_value.value);
if (key_callback_fun[KEY5]) {
key_callback_fun[KEY5](input_event_value.value);
}
break;
default:
break;
}
close(fd);
}
return 0;
#endif
}
int init_event_key(void){
int ret;
pthread_t thread_key;
//if (access(DEV_NAME, F_OK)) { /* 检查按键设备文件是否存在*/
if (access(KEY_MODULE_PATH, F_OK) == 0) {/* 检查按键模块是否存在*/
system("insmod /root/imx_key.ko");
while (access(DEV_NAME, F_OK)) {/* 等待按键设备文件生成*/
sleep(1);
}
} else {
printf("key module moust at /root \n");
return -1;
}
//}
ret = pthread_create(&thread_key, PTHREAD_CREATE_JOINABLE, (void *)key_pthread, NULL);
if (ret) {
printf("create thread faile at %s \n", __FUNCTION__);
return -1;
}
return 0;
}
static enum {
SHOW_L,
SHOW_H, /* 显示最高安全温度状态 */
SHOW_TEMPER,
} sys_status;
static int key2_action(int value){/* 只响应键按下事件,忽略键提起事件*/
if (value == 0) {
return 0;
}
sys_status = SHOW_L;/* 设置为显示最低安全温度状态*/
return 0;
}
static int key3_action(int value){/* 只响应键按下事件,忽略键提起事件*/
if (value == 0) {
return 0;
}
sys_status = SHOW_TEMPER;/* 设置为显示当前环境温度状态*/
return 0;
}
static int key4_action(int value){/* 只响应键按下事件,忽略键提起事件*/
if (value == 0) {
return 0;
}
sys_status = SHOW_H;/* 设置为显示最高安全温度状态*/
return 0;
}
static int key1_action(int value){
int min_temperature = 0, max_temperature = 0;
int ret;/* 只响应键按下事件,忽略键提起事件*/
if (value == 0) {
return 0;
}
/* 在EEPROM读出最高/最低安全温度值*/
ret = get_temperature_from_eeprom(&min_temperature, &max_temperature);
if (ret) {
printf("get temperature from eeprom faile at %s \n", __FUNCTION__);
return -1;
}
switch (sys_status) {
case SHOW_L:/* 若当处于显示最低安全温度状*/
if (min_temperature > 0) {/* 最低安全温度不能小于0*/
min_temperature--;
}
break;
case SHOW_H:/* 当处于显示最高安全温度状态*//* 最高安全温度不能低于最低安全温度*/
if (max_temperature > min_temperature) {
max_temperature--;
}
break;
case SHOW_TEMPER:
break;
}
/* 在EEPROM写入最低/最安全高温度值*/
ret = set_temperature_to_eeprom(min_temperature, max_temperature);
if (ret) {
printf("set temperature to eeprom faile at %s \n", __FUNCTION__);
return -1;
}
return 0;
}
static int key5_action(int value){
int min_temperature = 0, max_temperature = 0;
int ret;/* 只响应键按下事件,忽略键提起事件*/
if (value == 0) {
return 0;
}
/* 在EEPROM读出最高/最低安全温度值*/
ret = get_temperature_from_eeprom(&min_temperature, &max_temperature);
if (ret) {
printf("get temperature from eeprom faile at %s \n", __FUNCTION__);
return -1;
}
switch (sys_status) {
case SHOW_L:/* 若当处于显示最低安全温度状*//* 最低安全温度不能高于最高安全温度*/
if (min_temperature < max_temperature){
min_temperature++;
}
break;
case SHOW_H:/* 当处于显示最高安全温度状态*/
if (max_temperature < 85) {/* 最高安全温度不能高于85度*/
max_temperature++;
}
break;
case SHOW_TEMPER:
break;
}
/* 在EEPROM写入最低/最高安全温度值*/
ret = set_temperature_to_eeprom(min_temperature, max_temperature);
if (ret) {
printf("set temperature to eeprom faile at %s \n", __FUNCTION__);
return -1;
}
return 0;
}
void set_digitron_vlue(int value1,int value2,int value3,int value4)
{
show_value[0]=value1;
show_value[1]=value2;
show_value[2]=value3;
show_value[3]=value4;
}
static int thread_control(int *value){
int min_temperature = 0, max_temperature = 0, temperature;
float temp_t;
int ret = -1;
int value1, value2, value3,value4;
while (1) {
/* 在EEPROM读取最低/最高安全温度值*/
ret = get_temperature_from_eeprom(&min_temperature,&max_temperature);
if (ret) {
printf("read temperature faile \n");
break;
}
temp_t = get_temperature();/* 获取当前环境温度*/
temperature = (int )(temp_t * 100.0);/* 获取当前环境温度并转换为整数*/
temp1[0]=temperature;
/* 显示控制*/
switch (sys_status) {
/* 当处于显示最低安全温度状态时,数码管显示类似:26.0L */
case SHOW_L:
value1 = min_temperature / 10;/* 数码管1位段显示最低安全温度的十位*/
value2 = min_temperature % 10;/* 数码管2位段显示最低安全温度的个位*/
value3 = 0;/* 数码管3位段显示0*/
value4 = 22;/* 数码管4位段显示"L"*/
set_digitron_vlue(value1, value2, value3, value4);
break;
/* 当处于显示最高安全温度状态时,数码管显示类似:40.0H */
case SHOW_H:
value1 = max_temperature / 10;/* 数码管1位段显示最高安全温度的十位*/
value2 = max_temperature % 10;/* 数码管2位段显示最高安全温度的个位*/
value3 = 0;/* 数码管3位段显示显示0*/
value4 = 21;/* 数码管4位段显示"H"*/
set_digitron_vlue(value1, value2, value3, value4);
break;
/* 显示当前环境温度:两位整数,两位小数*/
case SHOW_TEMPER:/* 注意temperature已经把当前环境温度值乘以100,转换成整数值*/
value1 = temperature/1000;/* 数码管的1位段显示当前环境温度的十位*/
value1 = value1%10;
value2 = temperature/100;/* 数码管的2位段显示当前环境温度的个位*/
value2 = value2%10;
value3 = temperature/10;/*数码管的3位段显示当前环境温度的十分位*/
value3 = value3%10;
value4 = temperature%10;/*数码管的4位段显示当前环境温度的百分位*/
set_digitron_vlue(value1, value2, value3, value4);
break;
default:
break;
}
/* 监控当前环境温度*/
if (temp_t < min_temperature) { /* 温度过低*/
/* 蜂鸣器短鸣一声,数码管显示的数字闪烁*/
set_digitron_on(DIGITRON_OFF);
usleep(50*1000);
set_digitron_on(DIGITRON_ON);
} else if (temp_t > max_temperature) {/* 温度过高*/
/* 蜂鸣器短鸣两声,数码管显示的数字闪烁*/
set_digitron_on(DIGITRON_OFF);
usleep(50*1000);
set_digitron_on(DIGITRON_ON);
usleep(20*1000);
}
usleep(300*1000);
}
return NULL;
}
int init_control(void){
int ret;
pthread_t thread_control_t;
sys_status = SHOW_TEMPER;/*初始化为显示当前环境温度状态*/
ret = install_key_function(key1_action, KEY1);/* 在KEY1按键安装响应函数*/
if (ret) {
printf("install call fun faile in %s \n", __FUNCTION__);
return -1;
}
ret = install_key_function(key2_action, KEY2);/* 在KEY2按键安装响应函数*/
if (ret) {
printf("install call fun faile in %s \n", __FUNCTION__);
return -1;
}
ret = install_key_function(key3_action, KEY3);/* 在KEY3按键安装响应函数*/
if (ret) {
printf("install call fun faile in %s \n", __FUNCTION__);
return -1;
}
ret = install_key_function(key4_action, KEY4);/* 在KEY4按键安装响应函数*/
if (ret) {
printf("install call fun faile in %s \n", __FUNCTION__);
return -1;
}
ret = install_key_function(key5_action, KEY5);/* 在KEY5按键安装响应函数*/
if (ret) {printf("install call fun faile in %s \n", __FUNCTION__);
return -1;
}
/* 生成温度监控线程*/
ret = pthread_create(&thread_control_t, PTHREAD_CREATE_JOINABLE, (void *)thread_control, NULL);
if (ret) {
printf("create thread faile in %s \n", __FUNCTION__);
return -1;
}
return 0;
}
int tcp(void)
{
int iR;
int sockfd; // Socket file descriptor
int nsockfd; // New Socket file descriptor
int num;
int sin_size; // to store struct size
char sdbuf[LENGTH]; // Send buffer
struct sockaddr_in addr_local;
struct sockaddr_in addr_remote;
// char sendstr[16]= {"123456789 abcde"};
/* Get the Socket file descriptor */
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
{
printf ("ERROR: Failed to obtain Socket Despcritor.\n");
return (0);
} else {
printf ("OK: Obtain Socket Despcritor sucessfully.\n");
}
/* Fill the local socket address struct */
addr_local.sin_family = AF_INET; // Protocol Family
addr_local.sin_port = htons (PORT); // Port number
addr_local.sin_addr.s_addr = htonl (INADDR_ANY); // AutoFill local address
memset (addr_local.sin_zero,0,8); // Flush the rest of struct
/* Blind a special Port */
if( bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) == -1 )
{
printf ("ERROR: Failed to bind Port %d.\n",PORT);
return (0);
} else {
printf("OK: Bind the Port %d sucessfully.\n",PORT);
}
/* Listen remote connect/calling */
if(listen(sockfd,BACKLOG) == -1)
{
printf ("ERROR: Failed to listen Port %d.\n", PORT);
return (0);
} else {
printf ("OK: Listening the Port %d sucessfully.\n", PORT);
}
while(1)
{
sin_size = sizeof(struct sockaddr_in);
/* Wait a connection, and obtain a new socket file despriptor for single connection */
if ((nsockfd = accept(sockfd, (struct sockaddr *)&addr_remote, (socklen_t *__restrict)&sin_size)) == -1)
{
printf ("ERROR: Obtain new Socket Despcritor error.\n");
continue;
} else {
printf ("OK: Server has got connect from %s.\n", inet_ntoa(addr_remote.sin_addr));
}
/* Child process */
if(!fork())
{
printf("You can enter string, and press 'exit' to end the connect.\n");
while(strcmp(sdbuf,"exit") != 0)
{
iR=(int)scanf("%s", sdbuf);
if(iR>512) break;
if((num = send(nsockfd, sdbuf, strlen(sdbuf), 0)) == -1)
{
printf("ERROR: Failed to sent string.\n");
close(nsockfd);
exit(1);
}
printf("OK: Sent %d bytes sucessful, please enter again.\n", num);
}
}
close(nsockfd);
while(waitpid(-1, NULL, WNOHANG) > 0);
}
}
int tcp_server(void)
{
/*
int sockfd;
int new_fd;
*/
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size;
int nbytes;
/*----------------define local variables,related to thread-----------------*/
int ret;
pthread_t id1,id2;
//initialize the mutex
pthread_mutex_init(&mutex_r,NULL);
pthread_mutex_init(&mutex_w,NULL);
/* ---------------------related to network ---------------------------------*/
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:IPV4;SOCK_STREAM:TCP
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
}
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET; // Internet
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}
if(listen(sockfd,5)==-1)
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
printf("start listen...\n");
while(1)
{
sin_size=sizeof(struct sockaddr_in);// This is must be in while()?
printf("waiting for connection ----\n");
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
exit(1);
}
fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr));
/*------ create the read thread -------- */
//ret = pthread_create(&id1, NULL, (void*)read_pthread, NULL);
//if (ret)
//{
// printf("Create pthread error!\n");
// return 1;
//}
//printf("start the read_pthread successed \n");
/*--------create the wirte thread----------------*/
//启动写线程便会终止整个程序,不知为何??
ret = pthread_create(&id2, NULL, (void*)write_pthread, NULL);
if (ret)
{
printf("Create pthread error!\n");
return 1;
}
printf("start the write_pthread successed\n");
//printf("start to read/write data \n");
/* -----------read and write data ------------------*/
/*while(1)
{
//How long time to check ?
if(pthread_kill(id1,0)!=0)
{
printf("read_pthread is stoped ,\n");
break;
}
if(!pthread_mutex_lock(&mutex_r))
{
if(read_flag)
{
//实际操作中,把read_buffer中数据传给main 循环中的变量
printf("Server received--%i ----%s \n",num,read_buffer);
}
pthread_mutex_unlock(&mutex_r);
}
usleep(20000);
//close(new_fd);
} */
}
//close(sockfd); //How to jump here ?
printf("Close socket !\n");
exit(0);
}
int temp_send(void){
int ret;
pthread_t thread_tcp_t;
/* 生成温度监控线程*/
ret = pthread_create(&thread_tcp_t, PTHREAD_CREATE_JOINABLE, (void *)tcp_server, NULL);
if (ret) {
printf("create thread faile in %s \n", __FUNCTION__);
return -1;
}
return 0;
}
void write_pthread(void)
{
/*
int state;
state=PTHREAD_CANCEL_DEFERRED;
pthread_setcancelstate(state,&oldstate);
*/
static int nbytes;
static char buffer[buffer_size];
while(1) //
{
/*这里进行互斥标志位的判断,把数据传递到buffer */
/*
pthread_mutex_lock(&mutex_w);
write_flag=0;
pthread_mutex_unlock(&mutex_w);
*/
/*transfer datas */
/*memcpy(read_buffer,buffer,nbytes);*/
strcpy(buffer,temp1);
/*
pthread_mutex_lock(&mutex_w);
write_flag=1;
pthread_mutex_unlock(&mutex_w);
*/
/*string -> char **/
nbytes=write(new_fd,buffer,buffer_size);
if(nbytes<0)
{
fprintf(stderr,"write error:%s\n\a",strerror(errno));
}
usleep(20000);
}
}
//方法要对变量加上互斥锁
void read_pthread(void)
{
static int nbytes;
static char buffer[buffer_size];
while(1)
{
nbytes=read(new_fd,buffer,buffer_size);
num++;
if((nbytes==0)||(nbytes==-1))
{
if(nbytes==0)
{ //the connection had be closed .
printf("The connection is error !\n");
break;
}
else
fprintf(stderr,"Read Error:%s\n",strerror(errno));
close(new_fd);
exit(1);
}
//这里的加锁是可预见的
/*-------mutex lock----------*/
pthread_mutex_lock(&mutex_r);
read_flag=0;
pthread_mutex_unlock(&mutex_r);
memcpy(read_buffer,buffer,nbytes);
pthread_mutex_lock(&mutex_r);
read_flag=1;
pthread_mutex_unlock(&mutex_r);
}
printf("read_pthread is quit\n");
}
int main(int argc, char *argv[]){
int ret;
//ret = init_gpio117();/* 初始化gpio117*/
//if (ret)
//return -1;
ret = temp_send();
if (ret)
return -1;
ret = init_digitron();/* 初始化数码管模块*/
if (ret)
return -1;
ret = init_eeprom();/* 初始化eeprom模块*/
if (ret)
return -1;
ret = init_temperature_function();/* 初始化温度读取模块*/
if (ret)
return -1;
ret = init_event_key();/* 初始化按键模块*/
if (ret)
return -1;
ret = init_control();/* 初始化监控模块*/
if (ret)
return -1;
while ( 1 ) {
sleep(1);
}
return ret;
}