URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9804
[ Назад ]

Исходное сообщение
"Как правильно собрать программу для Debian (Raspbian"

Отправлено DimNsk , 28-Дек-13 23:35 
есть ихсодники

main.c

/*Windows
#include <cstdlib>
#include <iostream>
#include <usb.h>
*/
/*
Linux*/
/* #include "usb.h"  */
#include </usr/include/libusb-1.0/libusb.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <string.h>

#define VERSION "0.1.0"
#define VENDOR_ID 0x16c0
#define PRODUCT_ID 0x05df

#define INTFACE 0
#define ONEWIRE_REPEAT       5
#define USB_REPEAT           5
#define USB_PAUSE_CONST      50000
unsigned char USB_BUFI[8];
unsigned char USB_BUFO[8];
unsigned long long ONEWIRE_ROM[40];
float ONEWIRE_TEMP[40];
int ONEWIRE_COUNT;
float T;
    
const static int timeout=5000; /* timeout in ms */


usb_dev_handle *find_lvr_winusb();
usb_dev_handle* setup_libusb_access() {
     usb_dev_handle *lvr_winusb;
     usb_set_debug(0);
     usb_init();
     usb_find_busses();
     usb_find_devices();

     if(!(lvr_winusb = find_lvr_winusb())) {
                return NULL;
        }


/* Linux */
usb_detach_kernel_driver_np(lvr_winusb,0);
        if (usb_set_configuration(lvr_winusb, 1) < 0) {
                printf("Could not set configuration 1 : \n");
                return NULL;
        }

        if (usb_claim_interface(lvr_winusb, INTFACE) < 0) {
                printf("Could not claim interface: \n");
                return NULL;
        }
        return lvr_winusb;
}

usb_dev_handle *find_lvr_winusb()
{
      struct usb_bus *bus;
         struct usb_device *dev;
         for (bus = usb_busses; bus; bus = bus->next) {
         for (dev = bus->devices; dev; dev = dev->next) {
                        if (dev->descriptor.idVendor == VENDOR_ID &&
                                dev->descriptor.idProduct == PRODUCT_ID ) {
                                usb_dev_handle *handle;
                                if (!(handle = usb_open(dev))) {
                                        printf("Could not open USB device\n");
                                        return NULL;
                                }
                                return handle;
                        }
                }
        }
        return NULL;
}

usb_dev_handle *lvr_winusb = NULL;

void USB_PAUSE(unsigned long long MS)
{   //  MS - задержка в милисекундах
    //  блокирует всё
    for (unsigned long long i=0; i<MS*USB_PAUSE_CONST; i++);
}

void USB_BUF_CLEAR()
{   //  очистка буферов приёма и передачи
    for (int i=0; i<9; i++) { USB_BUFI[i]=0; USB_BUFO[i]=0; }
}

bool USB_GET_FEATURE()
{   //  чтение в буфер из устройства

    bool RESULT=false;
    int i=USB_REPEAT;   //  число попыток
    while (!RESULT & ((i--)>0))
        try {
            RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, timeout);
        }
            catch (...) { RESULT=false; };
    if (!RESULT) printf("Error reading from device\n");
/*
    printf("read ");
    for(int i=0;i<8;i++) printf("%x ",USB_BUFI[i]);
    printf("\n");
*/
    return RESULT;
}

bool USB_SET_FEATURE()
{   //  запись из буфера в устройство
    bool RESULT=false;
    try {
            RESULT = usb_control_msg(lvr_winusb, 0x21, 0x09, 0x300, 0, (char *)USB_BUFO, 0x8, timeout);
    }
        catch (...) { RESULT=false;  };
    if (!RESULT) printf("Error writing to device\n");
/*
    printf("write ");
    for(int i=0;i<8;i++) printf("%x ",USB_BUFO[i]);
    printf("\n");
*/
    return RESULT;
}

bool USB_GET_PORT(unsigned char &PS)
{   //  чтение состояния порта, 2ms
    USB_BUF_CLEAR();
    bool RESULT=false;
    USB_BUFO[0]=0x7E;
    int i=USB_REPEAT;   //  число попыток
    while (!RESULT & ((i--)>0))
        if (USB_SET_FEATURE())
            if (USB_GET_FEATURE())
                if (USB_BUFI[0]==0x7E) { PS=USB_BUFI[1]; RESULT=USB_BUFI[2]==PS; }
                    else RESULT=false;
    if (!RESULT) printf("Error reading PORT\n");
    return RESULT;
}

bool USB_SET_PORT(unsigned char PS)
{   //  запись состояния порта, 2ms
    USB_BUF_CLEAR();
    bool RESULT=false;
    USB_BUFO[0]=0xE7;
    USB_BUFO[1]=PS;
    int i=USB_REPEAT;   //  число попыток
    while (!RESULT & ((i--)>0))
        if (USB_SET_FEATURE())
            if (USB_GET_FEATURE())
                 { RESULT=(USB_BUFI[0]==0xE7)&(USB_BUFI[1]==PS)&(USB_BUFI[2]==PS); }
    if (!RESULT) printf("Error writing PORT\n");
    return RESULT;
}

bool USB_GET_FAMILY(unsigned char &FAMILY)
{   //  чтение группового кода устройства, 2ms
    USB_BUF_CLEAR();
    bool RESULT=false;
    USB_BUFO[0]=0x1D;
    int i=USB_REPEAT;   //  число попыток
    while (!RESULT & ((i--)>0))
        if (USB_SET_FEATURE())
            if (USB_GET_FEATURE())
                if (USB_BUFI[0]==0x1D) { RESULT=true; FAMILY=USB_BUFI[1]; }
                    else RESULT=false;
    if (!RESULT) printf("Error reading FAMILY\n");
    return RESULT;
}

bool USB_GET_SOFTV(unsigned int &SV)
{   //  чтение номера версии прошивки, 2ms
    USB_BUF_CLEAR();
    bool RESULT=false;
    USB_BUFO[0]=0x1D;
    int i=USB_REPEAT;   //  число попыток
    while (!RESULT & ((i--)>0))
        if (USB_SET_FEATURE())
            if (USB_GET_FEATURE())
                if (USB_BUFI[0]==0x1D) { RESULT=true; SV=USB_BUFI[2]+(USB_BUFI[3]>>8); }
                    else RESULT=false;
    if (!RESULT) printf("Error reading firmware version\n");
    return RESULT;
}

bool USB_GET_ID(unsigned int &ID)
{   //  чтение ID устройства, 2ms
    USB_BUF_CLEAR();
    bool RESULT=false;
    USB_BUFO[0]=0x1D;
    int i=USB_REPEAT;   //  число попыток
    while (!RESULT & ((i--)>0))
        if (USB_SET_FEATURE())
            if (USB_GET_FEATURE())
                if (USB_BUFI[0]==0x1D) { RESULT=true; ID=(USB_BUFI[4]<<24)+(USB_BUFI[5]<<16)+(USB_BUFI[6]<<8)+USB_BUFI[7]; }
                    else RESULT=false;
    if (!RESULT) printf("Error reading device ID\n");
    return RESULT;
}

bool USB_EE_RD(unsigned char ADR,unsigned  char &DATA)
{   //  чтение EEPROM
    USB_BUF_CLEAR();
    bool RESULT=false;
    USB_BUFO[0]=0xE0;
    USB_BUFO[1]=ADR;
    int i=USB_REPEAT;   //  число попыток
    while (!RESULT & ((i--)>0))
        if (USB_SET_FEATURE())
            if (USB_GET_FEATURE()) { RESULT=(USB_BUFI[0]==0xE0)&(USB_BUFI[1]==ADR); DATA=USB_BUFI[2]; }
    if (!RESULT) printf("Error reading EEPROM\n");
    return RESULT;
}

bool USB_EE_WR(unsigned char ADR,unsigned  char DATA)
{   //  запись EEPROM, 17ms
    USB_BUF_CLEAR();
    bool RESULT=false;
    USB_BUFO[0]=0x0E;
    USB_BUFO[1]=ADR;    USB_BUFO[2]=DATA;
    int i=USB_REPEAT;   //  число попыток
    while (!RESULT & ((i--)>0))
        if (USB_SET_FEATURE())
            {
            USB_PAUSE(15);   //  на запись в EEPROM
            if (USB_GET_FEATURE()) RESULT=(USB_BUFI[0]==0x0E)&(USB_BUFI[1]==ADR)&(USB_BUFI[2]==DATA);
            } else RESULT=false;
    if (!RESULT) printf("Error writing EEPROM\n");
    return RESULT;
}

bool OW_RESET()
{   //  RESET, ~3ms
    bool RESULT=false;
    int i;
    USB_BUF_CLEAR();
    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x48;
        
    unsigned char N=ONEWIRE_REPEAT;

    while (!RESULT &((N--)>0))
        if (USB_SET_FEATURE())
            {
            USB_PAUSE(1);
            if (USB_GET_FEATURE()) {
               RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x48)&(USB_BUFI[2]==0x00);
            }
                else RESULT=false;
            }
    if (!RESULT) printf("Error OW_RESET\n");
    return RESULT;
}

bool OW_READ_BIT(unsigned char &B)
{   //  чтение бита, 3ms
    bool RESULT=false;
    USB_BUF_CLEAR();
    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x81;    USB_BUFO[2]=0x01;
    if (USB_SET_FEATURE())
        {
        USB_PAUSE(1);
        if (USB_GET_FEATURE())
            { RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x81); B=USB_BUFI[2]&0x01; }
        }
    if (!RESULT) printf("Error OW_READ_BIT\n");
    return RESULT;
}

