linux下多线程采集温度----七段数码管(二)

本文主要是围绕数码管的显示、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;

}




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值