30/09/2018, 23:10

Không hiểu C++ source code - Truy xuất dữ liệu

Các bạn IT cho mình hỏi về đoạn code sau nhé (mình bên điện tử nên chỉ hiểu được tầm 40% mục đính của đoạn code sau) vì vậy mình cũng chưa biết cách để ứng dụng nó vào bài tập của mình. Đây là source code của 1 công ty điện tử, mình muốn dựa vào nó để phát triển tiếp ứng dụng của mình.

Đại loại là như thế này: Mình có 1 số dữ liệu, dữ liệu này được lưu vào vùng nhớ của 1 con chip. Nhiệm vụ của mình là đọc dữ liệu đó. Vùng nhớ này gọi là FIFO (First In First Out) nó cũng giống như EEPROM nhưng khả năng truy xuất nhanh hơn (nói thật mình cũng chưa hiểu hết về nó.)

Đây là đoạn code mà mình muốn hỏi:

Gen2ReaderInterface::Gen2Result SL900AMainDialog::coolLogAccessFIFO ( CoolLogError &error, unsigned char subcommand, QByteArray writePayload, QByteArray &readPayload )
{
    itsExecutedCommand = CMD_ACCESS_FIFO;
    error = CoolLogError::CoolLogNoError;
    itsRequest.clear();
    itsAnswer.clear();

    int appendedBytes = writePayload.length();
    unsigned int numBytesAvail = 0;
    switch (subcommand)
    {
    case 0xA0: 
        itsRequest[0] = 0xA0 + appendedBytes;
        itsRequest.append(writePayload);
        itsGen2Res = executeCommand(CMD_ACCESS_FIFO , (24 + appendedBytes * 8), itsRequest, 1, itsAnswer);
        break;
    case 0x80: 
        //read Bytes Available
        itsRequest.append((char)0xC0);
        itsGen2Res = executeCommand(CMD_ACCESS_FIFO , 24 , itsRequest, 9, readPayload);
        numBytesAvail = (readPayload[0] & 0x0F);
        //perform read
        itsRequest[0] = 0x80 | (numBytesAvail & 0x0F);
        itsGen2Res = executeCommand(CMD_ACCESS_FIFO , 24 , itsRequest, (1 + numBytesAvail * 8) , readPayload);
        break;
    
    case 0xC0: // Status
              itsRequest.append(subcommand);
              itsGen2Res = executeCommand(CMD_ACCESS_FIFO , 24 , itsRequest, 9, readPayload);
              break;
              
    }
    if (itsGen2Res != Gen2ReaderInterface::Gen2_OK)
        error = static_cast<CoolLogError>(static_cast<unsigned char>(itsAnswer[0]));

    return itsGen2Res;
}

Ở đây theo mình hiểu là: hàm có các biến truyền vào error, subcommand, writePayload and readPayload. Mình chỉ tập trung vào phần readPayload thôi, vì dùng để đọc dữ liệu.
Tương ứng với readPayload thì subcommand = 0x80.

Tuy nhiên khi mình đọc file hướng dẫn đối với con chip dùng để giao tiếp dữ liệu thì


subcommand = 0x80 tương đương với việc đọc 0 byte từ FIFO. Vì thế khi mình thử dùng lệnh:

itsGen2Res = itsParent->coolLogAccessFIFO(itsCoolLogError, 0x80, 0, readPayload);

thì không thấy kết quả gì. Các bạn IT cho mình hỏi là mình nên hiểu đoạn code trên như thế nào cho đúng. Xin cảm ơn.

Văn Dương viết 01:19 ngày 01/10/2018

Cái này chỉ có đi hỏi mấy ông bên điện tử đã từng làm con này. Hỏi IT sao mà biết được.

BiNa2605 viết 01:15 ngày 01/10/2018

Chỉ hỏi về code thôi, còn phần cứng mình sẽ tự tìm hiểu. Nói thật mình cũng hỏi bên điện tử rồi, nhưng toàn chỉ là những cái lắc đầu.
Ý mình ở đây là hàm coolLogAccessFIFO nó trả giá trị gì về, mình chỉ tập trung vô phần subcommand = 0x80 thôi. Nếu có gì thì mình discuss với nhau tại vì cái này họ viết phần giao diện. Thanks.

Hung viết 01:15 ngày 01/10/2018

Gì mà 0x80 là đọc 0 byte vậy pa?
0x80 là bật chế độ đọc FIFO
Còn số byte được đọc là giá trị của numBytesAvail
Trong đó
numBytesAvail = (readPayload[0] & 0x0F)

BiNa2605 viết 01:18 ngày 01/10/2018

Hi hungvu,

Nên khi mình thử apply đoạn code này vào
itsGen2Res = itsParent->coolLogAccessFIFO(itsCoolLogError, 0x80, 0, readPayload);

mình dùng subcommand = 0x80, phần writePayload mình không dùng nên cho giá trị bằng 0. Nhưng không có kết quả.