bool OW_READ_2BIT(unsigned char &B)
{   //  чтение 2-x бит, 3ms
    bool RESULT=false;
    USB_BUF_CLEAR();
    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x82;
    USB_BUFO[2]=0x01;    USB_BUFO[3]=0x01;
    if (USB_SET_FEATURE())
        {
        USB_PAUSE(1);
        if (USB_GET_FEATURE())
            { RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x82); B=(USB_BUFI[2]&0x01)+((USB_BUFI[3]<<1)&0x02); }
        }
    if (!RESULT) printf("Error OW_READ_2BIT\n");
    return RESULT;
}

bool OW_READ_BYTE(unsigned char &B)
{   //  чтение байта, 3ms
    bool RESULT=false;
    USB_BUF_CLEAR();
    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x88;    USB_BUFO[2]=0xFF;
    if (USB_SET_FEATURE())
        {
        USB_PAUSE(1);
        if (USB_GET_FEATURE())
            { RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x88); B=USB_BUFI[2]; }
        }
    if (!RESULT) printf("Error OW_READ_BYTE\n");
    return RESULT;
}

bool OW_READ_4BYTE(unsigned long &B)
{   //  чтение 4 байта, 4ms
    bool RESULT=false;
    USB_BUF_CLEAR();
    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x84;    USB_BUFO[2]=0xFF;
    USB_BUFO[3]=0xFF;    USB_BUFO[4]=0xFF;    USB_BUFO[5]=0xFF;
    if (USB_SET_FEATURE())
        {
        USB_PAUSE(2);
        if (USB_GET_FEATURE())
            { RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x84); B=USB_BUFI[2]+(USB_BUFI[3]<<8)+(USB_BUFI[4]<<16)+(USB_BUFI[5]<<24); }
        }
    if (!RESULT) printf("Error OW_READ_4BYTE\n");
    return RESULT;
}

bool OW_WRITE_BIT(unsigned char B)
{   //  запись бита, 3ms
    bool RESULT=false;
    USB_BUF_CLEAR();
    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x81;    USB_BUFO[2]=B&0x01;
    if (USB_SET_FEATURE())
        {
        USB_PAUSE(1);
        if (USB_GET_FEATURE())
            RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x81)&((USB_BUFI[2]&0x01)==(B&0x01));
        }
    if (!RESULT) printf("Error OW_WRITE_BIT\n");
    return RESULT;
}

bool OW_WRITE_BYTE(unsigned char B)
{   //  запись байта, 3ms
    bool RESULT=false;
    USB_BUF_CLEAR();
    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x88;    USB_BUFO[2]=B;
    if (USB_SET_FEATURE())
        {
        USB_PAUSE(1);
        if (USB_GET_FEATURE())
            RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x88)&(USB_BUFI[2]==B);
        }
    if (!RESULT) printf("Error OW_WRITE_BYTE\n");
    return RESULT;
}

bool OW_WRITE_4BYTE(unsigned long B)
{   //  запись 4 байта, 4ms
    bool RESULT=false;
    unsigned char D0, D1, D2, D3;
    D0=B&0xFF;
    D1=(B>>8) &0xFF;
    D2=(B>>16)&0xFF;
    D3=(B>>24)&0xFF;
    USB_BUF_CLEAR();
    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x84;    USB_BUFO[2]=B&0xFF;
    USB_BUFO[3]=(B>>8)&0xFF;
    USB_BUFO[4]=(B>>16)&0xFF;
    USB_BUFO[5]=(B>>24)&0xFF;
    if (USB_SET_FEATURE())
        {
        USB_PAUSE(2);
        if (USB_GET_FEATURE())
            RESULT=(USB_BUFI[0]==0x18)&(USB_BUFI[1]==0x84)&(USB_BUFI[2]==D0&(USB_BUFI[3]==D1)&(USB_BUFI[4]==D2)&(USB_BUFI[5]==D3));
        }
    if (!RESULT) printf("Error OW_WRITE_4BYTE\n");
    return RESULT;
}

unsigned char CRC8(unsigned char CRC, unsigned char D)
{   //  подчсёт CRC для DALLAS
    unsigned char R=CRC;
    for (int i=0; i<8; i++)
        if ((R^(D>>i))&0x01==0x01) R=((R^0x18)>>1)|0x80;
            else R=(R>>1)&0x7F;
    return R;
}

bool READ_ROM(unsigned long long &ROM64)
{   //  чтение ROM, 14ms
    bool RESULT=false;
    unsigned long B;
    unsigned char N=ONEWIRE_REPEAT;
    unsigned long long T, CRC;
    while (!RESULT&((N--)>0))
        if (OW_RESET())
            if (OW_WRITE_BYTE(0x33))
                {   //  чтение 64 бит
                ROM64=0;    CRC=0;
                if (OW_READ_4BYTE(B))
                    {
                    T=B;
                    ROM64=ROM64+T;
                    if (OW_READ_4BYTE(B)) { T=B; ROM64=ROM64+(T<<32); RESULT=true; }
                        else RESULT=false;
                    }
                    else RESULT=false;
                //   проверка CRC
                if (RESULT)
                    {
                    T=ROM64;
                    for (int i=0; i<8; i++) CRC=CRC8(CRC, (T>>(i*8))&0xFF);
                    RESULT=CRC==0;
                    }
                }
    if (!RESULT) printf("Error READ_ROM\n");
    return RESULT;
}

bool MATCH_ROM(unsigned long long ROM)
{   //  выбор прибора по ROM, 14ms
    bool RESULT=false;
    unsigned long long T=ROM;
    unsigned char N=ONEWIRE_REPEAT;
    while (!RESULT&((N--)>0))
        if (OW_RESET())
            if (OW_WRITE_BYTE(0x55))
                if (OW_WRITE_4BYTE(T&0xFFFFFFFF))
                    RESULT=OW_WRITE_4BYTE((T>>32)&0xFFFFFFFF);
    if (!RESULT) printf("Error MATCH_ROM\n");
    return RESULT;
}

bool SKIP_ROM()
{   //  пропуск ROM-команд, 6ms
    bool RESULT=false;
    unsigned char N=ONEWIRE_REPEAT;
    while (!RESULT&((N--)>0))
        if (OW_RESET()) RESULT=OW_WRITE_BYTE(0xCC);
    if (!RESULT) printf("Error SKIP_ROM\n");
    return RESULT;
}

bool SEARCH_ROM(unsigned long long ROM_NEXT, int PL)
{   //  поиск ROM, 1 dev - 410ms, 5 dev - 2.26s, 20 dev - 8.89s
    bool RESULT=false;
    unsigned char N=ONEWIRE_REPEAT;
    unsigned char BIT;
    bool CL[64]; for (int i=0; i<64; i++) CL[i]=false;
    unsigned long long RL[64];
    unsigned long long B1=1, CRC, ROM;
    while (!RESULT&((N--)>0))
        {
        ROM=0;
        if (OW_RESET()) RESULT=OW_WRITE_BYTE(0xF0);
        if (RESULT)
            for (int i=0; i<64; i++)
                if (RESULT)
                    if (OW_READ_2BIT(BIT))
                        switch (BIT&0x03)
                            {
                            case 0 :
                                {   //  коллизия есть
                                if (PL<i) {CL[i]=true; RL[i]=ROM;}
                                if (PL>=i) BIT=(ROM_NEXT>>i)&0x01; else BIT=0;
                                if(!OW_WRITE_BIT(BIT)) { RESULT=false; i=64; }
                                if (BIT==1) ROM=ROM+(B1<<i);
                                break;
                                }
                            case 1 : { if (!OW_WRITE_BIT(0x01)) { RESULT=false; i=64; } else ROM=ROM+(B1<<i); break;}
                            case 2 : { if (!OW_WRITE_BIT(0x00)) { RESULT=false; i=64; } break;}
                            case 3 : { RESULT=false; i=64; break;}   //  нет на линии
                            }
                        else { RESULT=false; i=64; }
        if (ROM==0) RESULT=false;
        if (RESULT) { CRC=0; for (int j=0; j<8; j++) CRC=CRC8(CRC, (ROM>>(j*8))&0xFF); RESULT=CRC==0; }
        }
    if (!RESULT) printf("Error SEARCH_ROM\n");
        else ONEWIRE_ROM[ONEWIRE_COUNT++]=ROM;
    //  рекурентный вызов поиска
    for (int i=0; i<64; i++)
        if (CL[i]) SEARCH_ROM(RL[i]|(B1<<i), i);
    return RESULT;
}

bool SKIP_ROM_CONVERT()
{   //  пропуск ROM-команд, старт измерения температуры, 9ms
    bool RESULT=false;
    unsigned char N=ONEWIRE_REPEAT;
    while (!RESULT&((N--)>0))
        if (OW_RESET())
            if (OW_WRITE_BYTE(0xCC))
                RESULT=OW_WRITE_BYTE(0x44);
    if (!RESULT) printf("Error SKIP_ROM_CONVERT\n");
    return RESULT;
}

bool GET_TEMPERATURE(unsigned long long ROM, float &T)
{   //  чтение температуры, 28ms
    unsigned long long CRC;
    unsigned long L1, L2;
    unsigned char L3;
    unsigned char FAMILY=ROM&0xFF;
    bool RESULT=false;
    unsigned char N=ONEWIRE_REPEAT;
    while (!RESULT&((N--)>0))
        if (MATCH_ROM(ROM))
            if (OW_WRITE_BYTE(0xBE))
                    if (OW_READ_4BYTE(L1))
                        if (OW_READ_4BYTE(L2))
                            if (OW_READ_BYTE(L3))
                                {
                                CRC=0;
                                for (int i=0; i<4; i++) CRC=CRC8(CRC, (L1>>(i*8))&0xFF);
                                for (int i=0; i<4; i++) CRC=CRC8(CRC, (L2>>(i*8))&0xFF);
                                CRC=CRC8(CRC, L3);
                                RESULT=CRC==0;

                                short K=L1&0xFFFF;
                                //  DS18B20 +10.125=00A2h, -10.125=FF5Eh
                                //  DS18S20 +25.0=0032h, -25.0=FFCEh
                                //  K=0x0032;
                                T=1000;     //  для неопознанной FAMILY датчик отсутствует
                                if ((FAMILY==0x28)|(FAMILY==0x22)) T=K*0.0625;  //  DS18B20 | DS1822
                                if (FAMILY==0x10) T=K*0.5;                      //  DS18S20 | DS1820
                                }
    if (!RESULT) printf("Error GET_TEMPERATURE\n");
    return RESULT;
}


