【问题标题】:Continuous Bluetooth C program using threads使用线程的连续蓝牙 C 程序
【发布时间】:2014-10-09 11:39:27
【问题描述】:

我正在尝试通过蓝牙发送我的测量数据(温度、湿度和压力),它必须是连续的,所以我为此使用线程,但这对我来说太复杂了。

蓝牙客户端代码如下:

    #include "defines.h"

    void L2CAP_client(char *b_addr, float *temp, float *humi, float *pressure)
    {
        struct sockaddr_l2 addr = { 0 };

        struct Measurement_Data *Thread_Data = malloc(sizeof(struct Measurement_Data));
        int s, status;
        char dest[18];

        pthread_t Measurement_data_thread = 0;
        int  iret = 0;
        pthread_t Thread_id;

        strncpy(dest, b_addr, 18);

        // allocate a socket
        s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
        Thread_Data->s_ptr = s;

        // set the connection parameters (who to connect to)
        addr.l2_family = AF_BLUETOOTH;
        addr.l2_psm = htobs(0x1001);
        str2ba( dest, &addr.l2_bdaddr );

        // connect to server
        status = connect(s, (struct sockaddr *)&addr, sizeof(addr));

        Thread_Data->temp = *temp;
        Thread_Data->humi = *humi;
        Thread_Data->pressure = *pressure;

        // send a message
        if( status == 0 ) {

            iret = pthread_create(&Measurement_data_thread, NULL, &Thread_Function,    (void*) &Thread_Data);
        if(iret != 0){
        perror("Thread creation failed\n");
       }
    Thread_id = pthread_self();
    printf("ID of Temp_thread is: %u\n", (unsigned int)Thread_id);

}

    if( status < 0 ) perror("uh oh");

    printf("Thread 1 returns: %d\n",iret);

    pthread_join(Measurement_data_thread, NULL);


    close(s);
 }

void *Thread_Function(void* Measurement_Data)
{
    int s = 0;
    struct Measurement_Data *Thread_Data = (struct Measurement_Data*) Measurement_Data;

    s = Thread_Data->s_ptr;
    send(s, &Thread_Data, sizeof(Thread_Data), 0);
    free(Thread_Data);

    //return 0;
}

这是蓝牙服务器代码:

#include "defines.h"

struct Measurement_Data *L2CAP_server(void)
{
    struct sockaddr_l2 loc_addr = { 0 }, rem_addr = { 0 };
    char buf[256] = { 0 };
    int s, client, bytes_read;
    int opt = sizeof(rem_addr);
    static struct Measurement_Data Data;
    struct Measurement_Data *Thread_Data = malloc(sizeof(struct Measurement_Data));

    pthread_t Measurement_data_thread = 0;
    int  iret = 0;
    pthread_t Thread_id;

    // allocate socket
    s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);

    // bind socket to port 0x1001 of the first available
    // bluetooth adapter
    loc_addr.l2_family = AF_BLUETOOTH;
    loc_addr.l2_bdaddr = *BDADDR_ANY;
    loc_addr.l2_psm = htobs(0x1001);

    bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));

    // put socket into listening mode
    listen(s, 1);

    // accept one connection
    client = accept(s, (struct sockaddr *)&rem_addr, &opt);
    Thread_Data->c_ptr = client;

    ba2str( &rem_addr.l2_bdaddr, buf );
    fprintf(stderr, "accepted connection from %s\n", buf);

    memset(buf, 0, sizeof(buf));

    iret = pthread_create(&Measurement_data_thread, NULL, &Thread_Function, (void*) &Thread_Data);
    if(iret != 0){
        perror("Thread creation failed\n");
    }
    Thread_id = pthread_self();
    printf("ID of Temp_thread is: %u\n", (unsigned int)Thread_id);


    printf("Thread 1 returns: %d\n",iret);

    pthread_join(Measurement_data_thread, NULL);

    // close connection
    close(client);
    close(s);

    return (&Data);

}
void *Thread_Function(void* Measurement_Data)
{
    int c = 0;
    struct Measurement_Data *Thread_Data = (struct Measurement_Data*) Measurement_Data;

    c = Thread_Data->c_ptr;
    recv(c, &Thread_Data, sizeof(Thread_Data), 0);
    printf("Temp: %0.1f\n", Thread_Data->temp);
    printf("Humi: %0.1f\n", Thread_Data->humi);
    printf("Pres: %0.1f\n", Thread_Data->pressure);
    free(Thread_Data);

    //return 0;
}

