This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] uint64_t 变量将接收值移位32位

Guru**** 2315160 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1506902/uint64_t-variable-shifts-received-value-by-32-bits

部件号:LP-EM-CC1354P10
主题中讨论的其他器件:CC1354P10SYSBIOS

工具/软件:

您好、

我在代码中有一个 typedef 结构、如下所示:

/* Typedef Struct definition */
typedef struct {
    uint32_t timestamp;
    uint64_t status;
    float data[32];
    uint32_t packet_id;
    int8_t  rssi;
} dataPoint_t;

我为 status 变量分配一个值、例如:

dataPoint_t dataPoint;
dataPoint.status = 15;

然后、该变量显示正在接收向左移动32位的值、我打印时显示为64424509440。

为什么会发生这种情况、如何获得正确的值?

提前感谢、
Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    对于包含代码的源文件、其中...

    Unknown 说:
    我为状态变量分配一个值

    ... 请遵循文章 如何提交编译器测试案例中的指示

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、George、

    我尝试遵循文章中的说明、但我使用的是 CCS 20.0.2、因此找不到仅编译.c 文件的选项。 您能否提供有关如何执行该操作的说明?

    谢谢你。

    此致、
    Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    抱歉。  此文章未更新为可与 CCSv20配合使用。   

    右键单击问题源文件的名称。  选择 工程属性 。  更改预处理器设置接近于相同。  无法仅构建一个文件。 相反、应编译整个工程。  因为 .o 为问题源文件生成的文件不是目标文件、链接失败。  忽略该故障。  要撤消这些更改、请右键单击问题源文件、然后选择 恢复已覆盖的 Build-Settings 。   

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、George、

    我通过选择"预处理源文件、保留注释(-C)"选项更改了预处理器设置、没有"使用-pp 后继续编译"选项、因此我没有检查任何其他内容。 但随后编译失败、并显示消息"tiarmclang:error:无效参数'-C '只允许与'-E'"一起使用。

    如果我同时使用-C 和-E 选项编译代码、则这是输出:

    我没有看到任何生成的文件要提交、我需要做什么?

    谢谢你。

    此致、
    Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    对于基于 clang 的编译器(如 tiarmclang)、正确的预处理选项是 -E -C 。  这将更改自动创建的 .o 将预处理文件转换为包含预处理输出的文本文件。  这就是链路失败的原因。  减少 .o 是要提交给 TI 的文件。  如何提交编译器测试用例中的其余说明 是正确的、即使对于 CCSv20也是如此。

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的测试用例。  我用它将测试用例构建到汇编源代码。  这是该汇编的一小部分。

    	ldr	r7, .LCPI4_1
    	ldr.w	r8, .LCPI4_2
    	ldr	r5, .LCPI4_3		@ r5 = &dataPoint
    	ldr	r6, .LCPI4_4
    	mov.w	r9, #0			@ r9:r10 = 15
    	mov.w	r10, #15
    	movs	r4, #19
    .Ltmp44:
    .LBB4_4:
    	ldrb	r0, [r7]
    .Ltmp45:
    	cbz	r0, .LBB4_6
    .Ltmp46:
    	bl	get_send_interval
    .Ltmp47:
    	bl	get_seconds2wait
    .Ltmp48:
    	bl	sleep
    .Ltmp49:
    	mov	r0, r8
    	bl	oeeDebug
    .Ltmp50:
    	bl	get_current_timestamp
    .Ltmp51:
    	str	r0, [r5]
    	ldr.w	r0, [r5, #144]
    	strd	r10, r9, [r5, #8]	@ dataPoint.status = 15
    

    这大致相当于 C 代码的这一部分...

                sleep(get_seconds2wait(get_send_interval()));
                // sleep(10); //debug
    
                oeeDebug("Creating dataPoint");
                /* Create dataPoint */
                dataPoint.timestamp = get_current_timestamp();
                dataPoint.status = /*lib_status_get_curr_value()*/ (uint64_t)15;

    在装配体中、我添加了 @μ s 注释。  请注意寄存器对是如何的 R9:R10  加载常数15。  该对被存储到  [R5、#8]  前一条指令。  请注意几个函数是如何调用的( BL 说明)。  这是有效的 、因为 tiarmclang 寄存器惯例 需要这些函数以及它们调用的所有函数来保留这些寄存器。  这些函数之一或其调用的一个函数是否在汇编中实现、并且该汇编程序无法同时保留 R9和 R10?

    谢谢。此致、

    -乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、George、

    很抱歉晚才回复。

    函数 get_seconds2wait ()、get_send_interval ()和 oeeDebug ()没有在汇编中实现。 sleep ()函数来自 TI 的 SimpleLink SDK 8.30.01.01。

    get_current_timestamp ()函数也没有在汇编中实现,下面是它的实现:

    uint32_t get_current_timestamp (){
    timestamp_get64 (和 ts);
    uint64_t ticks =((uint64_t) uart.hi ts << 32)| ts
    time_t current_time_ms =(time_t)((ticks * 1000ULL)/ freq.lo);
    返回(MIN_DEVICE_DATA.BOOT_TIMESTAMP +(CURRENT_TIME_ms/1000));
    }

    timestamp_get64函数也从 TI 的实验室中使用。

    我希望这会很有用。 如果您需要更多信息、请告诉我。

    此致、
    Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、George、

    它有可能是编译器的优化吗? 这是配置:

    我以 Wi-SUN CoAP 节点为例作为基础、并将其修改到我的工程、以防它有所帮助。

    此致、
    Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Eduardo:

    感谢您所做的所有调试工作。
    我将与团队跟进、并在获得更多见解后立即更新此主题。

    此致、
    Theo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Theo:

    如果在数据点结构中将其类型值设置为 int32_t、您是否可以获得正确的 RSSI 值?

    此致、

    Arthur

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Arthur:

    我将 RSSI 类型从 int8_t 更改为 int32_t、然后我做了数据点。RSSI = 50、是、我得到了正确的值。

    此致、
    Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Eduardo:

    很高兴听到这解决了您的问题。

    此致、
    Theo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Theo:

    实际上、这并没有解决我的问题。 此处的问题与 uint64_t 类型(本例中为 datapoint.status 变量)相关。

    我以为阿瑟只是要求我为他测试一些东西。

    此致、
    Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Eduardo:

    因此、用 uint32_t 类型替换 RSSI 时、是否仍然出现状态问题? 我想检查内存校准是否可能导致此问题。

    此致、

    Arthur  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Arthur:

    是的、即使将 RSSI 替换为 int32_t、问题仍然存在 我可以正确获得 RSSI 值、但状态值移动了32位、例如:设置数据点.status =(uint64_t) 50我读取时报告的值为214748364800。

    此致、
    Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    我还做了几个测试、我想与您分享。

    我实施了一个堆栈以在两个不同的任务之间共享数据。 以下是我用于收集和保存数据的有效载荷管理器头文件和源文件:

    /* payload-manager.h */ 
    
    #ifndef PAYLOAD_MANAGER_H
    #define PAYLOAD_MANAGER_H
    
    /* Define declaration */
    #include "hal_types.h"
    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    #include <ti/drivers/dpl/SemaphoreP.h>
    
    // #include "network-interface.h"
    // #include "nvs-datapoint.h"
    
    #define PAYLOAD_MANAGER_TASK_PRIORITY  5
    #define PAYLOAD_MANAGER_STACK_SIZE     2048
    #define STACK_CAPACITY 3
    
    /* Typedef Struct definition */
    typedef struct {
        uint32_t timestamp;
        uint64_t status;
        float data[32];
        uint32_t packet_id;
        uint16_t battery;
        int32_t rssi;
    } dataPoint_t;
    
    typedef struct {
        dataPoint_t buffer[STACK_CAPACITY];
        int top;     // próximo slot livre
        int count;   // quantos elementos estão salvos
        // Mutex de proteção de acesso
        SemaphoreP_Struct mutex;
        SemaphoreP_Handle mutexHandle;
        // Semáforo de contagem para controle de dados disponíveis
        SemaphoreP_Struct countSem;
        SemaphoreP_Handle countSemHandle;
    } dataStack_t;
    
    void *payloadManagerThread(void *arg0);
    
    /* 
     * Functions prototypes
     */
    /* Queue Data Stack */
    bool dataStack_pop(dataPoint_t *outData);
    void dataStack_push(dataPoint_t *newData);
    
    extern dataStack_t dataStack;
    
    #endif /* PAYLOAD_MANAGER_H */

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    payload-manager.c:

    /* payload-manager.c */
    #include "payload-manager.h"
    /* Extern variables used to CoAP communication with border router */
    extern volatile bool connectedFlg;
    extern uint8_t max_rssi_in;
    /* Local variables */
    char thing_alias[12];
    dataPoint_t dataPoint = {.packet_id = 0};
    dataStack_t dataStack;
    
    void dataStack_init(void) {
        SemaphoreP_Params semParams;
        SemaphoreP_Params_init(&semParams);
        semParams.mode = SemaphoreP_Mode_BINARY;
        dataStack.mutexHandle = SemaphoreP_construct(&dataStack.mutex, 1, &semParams);
        SemaphoreP_Params_init(&semParams);
        semParams.mode = SemaphoreP_Mode_COUNTING;
        dataStack.countSemHandle = SemaphoreP_construct(&dataStack.countSem, 0, &semParams);
        dataStack.top = 0;
        dataStack.count = 0;
    }
    void dataStack_push(dataPoint_t *newData) {
        SemaphoreP_pend(dataStack.mutexHandle, SemaphoreP_WAIT_FOREVER);
        if (dataStack.count == STACK_CAPACITY) {
            memmove(&dataStack.buffer[0], &dataStack.buffer[1], sizeof(dataPoint_t) * (STACK_CAPACITY - 1));
            dataStack.top = STACK_CAPACITY - 1;
            dataStack.count = STACK_CAPACITY - 1;
        }
        oeeDebug("DEBUG PUSH 0: %lld", newData->status);
        memcpy(&dataStack.buffer[dataStack.top], newData, sizeof(dataPoint_t));
        oeeDebug("DEBUG PUSH 1: %lld", dataStack.buffer[dataStack.top].status);
        dataStack.top++;
        dataStack.count++;
        SemaphoreP_post(dataStack.mutexHandle);
        SemaphoreP_post(dataStack.countSemHandle);
    }
    bool dataStack_pop(dataPoint_t *outData) {
        SemaphoreP_pend(dataStack.countSemHandle, SemaphoreP_WAIT_FOREVER);
        SemaphoreP_pend(dataStack.mutexHandle, SemaphoreP_WAIT_FOREVER);
        if (dataStack.count == 0) {
            SemaphoreP_post(dataStack.mutexHandle);
            return false;
        }
        dataStack.top--;
        dataStack.count--;
        oeeDebug("DEBUG POP 0: %lld", dataStack.buffer[dataStack.top].status);
        memcpy(outData, &dataStack.buffer[dataStack.top], sizeof(dataPoint_t));
        SemaphoreP_post(dataStack.mutexHandle);
        return true;
    }
    
    void *payloadManagerThread(void *arg0) {
        dataStack_init();
        while (1) {
            if(connectedFlg) {
                sleep(10);
                oeeDebug("Creating dataPoint");
                dataPoint.status = /*lib_status_get_curr_value()*/51;
                if (connectedFlg) {
                    dataStack_push(&dataPoint);
                }
            }
        }
        return NULL;
    }

    为了能够在此处粘贴代码、我需要删除一些行、但与问题相关的所有内容都得到了维护。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是 comm-manager.c 代码、该代码使用已定义的 pop 函数、我希望收到正确的状态变量:

    /* comm-manager.c */
    void *commManagerThread(void *arg0) {
        dataPoint_t data;
    // some code runs here before...
                if (dataStack_pop(&data)) {
                    oeeDebug("Status read at comm-manager: %lld", data.status);
                    //do something
                }
    // code continues...
    }

    "oeeDebug (...)" 函数只是对 UART 函数的打印、我可以用它来输出数据并进行调试。

    运行此代码后、结果如下所示:

    Creating dataPoint
    DEBUG PUSH 0: 51
    DEBUG PUSH 1: 51
    DEBUG POP 0: 223338299391

    如您所见、dataStack_push 函数似乎可以正常工作、当我尝试使用 dataStack_pop 读取完全相同的值时、它会将向左移动32位的值打印出来。

    我注意到了其他问题:如果我在 payload-manager.c 中使用 dataStack_pop、则可以正确读取该值。 因此、出于某种原因、当我尝试从另一个.c 代码读取值时遇到了这个问题、但我不知道确切的原因。

    我希望这些信息可以提供有关如何解决这个问题的任何想法、我不知道这里发生了什么。

    提前感谢您。
    此致、
    Eduardo。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    我注意到、如果我在 comm-manager.c 文件中创建一个 datapoint_t 变量、则问题也会发生、因此 push/pop 函数似乎不是问题。

    在 commerManagerThread 中、我创建了:

    数据点 test_data;
    TEST_DATA.STATUS = 66;

    我可以看到同样的行为、打印数据显示为值283467841536。

    此致、
    Eduardo。