int read_ports()
{
    int ret=0;
    unsigned char PS;
    if(USB_GET_PORT(PS)) {
        if((PS==8)|(PS==24)) printf("Port1 is on\n");
        else printf("Port1 is off\n");
        if(PS>=16) printf("Port2 is on\n");
        else printf("Port2 is off\n");
        return 1;
    }
    return 0;
}

int set_port(int num, bool stat)
{
    unsigned char PS, PS_OLD;
    bool ret;

    if (USB_GET_PORT(PS))
        {   //  удалость прочитать
        PS_OLD=PS;
        } else { printf("Error USB_GET_PORT\n"); return 0; }
    //  включение / выключение
    if ((num==1)&(stat==1))  { PS=PS|0x08; ret = USB_SET_PORT(PS); }
    else if ((num==1)&(stat==0)) { PS=PS&0x10; ret = USB_SET_PORT(PS); }
    else if ((num==2)&(stat==1))  { PS=PS|0x10; ret = USB_SET_PORT(PS); }
    else if ((num==2)&(stat==0)) { PS=PS&0x08; ret = USB_SET_PORT(PS); }            
    if(!ret) return 0;
    printf("Status port changed\n");
    return 1;
}

int device_info() {
    int ret=0;
    unsigned int SV,ID;
    unsigned char FAMILY;
    ret = USB_GET_SOFTV(SV);
    if(ret) printf("Firmware: %xh\n", SV);
    ret = USB_GET_FAMILY(FAMILY);
    if(ret) printf("USB series: %xh\n", FAMILY);
    ret = USB_GET_ID(ID);
    if(ret) printf("USB identifier: %xh\n", ID);
    return 1;
}


int scan() {
    int ret;
    ret = SEARCH_ROM(0, 0);
    for(int i=1;i<=ONEWIRE_COUNT;i++) {
            printf("temp_id%d = %x",i, (ONEWIRE_ROM[i-1]>>32)&0xFFFFFFFF);
            printf("%x\n",ONEWIRE_ROM[i-1]&0xFFFFFFFF);
    }
    return 1;    
}

int temp(unsigned long long ROM) {
    int ret;
    ONEWIRE_COUNT = 1;
    ONEWIRE_ROM[0] = ROM;
    SKIP_ROM_CONVERT();
    ret = GET_TEMPERATURE(ONEWIRE_ROM[0], T);
    if(ret) printf("%f\n",T);
}

int ports_save() {
    unsigned char PS;
    if (USB_GET_PORT(PS)) {
        if (USB_EE_WR(0x04, PS)) {printf("Status ports saved\n");return 1;}
    }
    printf("Error saving ports status\n");
    return 0;
}

int delay_get() {
    unsigned char B;
    USB_EE_RD(0x05, B);
    printf("%d\n", B);
    return 1;
}

int delay_set(int B) {
    if((B<5)|(B>255)) {
        printf("Wrong num %d\n",B);
        return 0;
    }
    if (USB_EE_WR(0x05, B)) {printf("Delay changed\n");return 1;}
    return 0;
}


long long unsigned int HexStringToUInt(char* s)
{
long long unsigned int v = 0;
while (char c = *s++)
{
if (c < '0') return 0; //invalid character
if (c > '9') //shift alphabetic characters down
{
if (c >= 'a') c -= 'a' - 'A'; //upper-case 'a' or higher
if (c > 'Z') return 0; //invalid character
if (c > '9') c -= 'A'-1-'9'; //make consecutive with digits
if (c < '9' + 1) return 0; //invalid character
}
c -= '0'; //convert char to hex digit value
v = v << 4; //shift left by a hex digit
v += c; //add the current digit
}

return v;
}

int main( int argc, char **argv)
{
    lvr_winusb = setup_libusb_access();

        char buf;
  
        if(argc==1) {
            printf("Temperature sensor BM1707 control v1.0\n");
            if(lvr_winusb!=NULL) {
                printf("Device has been plugged\n");
            }
            else printf("Device unplugged\n");
            printf("\nUsage: bmcontrol [options]\n\n");
            printf("   info                          Show device information\n");
            printf("   scan                          Scaning temperature sensors\n");
            printf("   temp <id>                     Show temperature sensor <id> \n");
            printf("   ports                         Show ports status\n");
            printf("   pset <port> <status>          Set off/on port status.\n");
            printf("                                 Correct value: port [1, 2] status [0, 1]. \n");
            printf("   psave                         Save ports status in EEPROM\n");
            printf("   delay                         Get delay time of device before power save\n");
            printf("   delay <5-255>                 Set delay time of device before power save\n");
        }
        else if(lvr_winusb!=NULL){
             if(strcmp(argv[1],"ports") == 0) buf = read_ports();
             else if(strcmp(argv[1],"info") == 0) device_info();
             else if(strcmp(argv[1],"scan") == 0) scan();
             else if(strcmp(argv[1],"psave") == 0) ports_save();
             else if((strcmp(argv[1],"temp") == 0)&&(argv[2])) {
                  long unsigned rom1=0, rom2=0;
                  long long unsigned rom=0;
                  rom = HexStringToUInt(argv[2]);
                  temp(rom);
             }
             else if((strcmp(argv[1],"pset") == 0)&(argc==4)) buf = set_port(atoi((const char*) argv[2]), (bool) atoi((const char*) argv[3]));
             else if((strcmp(argv[1],"delay") == 0)&(argc==2)) delay_get();
             else if((strcmp(argv[1],"delay") == 0)&(argc==3)) delay_set( atoi(argv[2]));
             else printf("Wrong command %s.\n", argv[1]);
        }
        else {
             printf("Device not plugged\n");
             exit(-1);
        }
        if(lvr_winusb!=NULL) {
            usb_release_interface(lvr_winusb, 0);
            usb_close(lvr_winusb);
        }
        return 0;
}


и makefile

CC = g++

all: bmcontrol

%.o: %.c
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -I. -I/usr/include -lusb -o $@ $^


bmcontrol: main.o
    $(CC) -I/usr/include -L/usr/lib -lusb -o $@ $^


clean:
    rm -f *.o bmcontrol

при сборке  make

вываливаются ошибки

g++   -c -I. -I/usr/include -lusb -o main.o main.c
main.c:32:1: error: ‘usb_dev_handle’ does not name a type
main.c:33:1: error: ‘usb_dev_handle’ does not name a type
main.c:59:2: error: ‘usb_dev_handle’ does not name a type
main.c:79:1: error: ‘usb_dev_handle’ does not name a type
main.c: In function ‘bool USB_GET_FEATURE()’:
main.c:99:38: error: ‘lvr_winusb’ was not declared in this scope
main.c:99:102: error: ‘usb_control_msg’ was not declared in this scope
main.c: In function ‘bool USB_SET_FEATURE()’:
main.c:115:38: error: ‘lvr_winusb’ was not declared in this scope
main.c:115:102: error: ‘usb_control_msg’ was not declared in this scope
main.c: In function ‘int main(int, char**)’:
main.c:637:5: error: ‘lvr_winusb’ was not declared in this scope
main.c:637:38: error: ‘setup_libusb_access’ was not declared in this scope
main.c:669:104: error: ‘atoi’ was not declared in this scope
main.c:671:87: error: ‘atoi’ was not declared in this scope
main.c:676:21: error: ‘exit’ was not declared in this scope
main.c:679:48: error: ‘usb_release_interface’ was not declared in this scope
main.c:680:33: error: ‘usb_close’ was not declared in this scope
make: *** [main.o] Error 1

что я делаю не так?



Содержание

Сообщения в этом обсуждении
"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 29-Дек-13 02:02 
1. Убедитесь, что пакет libusb-dev установлен
2. Вот эту строчку:


#include </usr/include/libusb-1.0/libusb.h>


заменяете на:


#include <usb.h>


3. Собирается всё одной строчкой (вместо вашего мейк-файла):


g++ -lusb main.c -o bmcontrol


ну либо можно переделать ваш Makefile:


APP = bmcontrol
CXXFLAGS = -Wall -O2 -s
LDFLAGS = $(shell pkg-config --libs libusb)
OBJS = main.o

default: $(APP)

%.o: %.c
    $(CXX) $(CXXFLAGS) -c -o $@ $^


$(APP): $(OBJS)
    $(CXX) $(LDFLAGS) -o $@ $^

clean:
    rm -f *.o $(APP)

.PHONY: default $(APP) clean

4. Ну и напоследок просто совет: у вас там куча ошибок
4.1 Попробуйте собрать с опцией "-Wall" и пофиксите все предупреждения
4.2 Установите cppcheck и пофиксите все ошибки, которые выдает эта команда:


cppcheck --enable=all -I /usr/include/ main.c


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 29-Дек-13 02:19 
Если вы имели ввиду, как для Debian/Raspbian сделать deb-пакет, то есть разные способы, простые (для себя) и сложные (если хотите добавить свой пакет в репозиторий Debian).

Самый простой способ: использовать утилиту "checkinstall" вместо команды "make install".
1. Добавить install правило в ваш Makefile:


PREFIX ?= /usr/local
APP = bmcontrol

install:
    install -m 0755 $(APP) $(PREFIX)/bin

2. Выполнить команду "make".
3. Запустить утилиту "sudo checkinstall" и ответить на вопросы. Или можно как то так:


