Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

NIOS II C language about SDRAM IOWR & IORD function and fopen & fclose

Hi, I'm new about Quartus II & NIOS II.

I made hardware part using sopc builder (nios II cpu, sdram, on-chip mem,

jtag, sysid, and so on)

and composed c source code for software part.

I want to get right output data from 'printf' function

and test1.txt file from 'fopen, fprintf, fclose' function

,but i didn't get any right result.

How can I solve this problems?

=======================================================# include <stdio.h># include <unistd.h># include "system.h"

# define DEBOUNCE 10000

int main()

{

int input_data = 0x0001;

int output_data;

FILE *fp;

IOWR(SDRAM_0_BASE, 0, input_data);

output_data = IORD(SDRAM_0_BASE, input_data);

printf("output data = %d\n", output_data);

fp = fopen("C:\test1.txt", "w");

fprintf(fp, "%d", output_data);

fclose(fp);

return 0;

}

=======================================================

Thanks in advance.

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    > fp = fopen("C:\test1.txt", "w");

    if you know where is "c:\" on your board?

    when you just create CPU(NiosII)

    you don't have file-system

    you need to create file-system as well.( Linux, uC-OSII or by yourself).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Teddy,

    Apart from the fopen issue, I'm concerned about the two R/W instructions:

    IOWR(SDRAM_0_BASE, 0, input_data);
     output_data = IORD(SDRAM_0_BASE, input_data);
    Problem 1:

    You are writing to address 0 and reading from address 1 (content of input_data) which has not been initialized.

    Maybe, you meant this:

    output_data = IORD(SDRAM_0_BASE, 0);
    Problem 2:

    Are you sure this part of sdram is not already used for anything else?

    Otherwise your IOWR would corrupt code or other data.

    Cris
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi teddy,

    --- Quote Start ---

    p = fopen("C:\test1.txt", "w");

    fprintf(fp, "%d", output_data);

    fclose(fp);

    --- Quote End ---

    Akira is right. You need a filesystem for that.

    But as Cris mentioned, I am also concerned about the IOWR/IORD-part.

    If I got you right, you want to write input_data to some SDRAM-address and read it back for printing it.

    First: I would let the compiler allocate memory for you, unless you know what is at the specified address. You can use malloc or something like that or you just declare a variable.

    For example (assumed that data region is located at SDRAM):

    #include <stdio.h># include <unistd.h># include "system.h"
    int input_data = 1;
    int output_data = 0;
    int output_data_read = 0;
    int main()
    {
        IOWR(&output_data,0,input_data); // write input_data to output_data with IOWR
        output_data_read = IORD(&output_data,0); // read it back from output_data to output_data_read
        printf("output data = %d\n", output_data_read); // printing on STDOUT
       return 0;
    }
    
    Second: I would usually use IOWR/IORD only in cases where it can be neccessary. Like bypassing the data cache. Otherwise, better use standard C-coding for accessing memory.

    Regards,

    Philipp
    • Yogesh's avatar
      Yogesh
      Icon for Occasional Contributor rankOccasional Contributor
      Hi,
      How to use standard C coding to access memory as per your answer?
      I am having an array of data say 1,2,3...10. I want to write this data to FPGA memory( say address 1,2,3...10) using C code .
      How to do this ? Can you please provide a sample code to do the same ?

      Thankyou
      Regards,
      Yogesh
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Hi Teddy,

    Apart from the fopen issue, I'm concerned about the two R/W instructions:

    IOWR(SDRAM_0_BASE, 0, input_data);
     output_data = IORD(SDRAM_0_BASE, input_data);
    Problem 1:

    You are writing to address 0 and reading from address 1 (content of input_data) which has not been initialized.

    Maybe, you meant this:

    output_data = IORD(SDRAM_0_BASE, 0);
    Problem 2:

    Are you sure this part of sdram is not already used for anything else?

    Otherwise your IOWR would corrupt code or other data.

    Cris

    --- Quote End ---

    Thanks for your answer.

    I used 16bit input_data in c code and

    16bit SDRAM using SOPC Builder,

    but I got only 8bit output_data.

    Where is the problem?

    <result>

    output data1 = 11111111

    output data2 = 10101010

    =================================================# include <stdio.h># include <unistd.h># include "system.h"

    int main()

    {

    long input_data1 = 0x0000000011111111;

    long input_data2 = 0x1010101010101010;

    long output_data1;

    long output_data2;

    IOWR(SDRAM_0_BASE, 0, input_data1);

    output_data1 = IORD(SDRAM_0_BASE, 0);

    printf("output data1 = %x\n", output_data1);

    IOWR(SDRAM_0_BASE + 1, 0, input_data2);

    output_data2 = IORD(SDRAM_0_BASE + 1, 0);

    printf("output data2 = %x\n", output_data2);

    return 0;

    }

    =================================================
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    > fp = fopen("C:\test1.txt", "w");

    if you know where is "c:\" on your board?

    when you just create CPU(NiosII)

    you don't have file-system

    you need to create file-system as well.( Linux, uC-OSII or by yourself).

    --- Quote End ---

    Hi again!

    Do you know how can I get from SDRAM data to my hard driver?

    My goal is to have binary data of txt file form...

    Thanks for your continuous concern.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Teddy,

    0x prefix stands for hex number. One hex digit = 4bit !!!

    You must use 0b00101... to specify a binary number.

    Moreover, your 'long' data variables are actually 64bit long !

    You are getting the correct 32bit prints with %x format.

    If you want complete 64bit print you should use %lx or %llx

    If you want ram native 16bit data access, you should define variables as 'short'.

    Cris
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    int main()

    {

    long input_data1 = 0x0000000011111111;

    long input_data2 = 0x1010101010101010;

    long output_data1;

    long output_data2;

    IOWR(SDRAM_0_BASE, 0, input_data1);

    output_data1 = IORD(SDRAM_0_BASE, 0);

    printf("output data1 = %x\n", output_data1);

    IOWR(SDRAM_0_BASE + 1, 0, input_data2);

    output_data2 = IORD(SDRAM_0_BASE + 1, 0);

    printf("output data2 = %x\n", output_data2);

    return 0;

    }

    --- Quote End ---

    I think it is not possible to perform 64 bit IOWR.

    If you want to write 64 bit data you have to split it up into 2*IOWR.

    Use IOWR twice.

    Or am I wrong here? NIOS is 32bit
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    oh you are teddy80

    hi again.

    if you have UART(RS-232C)

    you can program on NiosII to send data from SDRAM.

    and your computer can get RS232C data some how like hyper terminal.

    RS232C is slow...

    there is several way. LAN / SD-Card / USB ...

    but many things are difficult after all.

    you need to learn more.

    UART is easy to use.

    I recommend biginer to use UART to read data from embedded system.

    see you and good luck