Uploaded image for project: 'Data Management'
  1. Data Management
  2. DM-37040

Document interface for readDaq in ts_m2fpga project in Phase 3

    XMLWordPrintable

    Details

    • Type: Story
    • Status: Done
    • Resolution: Done
    • Fix Version/s: None
    • Component/s: ts_main_telescope
    • Labels:

      Description

      Continue the experiment with LabVIEW FPGA code and C programming using the FPGA C API Interface. Work on the comments/questions in the previous ticket DM-36940:

      • check the mistakes in the code snippet comments.
      • help to clarify the returned memory region in "acquire" function is in stack or heap. And the OS can reallocate the memory after the "releasing" or not. There is the problem of memory leakage or not. This demonstration can be done in another ticket.

      and try to answer these questions:

      • question1: what will happen if there are no elements or less than the requested elements?
      • question2: what will happen if I want to release 5 elements and there are only 2 or 0 elements in the FIFO?
      • question3: what will happen if I want to add more elements in the FIFO but there is no available space?

        Attachments

          Issue Links

            Activity

            Hide
            pcortes Patricio Cortes added a comment - - edited

            Question 1: what will happen if there are no elements or less than the requested elements?
            (github branch: noElementsInFifo)

            To answer this question I considered two designs:

            Design 1: Using the NiFpga_ReadFifoU16() one time only, and numberOfElements = 9.
            Design2: Using the NiFpga_ReadFifoU16() with numberOfElements = 0 first and if elementsRemaining >= 9, then numberOfElements = 9, and start reading FIFO elements.

            With Design1:
            No elements yet in the RT side of FIFO:
            With timeout = 0

            • the NiFpga_ReadFifoU16() returns the timeout error, status = -50400 (The timeout expired before the FIFO operation could complete). The data read is (0-0-0-0-0-0-0-0-0).
            • If new data is written on FIFO, status = 0, and new data is read (1-2-3-4-5-6-7-8-9).
            • The function will get the timeout error again (status = -50400) until new data is received. The data read is still (1-2-3-4-5-6-7-8-9-10).
            • If new data is received (10-11-12-13-14-15-16-17-18), status = 0, and the reading is (2-3-4-5-6-7-8-9-10). → not sure why this happens.
            • The function will get the timeout error again (status = -50400) until new data is received. The data read is still 2-3-4-5-6-7-8-9-10.
            • If new data is received (19-20-21-22-23-24-25-26-27), the reading is (3-4-5-6-7-8-9-10-11) → not sure why this happens.

            With Design2:
            No elements yet in the RT side of FIFO:

            • In this case, the design waits for enough elements to read (9 in the example).

            Less elements than required:

            • In this design, there will be enough elements to read always, because we are counting elementsRemaining >= 9?, and if this is True, then elements are read.
            • If the numberOfElements required is NEVER enough, we will be waiting forever or until the program stops.
            Show
            pcortes Patricio Cortes added a comment - - edited Question 1: what will happen if there are no elements or less than the requested elements? (github branch: noElementsInFifo) To answer this question I considered two designs: Design 1: Using the  NiFpga_ReadFifoU16()  one time only, and  numberOfElements = 9 . Design2: Using the  NiFpga_ReadFifoU16() with numberOfElements = 0 first and if elementsRemaining >= 9 , then numberOfElements = 9 , and start reading FIFO elements. With Design1: No elements yet in the RT side of FIFO: With timeout = 0 the NiFpga_ReadFifoU16()  returns the timeout error, status = -50400 (The timeout expired before the FIFO operation could complete). The data read is (0-0-0-0-0-0-0-0-0). If new data is written on FIFO, status = 0, and new data is read (1-2-3-4-5-6-7-8-9). The function will get the timeout error again ( status = -50400 ) until new data is received. The data read is still (1-2-3-4-5-6-7-8-9-10). If new data is received (10-11-12-13-14-15-16-17-18), status = 0, and the reading is (2-3-4-5-6-7-8-9-10). → not sure why this happens. The function will get the timeout error again ( status = -50400 ) until new data is received. The data read is still 2-3-4-5-6-7-8-9-10. If new data is received (19-20-21-22-23-24-25-26-27), the reading is (3-4-5-6-7-8-9-10-11) → not sure why this happens. With Design2: No elements yet in the RT side of FIFO: In this case, the design waits for enough elements to read (9 in the example). Less elements than required: In this design, there will be enough elements to read always, because we are counting elementsRemaining >= 9? , and if this is True, then elements are read. If the numberOfElements required is NEVER enough, we will be waiting forever or until the program stops.
            Hide
            ttsai Te-Wei Tsai added a comment -

            For the Design 1 and 2, I think it is better to put non-zero timeout value and check the behavior of timeout error and the related elements in FIFO (if any, both in C and LabVIEW side). In addition, unless there is a good reason, the blocking call should be avoided unless you have a good design to be able to close the application as soon as possible when needed.

            Show
            ttsai Te-Wei Tsai added a comment - For the Design 1 and 2, I think it is better to put non-zero timeout value and check the behavior of timeout error and the related elements in FIFO (if any, both in C and LabVIEW side). In addition, unless there is a good reason, the blocking call should be avoided unless you have a good design to be able to close the application as soon as possible when needed.
            Hide
            pcortes Patricio Cortes added a comment - - edited

            After a few weeks of working on another project, I return to this ticket. Unfortunately, on Monday I wasted time working on this ticket with the wrong bitfile, so the results were always incorrect. Fortunately yesterday I realized this and fixed this.

            Show
            pcortes Patricio Cortes added a comment - - edited After a few weeks of working on another project, I return to this ticket. Unfortunately, on Monday I wasted time working on this ticket with the wrong bitfile, so the results were always incorrect. Fortunately yesterday I realized this and fixed this.
            Hide
            pcortes Patricio Cortes added a comment - - edited

            These are the new results after fixing the problem with the bitfile that I mentioned before.

            Question 1: what will happen if there are no elements or less than the requested elements?

            To answer this question I considered two designs:

            Design 1: Using the NiFpga_ReadFifoU16() one time only, and set the numberOfElements = 9.
            Design 2: Using the NiFpga_ReadFifoU16() with numberOfElements = 0 first and ask if elementsRemaining >= 9, then set numberOfElements = 9, and start reading FIFO elements.

            With Design1:

            • I created the branch features/noElementsFifoDesign1.
            • The FPGA writes 9 elements from 1 to 9, then 10 to 18, and so on.
            • Set timeout = 0.
            • Since there are no elements to read or less than the requested, the NiFpga_ReadFifoU16() returns the timeout error (status = -50400) which means the timeout expired before the FIFO operation could complete. The data read is (0-0-0-0-0-0-0-0-0) at the first reading.
            • If new data is written on FIFO, status = 0, and new data is read (1-2-3-4-5-6-7-8-9).
            • The function will get the timeout error again until new data is received.
            • If new data is received (10-11-12-13-14-15-16-17-18), status = 0, and the reading is (10-11-12-13-14-15-16-17-18), as expected.
            • Set timeout = -1, following Te-Wei's previous comment. The "con" in this case is adding a blocking call. We try to avoid it.
            • If we set timeout = 5 (5 ms) for instance, the NiFpga_ReadFifoU16() will wait for 5 ms to receive data and will return the timeout error if any data is received.
            • In the 0e12afb commit, I set timeout = 0 and ask if status = 0 then read the data received and printed on the terminal, else I printed the message "No data to read yet..."
            • This design allows us to avoid a blocking call and executes an action based on the status value.

            With Design2:

            • I created the branch features/noElementsFifoDesign2.
            • The FPGA writes 9 elements from 1 to 9, then 10 to 18, and so on.
            • In this case, the design waits for enough elements to read (9 in the example).
            • If there are fewer elements than required, the code will wait until the number of elements received is greater or equal to the requested number of elements, so there will be always enough elements to read.
            • In this design, there is no blocking call.
            • If the number of elements required is NEVER enough, we will be waiting forever or until the program stops.

            With Design1 and set numberOfElements = 11:

            • I created the branch features/lessElementsFifoDesign1.
            • In the Design1 set numberOfElements = 11 (more than 9) and the FPGA writing 9 elements from 1 to 9, then 10 to 18, and so on.
            • I added an indicator in the mainFPGA.vi called fpgaError that shows the FIFO write function error terminal. This will be read in the RT target C code.
            • NiFpga_ReadFifoU16() works ok the first reading, i.e. (1-2-3-4-5-6-7-8-9-10-11).
            • The status of this function gets the value -63195 (NiFpga_Status_InvalidSession) which means the session is invalid or has been closed. Not sure why this happens.
            • After this, the function stops reading, and the FPGA can't be stopped.

             

            Show
            pcortes Patricio Cortes added a comment - - edited These are the new results after fixing the problem with the bitfile that I mentioned before. Question 1: what will happen if there are no elements or less than the requested elements? To answer this question I considered two designs: Design 1: Using the  NiFpga_ReadFifoU16()  one time only, and set the  numberOfElements = 9 . Design 2: Using the  NiFpga_ReadFifoU16()  with  numberOfElements = 0  first and ask if  elementsRemaining >= 9 , then set  numberOfElements = 9 , and start reading FIFO elements. With Design1: I created the branch  features/noElementsFifoDesign1. The FPGA writes 9 elements from 1 to 9, then 10 to 18, and so on. Set  timeout = 0. Since there are no elements to read or less than the requested, the  NiFpga_ReadFifoU16()  returns the timeout error ( status =   -50400) which means the timeout expired before the FIFO operation could complete. The data read is (0-0-0-0-0-0-0-0-0) at the first reading. If new data is written on FIFO,  status = 0,  and new data is read (1-2-3-4-5-6-7-8-9). The function will get the timeout error again until new data is received. If new data is received (10-11-12-13-14-15-16-17-18),  status = 0,  and the reading is (10-11-12-13-14-15-16-17-18), as expected. Set  timeout = -1,  following Te-Wei's previous comment. The "con" in this case is adding a blocking call. We try to avoid it. If we set  timeout = 5 (5 ms) for instance, the  NiFpga_ReadFifoU16()  will wait for 5 ms to receive data and will return the timeout error if any data is received. In the  0e12afb  commit, I set timeout = 0 and ask if status = 0 then read the data received and printed on the terminal, else I printed the message "No data to read yet..." This design allows us to avoid a blocking call and executes an action based on the status value. With Design2: I created the branch  features/noElementsFifoDesign2. The FPGA writes 9 elements from 1 to 9, then 10 to 18, and so on. In this case, the design waits for enough elements to read (9 in the example). If there are fewer elements than required, the code will wait until the number of elements received is greater or equal to the requested number of elements, so there will be always enough elements to read. In this design, there is no blocking call. If the number of elements required is NEVER enough, we will be waiting forever or until the program stops. With Design1 and set numberOfElements = 11: I created the branch  features/lessElementsFifoDesign1. In the Design1 set  numberOfElements = 11 (more than 9) and the FPGA writing 9 elements from 1 to 9, then 10 to 18, and so on. I added an indicator in the mainFPGA.vi called fpgaError that shows the FIFO write function error terminal. This will be read in the RT target C code. NiFpga_ReadFifoU16() works ok the first reading, i.e. (1-2-3-4-5-6-7-8-9-10-11). The status of this function gets the value -63195 (NiFpga_Status_InvalidSession) which means the session is invalid or has been closed. Not sure why this happens. After this, the function stops reading, and the FPGA can't be stopped.  
            Hide
            ttsai Te-Wei Tsai added a comment - - edited

            This experiment is based on the "read' function. How about the result of "acquire" function?

            I think the summary of test of "read" function is:

            1. Assume I want to read 1 element and there is no element in FIFO.
                (a) timeout = 0. I will get the timeout error immediately.
                (b) timeout = -1. I will wait the element forever.

            2. Assume I want to read 1 element and there is 1 element in FIFO. No matter what the timeout value is, I will get the element.

            3. Assume I want to read 2 elements and there is only 1 element in FIFO. No matter what the timeout value is, the function will wait forever for the element. --> This is based on the comment: "If the number of elements required is NEVER enough, we will be waiting forever or until the program stops." But this is weird for this part: "The status of this function gets the value -63195 (NiFpga_Status_InvalidSession) which means the session is invalid or has been closed. Not sure why this happens.".

            Actually, for the point 3, I thought the normal design should be giving you the element I have or timeout error (assume the timeout is not -1). Please double check. If only returning the existed element (which is not enough), there should be a byte data read or something similar to tell you that you do not get all the data you requested to read.
             

            I think the problem in the design of experiment is: "The FPGA writes 9 elements from 1 to 9, then 10 to 18, and so on.". I think you should just write the data once only here. In addition, the final part of comment is concerning ("The status of this function gets the value -63195 (NiFpga_Status_InvalidSession) which means the session is invalid or has been closed. Not sure why this happens.").

             

            If the point 3 is correct, the safest way for C/C++ developer should be just reading one element at a time (assume he/she has no other information to know the status of FIFO). By doing this, the behavior of timeout is predictable.

            Show
            ttsai Te-Wei Tsai added a comment - - edited This experiment is based on the "read' function. How about the result of "acquire" function? I think the summary of test of "read" function is: 1. Assume I want to read 1 element and there is no element in FIFO.     (a) timeout = 0. I will get the timeout error immediately.     (b) timeout = -1. I will wait the element forever. 2. Assume I want to read 1 element and there is 1 element in FIFO. No matter what the timeout value is, I will get the element. 3. Assume I want to read 2 elements and there is only 1 element in FIFO. No matter what the timeout value is, the function will wait forever for the element. --> This is based on the comment: "If the number of elements required is NEVER enough, we will be waiting forever or until the program stops." But this is weird for this part: "The status of this function gets the value -63195 (NiFpga_Status_InvalidSession) which means the session is invalid or has been closed. Not sure why this happens.". Actually, for the point 3, I thought the normal design should be giving you the element I have or timeout error (assume the timeout is not -1). Please double check. If only returning the existed element (which is not enough), there should be a byte data read or something similar to tell you that you do not get all the data you requested to read.   I think the problem in the design of experiment is: "The FPGA writes 9 elements from 1 to 9, then 10 to 18, and so on.". I think you should just write the data once only here. In addition, the final part of comment is concerning ("The status of this function gets the value -63195 (NiFpga_Status_InvalidSession) which means the session is invalid or has been closed. Not sure why this happens.").   If the point 3 is correct, the safest way for C/C++ developer should be just reading one element at a time (assume he/she has no other information to know the status of FIFO). By doing this, the behavior of timeout is predictable.
            Hide
            ttsai Te-Wei Tsai added a comment - - edited

            In design 2, the following part should not happen because you checked there should be the enough elements already:

            """

            • If there are fewer elements than required, the code will wait until the number of elements received is greater or equal to the requested number of elements, so there will be always enough elements to read.
            • In this design, there is no blocking call.
            • If the number of elements required is NEVER enough, we will be waiting forever or until the program stops.

            """

            Show
            ttsai Te-Wei Tsai added a comment - - edited In design 2, the following part should not happen because you checked there should be the enough elements already: """ If there are fewer elements than required, the code will wait until the number of elements received is greater or equal to the requested number of elements, so there will be always enough elements to read. In this design, there is no blocking call. If the number of elements required is NEVER enough, we will be waiting forever or until the program stops. """
            Hide
            pcortes Patricio Cortes added a comment -

            After improving the experiment, and using the "read' function, I got the following results:

            1. Assume I want to read 1 element and there is no element in FIFO.
                (a) timeout = 0. I will get the timeout error -50400 immediately (The timeout expired before the FIFO operation could complete).
                (b) timeout = -1. I will wait for the element forever.

            2. Assume I want to read 1 element and there is 1 element in FIFO. No matter what the timeout value is, I will get the element.

            3. Assume I want to read 2 elements and there is only 1 element in FIFO.
                (a) timeout = 0. I will get the timeout error -50400 immediately (The timeout expired before the FIFO operation could complete).
                (b) timeout = -1. I will wait for the element forever.

            The next experiment will use the "acquire" function.

            Show
            pcortes Patricio Cortes added a comment - After improving the experiment, and using the "read' function, I got the following results: 1. Assume I want to read 1 element and there is no element in FIFO.     (a) timeout = 0. I will get the timeout error -50400 immediately (The timeout expired before the FIFO operation could complete).     (b) timeout = -1. I will wait for the element forever. 2. Assume I want to read 1 element and there is 1 element in FIFO. No matter what the timeout value is, I will get the element. 3. Assume I want to read 2 elements and there is only 1 element in FIFO.     (a) timeout = 0. I will get the timeout error -50400 immediately (The timeout expired before the FIFO operation could complete).     (b) timeout = -1. I will wait for the element forever. The next experiment will use the "acquire" function.
            Hide
            pcortes Patricio Cortes added a comment -

            Using the "acquire' function, I got the following results:

            1. Assume I want to read 1 element and there is no element in FIFO.
                (a) timeout = 0. I will get the timeout error -50400 immediately (The timeout expired before the FIFO operation could complete) and I will get the "Segmentation fault" message.
                (b) timeout = -1. I will wait for the element forever.

            2. Assume I want to read 1 element and there is 1 element in FIFO. No matter what the timeout value is, I will get the element.

            3. Assume I want to read 2 elements and there is only 1 element in FIFO.
                (a) timeout = 0. I will get the timeout error -50400 immediately (The timeout expired before the FIFO operation could complete)  and I will get the "Segmentation fault" message.
                (b) timeout = -1. I will wait for the element forever.

            I need to read and understand more about this function, how it manages the memory, and why this message appears.

            Show
            pcortes Patricio Cortes added a comment - Using the "acquire' function, I got the following results: 1. Assume I want to read 1 element and there is no element in FIFO.     (a) timeout = 0. I will get the timeout error -50400 immediately (The timeout expired before the FIFO operation could complete) and I will get the "Segmentation fault" message.     (b) timeout = -1. I will wait for the element forever. 2. Assume I want to read 1 element and there is 1 element in FIFO. No matter what the timeout value is, I will get the element. 3. Assume I want to read 2 elements and there is only 1 element in FIFO.     (a) timeout = 0. I will get the timeout error -50400 immediately (The timeout expired before the FIFO operation could complete)  and I will get the "Segmentation fault" message.     (b) timeout = -1. I will wait for the element forever. I need to read and understand more about this function, how it manages the memory, and why this message appears.
            Hide
            ttsai Te-Wei Tsai added a comment -

            Segmentation fault --> application is killed by the OS (as expected). Therefore, the "read" function is safer (the application is still alive).

            Show
            ttsai Te-Wei Tsai added a comment - Segmentation fault --> application is killed by the OS (as expected). Therefore, the "read" function is safer (the application is still alive).
            Hide
            pcortes Patricio Cortes added a comment - - edited

            After a quick analysis with Te-Wei about the C code that I wrote, we realized the "Segmentation fault" appears after I try to print the data received in FIFO, and not after I executed the "acquire" function, Therefore I can conclude the error -50400 appears in both functions and both are safer (the application is still alive). 

            Show
            pcortes Patricio Cortes added a comment - - edited After a quick analysis with Te-Wei about the C code that I wrote, we realized the "Segmentation fault" appears after I try to print the data received in FIFO, and not after I executed the "acquire" function, Therefore I can conclude the error -50400 appears in both functions and both are safer (the application is still alive). 
            Hide
            ttsai Te-Wei Tsai added a comment -

            Discussed with Patricio in Slack. Now we understand the behavior of "get" and "acquire" function. Great job done!

            Show
            ttsai Te-Wei Tsai added a comment - Discussed with Patricio in Slack. Now we understand the behavior of "get" and "acquire" function. Great job done!
            Hide
            pcortes Patricio Cortes added a comment -

            you mean "read" instead of "get" function .

            Show
            pcortes Patricio Cortes added a comment - you mean "read" instead of "get" function .

              People

              Assignee:
              pcortes Patricio Cortes
              Reporter:
              pcortes Patricio Cortes
              Reviewers:
              Te-Wei Tsai
              Watchers:
              Patricio Cortes, Te-Wei Tsai
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Jenkins

                  No builds found.