checkinstall --pkgname=bmcontrol --install=no --default
sudo dpkg -i bmcontrol*.deb


"Как правильно собрать программу для Debian (Raspbian"
Отправлено DimNsk , 29-Дек-13 20:38 
>[оверквотинг удален]
> install:
>  install -m 0755 $(APP) $(PREFIX)/bin
>

> 2. Выполнить команду "make".
> 3. Запустить утилиту "sudo checkinstall" и ответить на вопросы. Или можно как
> то так:
>
 
> checkinstall --pkgname=bmcontrol --install=no --default
> sudo dpkg -i bmcontrol*.deb
>

Все решилось сборкой и установкой библиотеки  libusb-0.1-12
после этого файл bmcontrol собрался без ошибок
Все спасибо


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 30-Дек-13 00:45 
> после этого файл bmcontrol собрался без ошибок

А в курсе, чё будет с этим кодом, если gcc сказать -O2 и больше?


void USB_PAUSE(unsigned long long MS)
{   //  MS - задержка в милисекундах блокирует всё
    for (unsigned long long i=0; i<MS * USB_PAUSE_CONST; i++);
}

правильно, он превратиться в:

void USB_PAUSE(void)
{
  return;
}

если прям так уверены, что 50000 циклов сравнения и сложения прим. равны 1 мс,
то надо volatile писать.


void USB_PAUSE(unsigned long long MS)
{
    for (unsigned long long volatile i=0; i < (MS * USB_PAUSE_CONST); i++);
}


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 30-Дек-13 04:26 
> если прям так уверены, что 50000 циклов сравнения и сложения прим. равны
> 1 мс,
> то надо volatile писать.

Ну а если совсем по уму, то так:

1. Если можно использовать неблокирующее ожидание (по сути планировщик будет выполнять другие процессы, пока ожидание не закончится, т.е. как если бы мы делали sched_yield()):


#include <time.h>

void sleep_nonblocking(unsigned int msecs)
{
    struct timespec req;

    req.tv_sec = msecs / 1000;
    req.tv_nsec = (msecs - req.tv_sec * 1000) * 1000000;

    if (nanosleep(&req, NULL) == -1) {
        perror("Error occurred while sleeping");
        exit(EXIT_FAILURE);
    }
}


2. Если нужно обязательно блокирующее ожидание (как у вас сейчас сделано):


#include <time.h>
#include <stdio.h>
#include <stdlib.h>

#define CLOCKS_PER_MSEC (CLOCKS_PER_SEC / 1000)

void sleep_blocking(unsigned int msecs)
{
    clock_t goal;

    goal = msecs * CLOCKS_PER_MSEC + clock();
    while (goal > clock());
}


При этом для обоих случаев можно компилировать с "-O2" и не нужно использовать volatile.

Подробнее почитать про эти вызовы можно в "man 2 nanosleep" и в "man 3 clock" (должен быть установлен пакет manpages-dev).

Да, и еще, на всякий пожарный: код с "nanosleep()" нельзя компилировать с опцией "-ansi". Подробности в /usr/include/features.h.

Что касается портируемости: вот например как сделали в VLC:

Linux:
http://git.videolan.org/?p=vlc.git;a=blob;f=src/posix/thread...

Windows:
http://git.videolan.org/?p=vlc.git;a=blob;f=src/win32/thread...


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 30-Дек-13 05:22 
> void sleep_nonblocking(unsigned int msecs)
> void sleep_blocking(unsigned int msecs)

Вот только с названиями я погорячился: для этих функций уже есть хорошие названия:

sleep_nonblocking() -> msleep()
sleep_blocking() -> mdelay()


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 30-Дек-13 21:44 
> Ну а если совсем по уму, то так:

Плоха сделал, давай ищо! Нужна через asm("rdtsc"..), с коррекцией, нормализацией таймера,
реалтаймом, и  barrier() не забудь, а то мало ли чо, мож кэш плохой.  


"Как правильно собрать программу для Debian (Raspbian"
Отправлено DimNsk , 30-Дек-13 23:01 
>> Ну а если совсем по уму, то так:
> Плоха сделал, давай ищо! Нужна через asm("rdtsc"..), с коррекцией, нормализацией таймера,
> реалтаймом, и  barrier() не забудь, а то мало ли чо, мож
> кэш плохой.

однако :)


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 31-Дек-13 01:02 
>> Ну а если совсем по уму, то так:
> Плоха сделал, давай ищо! Нужна через asm("rdtsc"..), с коррекцией, нормализацией таймера,
> реалтаймом, и  barrier() не забудь, а то мало ли чо, мож
> кэш плохой.

Вам когда-нибудь говорили, какой вы умный и какая у вас тонкая ирония? :)


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 31-Дек-13 04:11 
> Вам когда-нибудь говорили, какой вы умный и какая у вас тонкая ирония? :)

Сам тащусь :)
С наступающим Новым Годом!


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 31-Дек-13 06:51 
>> Вам когда-нибудь говорили, какой вы умный и какая у вас тонкая ирония? :)
> Сам тащусь :)
> С наступающим Новым Годом!

и вас по тому же месту! :)


"Как правильно собрать программу для Debian (Raspbian"
Отправлено DimNsk , 31-Дек-13 07:44 
>>> Вам когда-нибудь говорили, какой вы умный и какая у вас тонкая ирония? :)
>> Сам тащусь :)
>> С наступающим Новым Годом!
> и вас по тому же месту! :)

Продолжаем...

Функция GET_TEMPERATURE выдает ошибку:

Вот код функции

bool GET_TEMPERATURE(unsigned long long ROM, float &T)
{
    if ( DEBUG ) printf("[D] enter GET_TEMPERATURE\n");
    unsigned long long CRC;
    unsigned long L1, L2;
    unsigned char L3;
    unsigned char FAMILY=ROM&0xFF;
    bool RESULT=false;
    unsigned char N=3;
    while (!RESULT&((N--)>0))
        if (MATCH_ROM(ROM))
            if (OW_WRITE_BYTE(0xBE))
                    if (OW_READ_4BYTE(L1))
                        if (OW_READ_4BYTE(L2))
                            if (OW_READ_BYTE(L3))
                            {
                                if ( DEBUG ) printf("[D] L1=%lx\tL2=%lx\tL3=%hhx\n", L1, L2, L3);
                                CRC=0;
                                for (int i=0; i<4; i++) CRC=CRC8(CRC, (L1>>(i*8))&0xFF);
                                if ( DEBUG ) printf("[D] CRC=%llx\n", CRC);
                                for (int i=0; i<4; i++) CRC=CRC8(CRC, (L2>>(i*8))&0xFF);
                                if ( DEBUG ) printf("[D] CRC=%llx\n", CRC);
                                CRC=CRC8(CRC, L3);
                                if ( DEBUG ) printf("[D] CRC=%llx\n", CRC);
                                RESULT=CRC==0;
                                short K=L1&0xFFFF;
                                //  DS18B20 +10.125=00A2h, -10.125=FF5Eh
                                //  DS18S20 +25.0=0032h, -25.0=FFCEh
                                //  K=0x0032;
                                T=1000;     //  for unknow FAMILY - no sensor exists
                                if ((FAMILY==0x28)|(FAMILY==0x22)) T=K*0.0625;  //  DS18B20 | DS1822
                                if (FAMILY==0x10) T=K*0.5;                      //  DS18S20 | DS1820
                                if ( DEBUG ) printf("[D] ~T=%f\n", T);
                            } else printf("[!] !OW_READ_BYTE(L3) \n");
                        else printf("[!] !OW_READ_4BYTE(L2) \n");
                    else printf("[!] !OW_READ_4BYTE(L1) \n");
                else printf("[!] !OW_WRITE_BYTE(0xBE) \n");
        else printf("[!] !MATCH_ROM(ROM) \n");
    if (!RESULT) printf("[!] Error GET_TEMPERATURE\n");
    return RESULT;
}


вот вывод  DEBUG

#  /root/mp707/bmcontrol scan

temp_id1 = 8300000483000004
temp_id2 = 40000034000003


# /root/mp707/bmcontrol temp 40000034000003
[D] enter GET_TEMPERATURE
[D] L1=ffffffff L2=ffffffff     L3=ff
[D] CRC=8d
[D] CRC=c9
[D] CRC=63
[D] ~T=1000.000000
[D] L1=ffffffff L2=ffffffff     L3=ff
[D] CRC=8d
[D] CRC=c9
[D] CRC=63
[D] ~T=1000.000000
[D] L1=ffffffff L2=ffffffff     L3=ff
[D] CRC=8d
[D] CRC=c9
[D] CRC=63
[D] ~T=1000.000000
[!] Error GET_TEMPERATURE


Что не так?


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 31-Дек-13 14:54 
> Что не так?

Переменная RESULT должна быть не нулевой при выходе из функции, а для этого CRC8(L3) должен быть нулем. У вас же CRC8(L3) равен 63. Очевидно, L3 некорректный (он равен ff). Да и L1, L2 тоже странные, ffffffff. И это response на команду 0xbe, для DS18B20 это "Read Scratchpad". Не похоже на корректные значения датчика. А id датчиков правильные? Либо вы неправильно программу используете, либо девайс ваш накрылся. Ну или прога кривая.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено DimNsk , 31-Дек-13 15:26 
>> Что не так?
> Переменная RESULT должна быть не нулевой при выходе из функции, а для
> этого CRC8(L3) должен быть нулем. У вас же CRC8(L3) равен 63.
> Очевидно, L3 некорректный (он равен ff). Да и L1, L2 тоже
> странные, ffffffff. И это response на команду 0xbe, для DS18B20 это
> "Read Scratchpad". Не похоже на корректные значения датчика. А id датчиков
> правильные? Либо вы неправильно программу используете, либо девайс ваш накрылся. Ну
> или прога кривая.