它只发送零,我也收到此错误:* glibc detected * ./anturi_luku: munmap_chunk(): invalid pointer: 0xbef48738 ***

我需要使用互斥锁来锁定数据是对的吗?

【问题讨论】:

    标签: bluetooth pthreads continuous


    【解决方案1】:

    Valgrind 在这种情况下是一个非常有用的工具。你能使用 Valgrind 吗?你能分享一下valgrind报告吗?

    确保使用 'db-attach' 选项,因为 Valgrind 将在显示每个错误后暂停并打印该行。尝试使用以下命令,将 a.out 替换为您的文件名。

    $ valgrind --tool=memcheck --db-attach=yes ./a.out

    【讨论】:

    • 感谢您的快速回复!有没有其他方法可以处理这种情况,因为 valgrind 显然没有在 arm 架构上工作。我收到此错误:valgrind: failed to start tool 'memcheck' for platform 'arm-linux': No such file or directory – 编辑:树莓派似乎也有 valgrind。
    【解决方案2】:

    这是来自客户端的 valgrind 报告:

    ==2157== Memcheck, a memory error detector
    ==2157== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==2157== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==2157== Command: ./anturi_luku
    ==2157== 
    Temperature: 22.7C
    Humidity: 61.7%
    Temperature: 22.7C
    Humidity: 61.7%
    pressure= 0, 0, 0
    Pressure: 0.0 Pa
    ID of Temp_thread is: 67241968
    Thread 1 returns: 0
    ==2157== Thread 2:
    ==2157== Invalid free() / delete / delete[] / realloc()
    ==2157==    at 0x48348B8: free (vg_replace_malloc.c:427)
    ==2157==    by 0x8C0B: Thread_Function (L2CAP_client.c:89)
    ==2157==    by 0x485FBFB: start_thread (pthread_create.c:306)
    ==2157==    by 0x4962967: ??? (clone.S:116)
    ==2157==  Address 0xbde575e8 is on thread 1's stack
    ==2157== 
    ==2157== 
    ==2157== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- n
    ==2157== 
    ==2157== HEAP SUMMARY:
    ==2157==     in use at exit: 16 bytes in 1 blocks
    ==2157==   total heap usage: 2 allocs, 2 frees, 152 bytes allocated
    ==2157== 
    ==2157== LEAK SUMMARY:
    ==2157==    definitely lost: 16 bytes in 1 blocks
    ==2157==    indirectly lost: 0 bytes in 0 blocks
    ==2157==      possibly lost: 0 bytes in 0 blocks
    ==2157==    still reachable: 0 bytes in 0 blocks
    ==2157==         suppressed: 0 bytes in 0 blocks
    ==2157== Rerun with --leak-check=full to see details of leaked memory
    ==2157== 
    ==2157== For counts of detected and suppressed errors, rerun with: -v
    ==2157== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 6)
    

    【讨论】:

      【解决方案3】:

      很高兴您能够获得基于 ARM 的 C 语言蓝牙 L2CAP 客户端的 Valgrind 报告。

      如您所见,当第一个错误发生时,您将被询问以下内容。

      ---- 附加到调试器? --- [返回/N/n/Y/y/C/c] ----

      按 Ret、N Ret 或 n Ret 会导致 Valgrind 不针对此错误启动调试器。

      此时按下 Y Ret 或 y Ret 会导致 Valgrind 启动程序的调试器。

      从日志中可以看出,使用了“n”。你能用'Y'试试吗?

      此外,从日志看来,无效免费已完成。与其内联,似乎 free() 是在未分配的内存上调用的。检查一下。

      【讨论】:

      • 这很奇怪,因为我分配了两次内存,而且我释放了两次内存,正如您从我的代码中看到的那样。那我是在分配或释放错误吗?
      【解决方案4】:

      现在我的错误消息消失了。这是 pthread_create 函数的第四个参数。我删除了 & 字符。现在函数看起来像这样:pthread_create(&Measurement_data_thread, NULL, &Thread_Function, (void*) Thread_Data);

      但它仍然没有发送或接收任何数据。当我使用 printf 检查要在发送端 thread_function 上发送的那些数据值时,它们很好。但在接收端,它有时只打印零,有时什么也不打印。

      我现在需要互斥锁来锁定数据吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多