Khi so sách với phần hướng dẫn thì 3 bit đầu của subcommand là 100 = read data from FIFO. còn 4 bit cuối 3-0 để xác định có bao nhiêu bytes cần đọc từ bộ nhớ FIFO. Vậy từ 0x80 = 0b1000000 thì mình suy ra là đọc 0 byte từ FIFO. Còn phần code mẫu mình vẫn chưa hiểu lắm. Nếu như bạn nói là 0x80 là để bật chế độ đọc từ FIFO và số byte được đọc nhận từ giá trị của numBytesAvail thì mình sẽ xem lại thật kỹ phần này.

Bạn cho mình hỏi thêm là cái hàm coolLogAccessFIFO return giá trị itsGen2Res, thì cái giá trị này chính là kết quả của hàm executeCommand ở trên đúng không bạn. Thanks.

Hung viết 01:13 ngày 01/10/2018
  1. Giá trị phần tử đầu tiên của mảng readPayload truyền vào chính là giá trị quyết định số Byte cần đọc. Đoạn code rõ mồn một thế mà. Subcommand 0x80 chỉ quyết định giá trị của bit số 5-6-7, còn giá trị của bit số 0-3 phụ thuộc vào giá trị từ 0-3 của readPayload[0].
  2. Giá trị của itsGen2Res chính là kết quả của executeCommand.
Quân viết 01:26 ngày 01/10/2018

sao bạn có thể suy luận như thế được nhỉ.

numBytesAvail = (readPayload[0] & 0x0F)

sẽ lấy 4 bit cuối của giá trị readPayload[0], đây coi như 1 phép làm tròn số thôi, max sẽ chỉ có thể lấy ra 16 byte.

itsRequest[0] = 0x80 | (numBytesAvail & 0x0F);

dùng để bật bit đầu tiên của cái numBytesAvail thành 0b100… chứ không phải như bạn nghĩ là đọc 0 byte đâu

BiNa2605 viết 01:18 ngày 01/10/2018

Cảm ơn bạn nhé. Mình giao tiếp với máy tính qua UART thì được. Nhưng khi dùng đoạn code mẫu thì kết quả không có gì:
itsGen2Res = itsParent->coolLogAccessFIFO(itsCoolLogError, 0x80, 0, readPayload);

Bạn cho mình hỏi giờ mình muốn lấy giá trịn readPayload[0] ra để kiểm tra thì mình nên làm như thế nào. Mình đang làm bên ứng dụng RFID.

BiNa2605 viết 01:13 ngày 01/10/2018

@qloved, @hungvu: Thanks mấy bạn nhé. Lỗi của mình ở đây là mình vừa đọc giá trị bằng UART và đọc bằng Radio Frequency wave nên bị xung đột. Mình tắt UART và dùng cùng đoạn code:
itsGen2Res = itsParent->coolLogAccessFIFO(itsCoolLogError, 0x80, 0, readPayload);

thì đã đọc được tín hiệu. Mình debug bằng cách thay subcommand = 0xC0 để đọc giá trị trạng thái của chip rồi xem coi nó đang ở trạng thái nào. Sau đó suy luận dần ra. Mặc dù hiện giờ mình đã đọc được tín hiệu từ FIFO nhưng mình vẫn còn gặp 1 lỗi sau mong các bạn cho mình thêm gợi ý.

Tín hiệu mình đọc về nó như thế này.

Phần code lấy giá trị:

tempX0 = static_cast<int>(readPayload[0]); tempX1 = static_cast<int>(readPayload[1]); tempY0 = static_cast<int>(readPayload[2]);

Thay vì những giá trị phải được giữ nguyên thì nó lại trả về 0. Mình tự suy luận các trường hợp sau:

  • Thời gian delay không đúng nên cần phải đồng bộ bên gửi tín hiệu và bên nhận tín hiệu.
  • Rớt gói tín hiệu -> cho dù rớt gói thì mình vẫn mong muốn tín hiệu được giữ nguyên ở trạng thái cũ.

Mong các bạn góp ý cho mình. Xin cảm ơn.

Nguyen Ca viết 01:26 ngày 01/10/2018

tempX0 = static_cast<int>(readPayload[0]);tempX1 = static_cast<int>(readPayload[1]);tempY0 = static_cast<int>(readPayload[2]);

không làm C++ nhưng mình đoán static_cast(int) nó ép về kiểu integer(số nguyên :0.1->0…). bạn debug xem giá trị của nó là bao nhiêu?

BiNa2605 viết 01:16 ngày 01/10/2018

Mình truyền vào số nguyên trước (số đó mình biết trước), sau đó mình ép kiểu để tính toán cho sau này. Nên không có trường hợp số thập phân. Thanks bạn.

BiNa2605 viết 01:16 ngày 01/10/2018

I solved my problem. Thanks, all.

Bài liên quan
0