Девайс работает и Датчики исправные  только что проверил в Win.

Насчет id датчиков  
есть подозрения что они не правильно определяются

в Win
это
83000004BFC35D28
0400000334EDDD28

а BMcontrol в Raspbian
определяет их как
8300000483000004
40000034000003



"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 02-Янв-14 01:26 
>[оверквотинг удален]
> Насчет id датчиков
> есть подозрения что они не правильно определяются
> в Win
> это
> 83000004BFC35D28
> 0400000334EDDD28
> а BMcontrol в Raspbian
> определяет их как
> 8300000483000004
> 40000034000003

Кажется, в Linux неправильно работает считывание. Заметьте, в Linux каждые 4 байта (32 бита) повторяются, например 0x83000004, а дальше опять тоже самое. Скорее всего, прога ваша глючная и не протестированная.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 02-Янв-14 01:48 
>[оверквотинг удален]
>> это
>> 83000004BFC35D28
>> 0400000334EDDD28
>> а BMcontrol в Raspbian
>> определяет их как
>> 8300000483000004
>> 40000034000003
> Кажется, в Linux неправильно работает считывание. Заметьте, в Linux каждые 4 байта
> (32 бита) повторяются, например 0x83000004, а дальше опять тоже самое. Скорее
> всего, прога ваша глючная и не протестированная.

Знаете, у меня есть подозрение, что как раз функция задержки у вас не выполняет свою задачу. Попробуйте заменить у себя эту функцию:


void USB_PAUSE(unsigned long long MS)
{   //  MS - задержка в милисекундах
    //  блокирует всё
    for (unsigned long long i=0; i<MS*USB_PAUSE_CONST; i++);
}


на эту:


void USB_PAUSE(unsigned int msecs)
{
    clock_t goal;

    goal = msecs * CLOCKS_PER_MSEC + clock();
    while (goal > clock());
}


а в самый верх программы добавьте это:


#include <time.h>
#include <stdlib.h>

#define CLOCKS_PER_MSEC (CLOCKS_PER_SEC / 1000)


Не удивлюсь, если после этого заработает. А автору программы надо руки пообрывать.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 02-Янв-14 02:03 
>[оверквотинг удален]
> Насчет id датчиков
> есть подозрения что они не правильно определяются
> в Win
> это
> 83000004BFC35D28
> 0400000334EDDD28
> а BMcontrol в Raspbian
> определяет их как
> 8300000483000004
> 40000034000003

Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/  . Попробуйте оттуда собрать, может сходу заработает. У вас по идее старая версия (1.0) отсюда: http://devphp.org.ua/?menu=scripts&sub=&sshow=5

Еще думаю вам будет интересно почитать вот это (и комментарии ниже): https://plus.google.com/+SergeyShpikin/posts/PYWwMJB6Wv3


Вот еще парочка интересных ссылок по MP707:

http://www.masterkit.ru/forum/viewtopic.php?t=1370&postdays=...

http://www.sinava.ru/MP707.php

http://habrahabr.ru/post/164399/

http://blog-i.ru/umniy-dom-versiya-2-0/temperaturniy-kontrol...



"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 02-Янв-14 02:06 
Ссылка на репозиторий плохо вставилась, вот правильная: https://code.google.com/p/bmcontrol/

"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 02-Янв-14 02:35 
> Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/

А еще лучше используйте мою версию отсюда: https://code.google.com/r/joeskb7-bmcontrol/


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 02-Янв-14 17:47 
>> Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/
> А еще лучше используйте мою версию отсюда: https://code.google.com/r/joeskb7-bmcontrol/

Нефеншуй! :-P

RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, timeout);

Нада

#include <linux/usb.h>

RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, USB_CTRL_SET_TIMEOUT);


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 02-Янв-14 18:12 
>>> Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/
>> А еще лучше используйте мою версию отсюда: https://code.google.com/r/joeskb7-bmcontrol/
> Нефеншуй! :-P
> RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, timeout);
> Нада
> #include <linux/usb.h>
> RESULT = usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, USB_CTRL_SET_TIMEOUT);

Во-первых для юзерспейса (в /usr/include) нет хедера linux/usb.h, это только для ядра. Во-вторых, под вендой (в MinGW) уж точно такого нет, а я пытался сделать чтобы всё стало кросс-платформенно.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 02-Янв-14 18:30 
Кстати, после каждого usb_control_msg() нужно 20 мс. таймаут ставить.
Если после записи сразу попытаешься считать.
Примерно из 100 раз одно значение будет неверное.
Можешь тестовый брутфорс на флешке устроить.

libusb ваще корявое угэ.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 02-Янв-14 20:40 
> Кстати, после каждого usb_control_msg() нужно 20 мс. таймаут ставить.
> Если после записи сразу попытаешься считать.
> Примерно из 100 раз одно значение будет неверное.
> Можешь тестовый брутфорс на флешке устроить.
> libusb ваще корявое угэ.

Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс? А где можно почитать об этом баге? И не знаете, был ли он исправлен в libusb-1.0 (по отношению к 0.1)?

Я просто никогда с libusb не работал, поэтому ничего не знаю про него, а по поводу моих фиксов -- они относятся к коду bmcontrol вообще, а не к работе с libusb.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 02-Янв-14 22:34 
>  А где можно почитать об этом баге? был ли он исправлен в libusb-1.0 (по отношению к 0.1)?

Я уж и не вспомню, года 3 не работал с libusb.
Погугли на тему: libusb timer error
Они ж там для задержек используют таймеры вместо *sleep()/*delay(), вот чёй-то там накосячили.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 03-Янв-14 05:14 
А, ещё косяк вспомнил: после освобождения драйвера прибора usb_detach_kernel_driver_np()
драйвер особо и не освобождался, в моём случае это был uvcvideo.ko
Второй раз подключится к нему нельзя было. Если драйвер в виде модуля,
то спасало rmmod/insmod, а если монолитом, только ребут.
  


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 04-Янв-14 16:06 
> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?

Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.

ret = usb_control_msg();
usleep(20);
if ( ret < 0 )
   ля-ля-ля ...error;



"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 04-Янв-14 20:03 
>> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?
> Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
> ret = usb_control_msg();
> usleep(20);
> if ( ret < 0 )
>    ля-ля-ля ...error;

Сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...


"Как правильно собрать программу для Debian (Raspbian"
Отправлено DimNsk , 04-Янв-14 20:16 
>>> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?
>> Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
>> ret = usb_control_msg();
>> usleep(20);
>> if ( ret < 0 )
>>    ля-ля-ля ...error;
> Сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...

Собрал. Работает!
Ваша версия: сканирование проходит дольше чем сборка для OpenWRT,
а вот опрос датчиков быстрее раза в два.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 04-Янв-14 20:30 
>>>> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?
>>> Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
>>> ret = usb_control_msg();
>>> usleep(20);
>>> if ( ret < 0 )
>>>    ля-ля-ля ...error;
>> Сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
> Собрал. Работает!
> Ваша версия: сканирование проходит дольше чем сборка для OpenWRT,
> а вот опрос датчиков быстрее раза в два.

Сборка под OpenWRT -- вот эта https://github.com/bubbafix/openwrt-bm1707/blob/master/packa...? Я дорабатывал оригинальную версию, про другие переделки ничего не могу сказать. Надеюсь, автор получил моё письмо и затянет изменения к себе в mainline.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 05-Янв-14 00:04 
>[оверквотинг удален]
>>>> if ( ret < 0 )
>>>>    ля-ля-ля ...error;
>>> Сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...
>> Собрал. Работает!
>> Ваша версия: сканирование проходит дольше чем сборка для OpenWRT,
>> а вот опрос датчиков быстрее раза в два.
> Сборка под OpenWRT -- вот эта https://github.com/bubbafix/openwrt-bm1707/blob/master/packa...
>  ? Я дорабатывал оригинальную версию, про другие переделки ничего не
> могу сказать. Надеюсь, автор получил моё письмо и затянет изменения к
> себе в mainline.


diff -ru a/main.c b/main.c
--- a/main.c    1979-12-31 00:00:00.000000000 +0300
+++ b/main.c    2014-01-05 00:08:35.859593000 +0400
@@ -370,10 +370,10 @@
     D2=(B>>16)&0xFF;
     D3=(B>>24)&0xFF;
     USB_BUF_CLEAR();
-    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x84;    USB_BUFO[2]=B&0xFF;
-    USB_BUFO[3]=(B>>8)&0xFF;
-    USB_BUFO[4]=(B>>16)&0xFF;
-    USB_BUFO[5]=(B>>24)&0xFF;
+    USB_BUFO[0]=0x18;    USB_BUFO[1]=0x84;    USB_BUFO[2]=D0;
+    USB_BUFO[3]=D1;
+    USB_BUFO[4]=D2;
+    USB_BUFO[5]=D3;
     if (USB_SET_FEATURE())
         {
         USB_PAUSE(2);
@@ -414,13 +414,11 @@
{    bool RESULT=false;
     unsigned char N=ONEWIRE_REPEAT;
     unsigned char BIT;
-    bool CL[64];
+    bool CL[64]= {false}; // array of false :)
     int i;
     uint64_t RL[64];
     uint64_t B1=1, CRC, ROM;

-    for (i=0; i<64; i++) CL[i]=false;
-
     while (!RESULT && N--)
         {
         ROM=0;


"Как правильно собрать программу для Debian (Raspbian"
Отправлено Andrey Mitrofanov , 05-Янв-14 00:18 
> @@ -414,13 +414,11 @@
>  {    bool RESULT=false;
>      unsigned char N=ONEWIRE_REPEAT;
>      unsigned char BIT;
> -    bool CL[64];
> +    bool CL[64]= {false}; // array of false :)
> -    for (i=0; i<64; i++) CL[i]=false;
> -

Ну, я понял бы, заменил бы memset-ом, но ведь инициализация переменной в стеке будет сделана компилятором тем же циклом.   ...  Или это такой хитрый способ  исполнить именно memset "руками" компилера?


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 05-Янв-14 05:40 
> Или это такой хитрый способ  исполнить именно memset "руками" компилера?

Ага.


mov      $0x0,%eax        ; чем заполняем, в EAX
mov      $0x20,%edx       ; длина - 32 или 0x20  (32 WORD или 64 BYTE)
mov      %ebx,%edi        ; указатель на начало в EDI
mov      %edx,%ecx        ; длину в ECX  
rep stos %eax,%es:(%edi)  ; повторять запись по адресу указанному в (ES:EDI) значением в EAX, пока ECX не будет равен 0  
sub      $0xffffff80,%esp ; новый указатель  

На x86_64 оно за 10 повторов обнулит, даже если у тя тип будет unsigned char или short.
Поэтому типы меньше int на x64 практически бесполезны.  

Это обычный цикл

из-за операции сравнения (i < 64) получим цикл loop 64 раза.


    jg     out
    mov    0xc(%esp),%eax
loop:
    mov    0xc(%esp),%eax
    inc    %eax
    mov    %eax,0xc(%esp)
    mov    0xc(%esp),%eax
    cmp    $0x3f,%eax
    jle    loop
out:
    add    $0x10,%esp

---
Так что, чтоб лишний раз не дёргать glibc. Конечно есть __builtin_memset,
но он всё равно тормознутее и не портабельно, а эта фича STD C99

"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 05-Янв-14 03:27 
>
 
> diff -ru a/main.c b/main.c
>

https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...

https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...

Авторство сохранено.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 06-Янв-14 21:20 
>...


diff -ur a/main.c b/main.c
--- a/main.c    1979-12-31 00:00:00.000000000 +0300
+++ b/main.c    2014-01-06 21:19:23.107679000 +0400
@@ -11,8 +11,11 @@
#include <string.h>
#include <stdint.h>
#include <time.h>
+#include <stdbool.h>

+#ifndef bool
typedef enum { false, true } bool;
+#endif

#define VERSION "1.1.1"
#define VENDOR_ID 0x16c0


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 08-Янв-14 03:30 
>[оверквотинг удален]
>  #include <string.h>
>  #include <stdint.h>
>  #include <time.h>
> +#include <stdbool.h>
> +#ifndef bool
>  typedef enum { false, true } bool;
> +#endif
>  #define VERSION "1.1.1"
>  #define VENDOR_ID 0x16c0
>

Сделал так: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 08-Янв-14 04:39 
> Сделал так: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...

Заодно для пущей портабельности вот такую штуку сделал: https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 04-Янв-14 22:38 
>>> Т.е. в каждый вызов usb_control_msg() нужно передавать в качестве timeout не менее 20 мс?
>> Не-не-не, туда по стандарту - USB_CTRL_SET_TIMEOUT. Я имел ввиду после.
>> ret = usb_control_msg();
>> usleep(20);
>> if ( ret < 0 )
>>    ля-ля-ля ...error;
> Сделал:

Ага, оно самое.  

Там бы знаешь ещё что, - понять что за константы в функции usb_control_msg()

эта GET // from device
usb_control_msg(lvr_winusb, 0xA1, 0x01, 0x300, 0, (char *)USB_BUFI, 0x8, timeout);

эта SET // to device
usb_control_msg(lvr_winusb, 0x21, 0x09, 0x300, 0, (char *)USB_BUFO, 0x8, timeout);

Я так думаю, что:

0xA1 - (USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN) /* (0x01 << 5) | 0x01 | 0x80 */
0x21 - (USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT) /* (0x01 << 5) | 0x01 | 0x00 */

0x01 - это по-моему запрос .... скорее всего CLEAR_FEATURE
0x09 - тута видимо SET_CONFIGURATION  

0x8 - это sizeof(USB_BUFI) и sizeof(USB_BUFO)  // размер буфера
0 - смещение он начала буфера.

0x300 - это типа сколько байт будет передано. Видимо афтор оригинала тоже где-то скопипастил код. :)



"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 05-Янв-14 03:41 
> Там бы знаешь ещё что, - понять что за константы в функции usb_control_msg()

Как говорится, good point. Только я по незнанию немного подвис на этом этапе. Но вроде разобрался. Ниже результаты.


> 0xA1 - (USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN) /* (0x01 << 5) | 0x01 | 0x80 */
> 0x21 - (USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT) /* (0x01 << 5) | 0x01 | 0x00 */

Верно, только в include/usb.h нет USB_DIR_*, там USB_ENDPOINT_* взамен.


> 0x01 - это по-моему запрос .... скорее всего CLEAR_FEATURE
> 0x09 - тута видимо SET_CONFIGURATION

Думаю это скорее вот что:


/*
* HID class requests
*/
#define HID_REQ_GET_REPORT 0x01
#define HID_REQ_SET_REPORT 0x09

украдено отсюда: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux....


> 0x300 - это типа сколько байт будет передано

Мне кажется, это вот что: если взять вот эту спеку: http://www.usb.org/developers/devclass_docs/HID1_11.pdf ...есть на этой странице http://www.usb.org/developers/hidpage/ )

и посмотреть на главу "7.2.1 Get_Report Request", там в Remarks написано вот что:


The wValue field specifies the Report Type in the high byte and the Report
ID in the low byte. Set Report ID to 0 (zero) if Report IDs are not used.

Report Type is specified as follows:
Value   Report Type
01      Input
02      Output
03      Feature
04-FF   Reserved

Так что 0x0300 это просто Report Type = Feature (0x03 в верхем байте), при том что Report ID = 0, т.е. Report IDs не используются.

Короче вот мой полный коммит:
https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 05-Янв-14 06:23 
> Думаю это скорее вот что:
>
 
> /*
>  * HID class requests
>  */
> #define HID_REQ_GET_REPORT 0x01
> #define HID_REQ_SET_REPORT 0x09
>

А эта приблуда HID девайс? =-о


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 05-Янв-14 07:40 
>> Думаю это скорее вот что:
>>
 
>> /*
>>  * HID class requests
>>  */
>> #define HID_REQ_GET_REPORT 0x01
>> #define HID_REQ_SET_REPORT 0x09
>>

> А эта приблуда HID девайс? =-о

Всё указывает на это. А что?

Суть девайса: контроллер ATTiny, который с одной стороны умеет общаться с PC по USB, а с другой стороны выступает в качестве хоста сенсоров, т.е. коллектит данные сенсоров, которые висят на 1-wire шине (температурные датчики ds1820). Даём команды с компа через эту тулзовину на контроллер (по USB) и получаем выхлоп -- температуру датчиков, их ID и т.д. По идее логично такой девайс сделать HID.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 05-Янв-14 08:25 
>> А эта приблуда HID девайс? =-о
> Всё указывает на это. А что?

Отсюда http://ru.wikipedia.org/wiki/USB_HID :


Другие устройства

...

Этим стали массово пользоваться, и появилось огромное количество устройств, которые, по сути, интерфейсами взаимодействия с человеком не являются. Например, *термометр*, ..... Любое устройство может принадлежать к USB HID классу, если оно удовлетворяет логическим спецификациям HID Consumer Control.

Так что имеем USB HID термометр :)

Подобного добра уже было наделано много, в чём можно убедиться нагуглив по запросу "USB HID thermometer ATTiny45 DS18B20".

В прошивке они обычно юзают вот эту софтварную (bitbang) реализацию USB: http://www.obdev.at/products/vusb/index.html

Даже общие рекомендации есть: https://github.com/eldavido/cp-hidkeys/blob/master/Readme.txt


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 05-Янв-14 18:42 
>>> Думаю это скорее вот что:
>>>
 
>>> /*
>>>  * HID class requests
>>>  */
>>> #define HID_REQ_GET_REPORT 0x01
>>> #define HID_REQ_SET_REPORT 0x09
>>>

>> А эта приблуда HID девайс? =-о
> Всё указывает на это. А что?

Да это так, условности. HID, Audio, COM,...

USB делятся всего на 4 типа, по режиму передачи: Изохронные, Управляющие, Прерывания и Блобы (BULK).
По назначению  - все девайсы ENDPOINTы (Хабы отдельная песня)


"Как правильно собрать программу для Debian (Raspbian"
Отправлено did5 , 21-Фев-14 10:49 
>> Вот репозиторий с вашей программой, там более новая версия (1.1): https://code.google.com/p/bmcontrol/
> А еще лучше используйте мою версию отсюда: https://code.google.com/r/joeskb7-bmcontrol/

Добрый день,
Пытаюсь собрать bmcontrol для роутера ASUS WL500gP v.1 с прошивкой WL500gp-1.9.2.7-rtn-r5066.trx на ядре 2.6.22. Компилирую на самом устройстве. Версия программы 1.1 компилируется без ошибок, но неверно определяется ID датчиков, как у  DimNsk. Пробовал последнюю версию 1.1.1 от skb7, компилится с ошибками:

[admin@WL-500gP bm]$ make
cc -Wall -pedantic -O2 -s -Iinclude -std=c99 -D_POSIX_C_SOURCE=199309L -c -o src/main.o src/main.c
In file included from include/os/usb.h:5,
                 from src/main.c:8:
/opt/include/usb.h:67: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:73: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:80: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:93: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:118: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:144: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:161: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:178: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:253: error: expected specifier-qualifier-list before Б─≤u_int8_tБ─≥
/opt/include/usb.h:265: error: expected specifier-qualifier-list before Б─≤u_int32_tБ─≥
src/main.c: In function Б─≤find_lvr_winusbБ─≥:
src/main.c:88: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idVendorБ─≥
src/main.c:89: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idProductБ─≥
make: *** [src/main.o] Error 1

На Ubuntu все работает, а на роутере нет. Подскажите, в чем может быть проблема?


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 22-Фев-14 03:05 
Вычитывание ID датчиков неправильно работает из-за слишком маленькой задержки ожидания. Как временное решение можете использовать bmcontrol 1.1, но исправьте функцию задержки, как я описал в ответе #18 в этом треде.

Лучше конечно попробовать починить мою версию для вашего девайса.
Чтобы пофиксить мою версию, я хотел бы узнать следующее:
1. Какая версия libusb используется? 0.1 или 1.0?
2. По хорошему такое должно делаться кросс-компиляцией, а не компилить на самом девайсе. Есть тулчейн для вашего девайса? Я хотел бы воспроизвести вашу ошибку у себя и посмотреть, в чем дело.
3. Ваша прошивка -- это не OpenWRT случайно?


"Как правильно собрать программу для Debian (Raspbian"
Отправлено did5 , 23-Фев-14 23:33 
Большое спасибо за отклик.

Попробую собрать bmcontrol 1.1 с исправленной функцией задержки, напишу о результате.

Давайте попробуем починить вашу версию bmcontrol:
1. В прошивке роутера по умолчанию стоит libusb1.0, я дополнительно устанавливал libusb_0.1.12-2_mipsel.ipk отсюда http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/.

2. Я изначально хотел собрать кросс-компиляцией на Ubuntu 12.10, но там было очень много ошибок во время компиляции, которые поправить мне не удалось. Поэтому стал пытаться уже на самом устройстве. Тулчейн есть тут - https://code.google.com/p/wl500g/downloads/list. Я пробовал на версии hndtools-mipsel-uclibc-4.6.4-K26-r5299.tar.bz2.

3. Неа, прошивка не OpenWRT. Это прощивка от Олега доработанная энтузиастами 1.9.2.7-rtn-r5066 - https://code.google.com/p/wl500g/


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 24-Фев-14 01:54 
> 1. В прошивке роутера по умолчанию стоит libusb1.0, я дополнительно устанавливал libusb_0.1.12-2_mipsel.ipk
> отсюда http://ipkg.nslu2-linux.org/feeds/optware/oleg/cross/stable/.

т.е. вы собирали с 1.0? или с 0.1? потому что bmcontrol написана под libusb-0.1, естественно в 1.0 все изменилось и не будет собираться. Меня на эту мысль навело отсутствие полей idVendor и idProduct в структуре usb_device_descriptor (судя по ошибкам компиляции из вашего вывода сборки). Убедитесь в следующем:
1. при сборке должен использоваться хедер usb.h именно от версии 0.1 (строка номер 5 в файле include/os/usb.h в моем проекте).

Если у вас этот хедер лежит не в стандартном месте (/usr/include), то нужно явно это указать компилятору при сборке. Сделать это можно в файле Makefile: во второй строке (CFLAGS) указать этот путь с помощью флага "-I" таким образом (для /opt/include):


CFLAGS = -Wall -pedantic -O2 -s -Iinclude -I/opt/include

Также покажите вывод следующих команд:


$ pkg-config --cflags libusb
$ pkg-config --libs libusb

По хорошему вывод первой надо использовать в Makefile для задания CFLAGS в Makefile, а вывод второй -- для задания LDFLAGS в Makefile; CLFAGS и LDFLAGS попросту скармливаются потом компилятору и компоновщику соответственно, а поскольку "gcc" выступает в роли обоих -- то оба этих списка скармливаются gcc. Если у вас оно отработает корректно -- я поменяю у себя в проекте таким образом поведение мейк-файла.

2. при компоновке (linking) должна использоваться библиотека libusb именно версии 0.1
У меня в Makefile есть строка:


LDFLAGS = -lusb

это указывает компоновщику линковать проект с библиотекой libusb.so или libusb.a, но библиотека ищется по стандартным путям только (/usr/lib и т.д.). Если у вас libusb-0.1 лежит не по стандартному пути, нужно в LDFLAGS дописать путь к вашей либе таким образом (пример для случая если у вас либа лежит в /opt/lib):


LDFLAGS = -lusb -L/opt/lib

Т.е. у меня подозрение, что это не у меня криво сделано, а просто нестандартные пути у вас. Хотя правда возникает вопрос, почему версия 1.1 у вас нормально собирается... В общем, попробуйте сделать, что я написал пока, а насчет кросс-компиляции -- позже посмотрю и напишу.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 24-Фев-14 02:18 
В общем, я внес изменение в свой проект, чтобы использовался pkg-config при сборке, не знаю, может это поможет, проверьте. Обновить проект можно так:

$ git pull --rebase

Вот само изменение:

https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...

Но если у вас нет pkg-config или нет для него файла для libusb-0.1 (у меня он например поставляется с пакетом libusb-dev и находится тут: /usr/lib/x86_64-linux-gnu/pkgconfig/libusb.pc), то ничего вообще не соберется.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 24-Фев-14 02:38 
> Версия программы 1.1 компилируется без ошибок

Посмотрел, какие различия между моим и его мейк-файлом. Попробуйте сделать следующие шаги. После каждого пробуйте собирать. Один из них наверняка поможет (скорее всего самый первый пункт). Напишите потом плиз о резултьтатах. Вот что стоит попробовать:

1. Добавить в самое начало моего Makefile строку:


CC = g++


2. В список CFLAGS (в моем Makefile) добавить такое:


-I/usr/include


3. В список LDFLAGS добавить тоже самое что в предыдущем пункте было добавлено в CFLAGS.

4. В список LDFLAGS добавить:


-L/usr/lib


5. В список CFLAGS добавить:


$(EXTRA_CFLAGS)


"Как правильно собрать программу для Debian (Raspbian"
Отправлено did5 , 24-Фев-14 10:49 
> т.е. вы собирали с 1.0? или с 0.1?

Собирал для версии libusb-0.1, но я был не уверен, что компилятор использует именно версию 0.1, т.к. установлено обе версии libusb.

> В общем, я внес изменение в свой проект, чтобы использовался pkg-config при сборке, не
> знаю, может это поможет, проверьте.

Обновил проект. pkg-config на роутере есть, пути подставляются в Makrefile корректно. Но все равно ошибки, как в моем сообщении №46.


> 1. Добавить в самое начало моего Makefile строку: CC = g++

Добавил строку CC, вот такие ошибки:

[admin@WL-500gP bm1.1.2]$ make
g++ -Wall -pedantic -O2 -s -Iinclude -I/opt/include   -std=c99 -D_POSIX_C_SOURCE=199309L -c -o src/main.o src/main.c
cc1plus: warning: command line option "-std=c99" is valid for C/ObjC but not for C++
src/main.c: In function Б─≤uint64_t HexStringToUInt(char*)Б─≥:
src/main.c:641: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
make: *** [src/main.o] Error 1

Удалил строку СС и еще удалил строку CFLAGS += -std=c99 -D_POSIX_C_SOURCE=199309L из Makefile. Сборка прошла без ошибок, bmcontrol работает и теперь ID датчика определяется верно!

[admin@WL-500gP bm1.1.2]$ make
cc -Wall -pedantic -O2 -s -Iinclude -I/opt/include   -c -o src/main.o src/main.c
cc -o bmcontrol src/main.o -L/opt/lib -lusb
[admin@WL-500gP bm1.1.2]$ ./bmcontrol info
Firmware: 3h
USB series: 29h
USB identifier: a9bh
[admin@WL-500gP bm1.1.2]$ ./bmcontrol scan
temp_id1 = 8900000357526b28
[admin@WL-500gP bm1.1.2]$ ./bmcontrol temp 8900000357526b28
21.875000

Спасибо огромное.

P.S. Осталось только проверить правдивость показаний датчика.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено did5 , 11-Мрт-14 09:31 
> P.S. Осталось только проверить правдивость показаний датчика.

Результаты измерений похожи на правду.

Написал скрипт, который снимает показания каждые 5 минут и записывает их в файл. За несколько дней наблюдений выявилась странная особенность, иногда вместе с результатом измерения появляется сообщение - Error OW_WRITE_BYTE. Измерение температуры в этот момент происходит, как видно из лога:

16.7 11.03.2014_08:05
16.7 11.03.2014_08:10
Error OW_WRITE_BYTE 16.6 11.03.2014_08:15
16.6 11.03.2014_08:20
16.6 11.03.2014_08:25

Смотрел в код, но так и не смог разобраться, почему появляется это сообщение.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 11-Мрт-14 11:43 
>[оверквотинг удален]
> файл. За несколько дней наблюдений выявилась странная особенность, иногда вместе с
> результатом измерения появляется сообщение - Error OW_WRITE_BYTE. Измерение температуры
> в этот момент происходит, как видно из лога:
> 16.7 11.03.2014_08:05
> 16.7 11.03.2014_08:10
> Error OW_WRITE_BYTE 16.6 11.03.2014_08:15
> 16.6 11.03.2014_08:20
> 16.6 11.03.2014_08:25
> Смотрел в код, но так и не смог разобраться, почему появляется это
> сообщение.

Пока что не разбирался, в чем проблема, но сделал такой коммит:
https://code.google.com/r/joeskb7-bmcontrol/source/detail?r=...

Если вы обновите исходники, чтобы получить это изменение:


$ git pull --rebase


и пересоберете проект, то можно будет "выкинуть" сообщения об ошибках, чтобы они не мешали вашему скрипту:


$ ./bmcontrol 2>/dev/null

или если надо вести логи, то можно как-то так:


$ ./bmcontrol 2>log-err.txt | tee log-out.txt


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 11-Мрт-14 12:16 
> иногда вместе с результатом измерения появляется сообщение - Error OW_WRITE_BYTE

Очень похоже на то, что говорил pavlinux здесь:
https://www.opennet.ru/openforum/vsluhforumID9/9804.html#25

Попробуйте увеличить QUIRK_LIBUSB_SLEEP до 100. По-хорошему конечно надо переехать с libusb-0.1 на libusb-1.0, по идее там это починили.


> Смотрел в код, но так и не смог разобраться, почему появляется это
> сообщение.

Это сообщение показывается, если вызов OW_WRITE_BYTE() завершился некорректно в одной из следующих функций:
- MATCH_ROM()
- SEARCH_ROM()
- SKIP_ROM_CONVERT()
- GET_TEMPERATURE()

Думаю, в вашем случае это была GET_TEMPERATURE().

В каждой из этих функций в случае некорректного завершения OW_WRITE_BYTE делается несколько повторов (ONEWIRE_REPEAT=5), что видно из кода:


    while (!RESULT && N--)


Если за 5 повторов так и не вышло нормально выполнить OW_WRITE_BYTE(), тогда будет выведено сообщение о том, в какой верхней функции произошла ошибка (список этих функций я написал выше). Но поскольку вы видите всего один вывод об ошибке, значит при повторном чтении программе удалось нормально прочитать значение датчика и вывести его. Иначе бы вы увидели 5 выводов "Error OW_WRITE_BYTE" и потом еще вывод об ошибке верхней функции.

Глядя в код OW_WRITE_BYTE() можно увидеть, что всего 3 возможных причины ошибки:
1. ошибка в вызове USB_SET_FEATURE()
2. ошибка в вызове USB_GET_FEATURE()
3. некорректный USB буффер после чтения записанного значения (т.е. либо записалось что-то не то, либо прочиталось неправильно).

В нашем случае это 3-я ошибка. Почему она возникает -- см. в самом верху этого сообщения.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено did5 , 11-Мрт-14 13:37 
> Очень похоже на то, что говорил pavlinux здесь:
> https://www.opennet.ru/openforum/vsluhforumID9/9804.html#25
> Попробуйте увеличить QUIRK_LIBUSB_SLEEP до 100. По-хорошему конечно надо переехать с libusb-0.1
> на libusb-1.0, по идее там это починили.

Спасибо за развернутый ответ. Увеличил QUIRK_LIBUSB_SLEEP до 100, продолжаю наблюдение. Если не поможет, то поправлю скрипт, чтобы не выводил сообщения об ошибках по вашей инструкции.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 11-Мрт-14 16:18 
> Спасибо за развернутый ответ. Увеличил QUIRK_LIBUSB_SLEEP до 100, продолжаю наблюдение.
> Если не поможет, то поправлю скрипт, чтобы не выводил сообщения об
> ошибках по вашей инструкции.

Напишите плиз о результатах. Если поможет увеличение задержки на libusb_quirks -- я вмержу в свою ветку это изменение.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено did5 , 12-Мрт-14 10:08 
>> Спасибо за развернутый ответ. Увеличил QUIRK_LIBUSB_SLEEP до 100, продолжаю наблюдение.
>> Если не поможет, то поправлю скрипт, чтобы не выводил сообщения об
>> ошибках по вашей инструкции.
> Напишите плиз о результатах. Если поможет увеличение задержки на libusb_quirks -- я
> вмержу в свою ветку это изменение.

Не помогло. Вчера утром внес изменения - увеличил QUIRK_LIBUSB_SLEEP до 100, ошибок не было. Вечером добавил к плате еще два датчика температуры DS18B20, скрипт теперь считывает показания с трех датчиков и записывает результаты в файл. Наблюдал весь вечер - ошибок не было. Утром глянул лог, а там снова куча ошибок. Первая появилась около часа ночи, потом они стали регулярными:

16.5 0.6 20.6 12.03.2014_06:01
16.5 0.5 Error OW_WRITE_BYTE 20.6 12.03.2014_06:05
16.4 Error OW_WRITE_BYTE 0.5 Error OW_WRITE_BYTE Error OW_WRITE_BYTE 20.6 12.03.2014_06:10
Error OW_WRITE_BYTE Error OW_WRITE_BYTE 16.4 0.4 20.6 12.03.2014_06:15
16.4 Error OW_WRITE_BYTE 0.3 20.6 12.03.2014_06:20
16.4 0.3 20.6 12.03.2014_06:25
16.3 0.2 20.5 12.03.2014_06:30


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 12-Мрт-14 14:15 
> Не помогло. Вчера утром внес изменения - увеличил QUIRK_LIBUSB_SLEEP до 100, ошибок
> не было. Вечером добавил к плате еще два датчика температуры DS18B20,
> скрипт теперь считывает показания с трех датчиков и записывает результаты в
> файл. Наблюдал весь вечер - ошибок не было. Утром глянул лог,
> а там снова куча ошибок. Первая появилась около часа ночи, потом
> они стали регулярными:

Ну это не дело, конечно. Проблема может быть не только в libusb, а еще и в прошивке контроллера. Конечно, неплохо было бы разработать свой подобный девайс, написать там всё по уму, сделать его опен-сорсным. В этом девайсе, конечно, приходится только догадываться, что пошло не так.

Еще вариант (поскольку проблемы начались после подключения дополнительных датчиков) -- неправильное подключение внешних датчиков. Посмотрите по этой ссылке, как их подключать: http://www.sinava.ru/MP707.php

а именно ответ на этот вопрос:


- Подключил к устройству термодатчик на расстоянии 5 метров - работает нормально. Затем подключил его на расстоянии 40 метров - устройство его не видит! Но ведь заявлено расстояние до последнего термодатчика 100 метров по витой паре 5 категории. Но у меня растояние 40 метров! При этом хоть ВИТАЯ, хоть НЕ ВИТАЯ ПАРА, но устройство не видит термодатчик! Что можно сделать?


"Как правильно собрать программу для Debian (Raspbian"
Отправлено did5 , 12-Мрт-14 15:25 
> Ну это не дело, конечно. Проблема может быть не только в libusb,
> а еще и в прошивке контроллера. Конечно, неплохо было бы разработать
> свой подобный девайс, написать там всё по уму, сделать его опен-сорсным.
> В этом девайсе, конечно, приходится только догадываться, что пошло не так.

Верно, это было бы лучшим вариантом. К сожалению, разработчики контроллера не участвуют в дальнейшей его поддержки для *nix систем.

>[оверквотинг удален]
> http://www.sinava.ru/MP707.php
> а именно ответ на этот вопрос:
>

 
> - Подключил к устройству термодатчик на расстоянии 5 метров - работает нормально.
> Затем подключил его на расстоянии 40 метров - устройство его не
> видит! Но ведь заявлено расстояние до последнего термодатчика 100 метров по
> витой паре 5 категории. Но у меня растояние 40 метров! При
> этом хоть ВИТАЯ, хоть НЕ ВИТАЯ ПАРА, но устройство не видит
> термодатчик! Что можно сделать?
>

Да, видел эту статью. На ее основе подключал датчики. Я не думаю, что проблема с подключением, т.к. все дополнительные датчики определяются без проблем и показывают действительные показания температуры. Попробую потом отключить доп.датчики и посмотрю на наличие ошибок.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 24-Фев-14 00:49 
> src/main.c: In function Б─≤find_lvr_winusbБ─≥:
> src/main.c:88: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idVendorБ─≥  
> src/main.c:89: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idProductБ─≥
>  Подскажите, в чем может быть проблема?

Из браузера мышом копипастил? :)



"Как правильно собрать программу для Debian (Raspbian"
Отправлено did5 , 24-Фев-14 10:50 
>> src/main.c: In function Б─≤find_lvr_winusbБ─≥:
>> src/main.c:88: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idVendorБ─≥
>> src/main.c:89: error: Б─≤struct usb_device_descriptorБ─≥ has no member named Б─≤idProductБ─≥
>>  Подскажите, в чем может быть проблема?
> Из браузера мышом копипастил? :)

Копировал мышкой, но не из браузера, а из окна PuTTy.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 02-Янв-14 07:50 
Поскольку у вас есть девайс, не могли бы вы попробовать собрать и протестировать эту прогу на linux и windows? Я пофиксил несколько багов и сделал код кросс-платформенным, так что должно собираться и по идее работать на linux и windows. Написал автору на почту, может он себе в mainline затащит эти патчи.

Вот репозиторий: https://code.google.com/r/joeskb7-bmcontrol/

Склонировать исходники можно с помощб Git, командой:


git clone https://code.google.com/r/joeskb7-bmcontrol/


Инструкции по сборке -- в файле README.

Напишите результат как проверите.


"Как правильно собрать программу для Debian (Raspbian"
Отправлено pavlinux , 31-Дек-13 22:22 
>[оверквотинг удален]
> [D] CRC=c9
> [D] CRC=63
> [D] ~T=1000.000000
> [D] L1=ffffffff L2=ffffffff     L3=ff
> [D] CRC=8d
> [D] CRC=c9
> [D] CRC=63
> [D] ~T=1000.000000
> [!] Error GET_TEMPERATURE
> Что не так?


if (OW_READ_4BYTE(L1))
   if (OW_READ_4BYTE(L2))
      if (OW_READ_BYTE(L3)) {
     if (DEBUG)
            printf("[D] L1=%lx\tL2=%lx\tL3=%hhx\n", L1, L2, L3);

L1, L2, L3 - не инициализируются и передаются в эти функции, обратно - хрен, точнее bool.
  


"Как правильно собрать программу для Debian (Raspbian"
Отправлено skb7 , 30-Дек-13 05:18 
Тогда уже так, чтобы было более понятно, что это просто loop delay:


void ldelay(volatile unsigned long loops)
{
    while (loops--);
}


"Как правильно собрать программу для Debian (Raspbian"
Отправлено lukich , 02-Ноя-14 23:15 
Скажите пожалуйста, как добиться чтобы bmcontrol заработал без sudo?

/home/lukich/Downloads/bmcontrol temp a2000003351bd328
Could not set configuration 1 :
Device not plugged