Community
cancel
Showing results for 
Search instead for 
Did you mean: 
chgm
Beginner
183 Views

printf() make the code work

Hi, all

I am in a trouble with printf(...). The problem is , when I insert the printf(...), my code runs correctly, when I ignore printf(...), it will fail.

The simple code runs in NIOS II,   for co-operating image processing.  Part of main() shown as below:

int main()
{
printf("Hello from Nios II!\n");
/*variable declaration*/
alt_u32 proc_num = 0;
alt_u32 frame_len = 0;
alt_u32 read_addr[16]; 
alt_u32 write_addr[16];

alt_msgdma_standard_descriptor a_descriptor[16]; //maximum 16 descriptors

alt_msgdma_dev * msgdma_dev_ptr = alt_msgdma_open("/dev/msgdma_img_proc_csr");
if (!msgdma_dev_ptr){
printf ("FAIL: Unable to open msgdma device");
return 1;
}
alt_msgdma_register_callback(msgdma_dev_ptr, msgdma_callback_function, 0, msgdma_dev_ptr);

/*fill in address array*/
for (int i = 0; i < 16; ++i){
read_addr[i] = RAM_BASE_ADDRESS + i * (0x800000);//start at 0, 16M, 32M...
write_addr[i] = RAM_BASE_ADDRESS + ( i + 1) * (0x800000); //start at 8M, 24M, 40M...
//printf("read address %d is 0x%08x\n", i, (unsigned int)read_addr[i]);
//printf("write address %d is 0x%08x\n", i, (unsigned int)write_addr[i]);
}

alt_dcache_flush_all(); // need to make sure all the data is written out to memory

do {
printf("spin until mailbox int.\n");
while (mb_interrupt_fired == 0) {} //wait for mailbox int
mb_interrupt_fired = 0; //restore int flag
/*prepare for 1st process*/
//calc frame length
proc_num = 0;

frame_len = ((IORD_32DIRECT(IMG_PROC_SUBMOD_0_BASE, IMG_SIZE_OFS) & VSIZE_MASK )>> 16) * \
(IORD_32DIRECT(IMG_PROC_SUBMOD_0_BASE, IMG_SIZE_OFS) & HSIZE_MASK );

proc_num = IORD_32DIRECT(IMG_PROC_SUBMOD_0_BASE, IMG_PRE_PROC_CH_EN_OFS);

printf("proc channel enable register is 0x%08x.\n", (unsigned int)proc_num);
proc_num = 0;
for (int i = 0; i < 32; ++i){
proc_num = proc_num + ((IORD_32DIRECT(IMG_PROC_SUBMOD_0_BASE, IMG_PRE_PROC_CH_EN_OFS) >> i) & 0x1);
}
printf("Number of proc loops is %d.\n", (int)proc_num);


/****************generate descriptor start***************/

//generate control bit
unsigned long control_bits = ALTERA_MSGDMA_DESCRIPTOR_CONTROL_TRANSFER_COMPLETE_IRQ_MASK | ALTERA_MSGDMA_DESCRIPTOR_CONTROL_ERROR_IRQ_MASK;
//generate descriptors
for (int i = 0; i < proc_num; ++i) {
if (alt_msgdma_construct_standard_mm_to_mm_descriptor (msgdma_dev_ptr, a_descriptor + i, (alt_u32 *)read_addr[i], (alt_u32 *)write_addr[i], frame_len, control_bits)!=0) {
printf("Failed to construct descriptor.");
return 1;
}
}

//write descriptor to msgdma
while ((IORD_ALTERA_MSGDMA_CSR_STATUS(MSGDMA_IMG_PROC_CSR_BASE) & ALTERA_MSGDMA_CSR_RESPONSE_BUFFER_FULL_MASK) != 0) {}
if(alt_msgdma_standard_descriptor_async_transfer (msgdma_dev_ptr, a_descriptor) != 0)
{
printf("Failed to write descriptor0 to the descriptor SGDMA port.");
return 1;
}

printf("Now waiting for interrupt... \n");
while (msgdma_interrupt_fired == 0) {} // wait for msgdma int
//printf("msgdma_int is %d\n",msgdma_interrupt_fired );
msgdma_interrupt_fired = 0;
//switch proc channel
alt_u32 temp_data = IORD_32DIRECT(IMG_PROC_SUBMOD_0_BASE, IMG_PRE_PROC_CH_EN_OFS) & (0xfffffffe);

IOWR_32DIRECT(IMG_PROC_SUBMOD_0_BASE, IMG_PRE_PROC_CH_EN_OFS, temp_data);
//handle next proc loops
if (proc_num > 1){
for (int i = 1; i < proc_num; ++i){
/****************generate descriptor start***************/
//wait until buffer has space
while ((IORD_ALTERA_MSGDMA_CSR_STATUS(MSGDMA_IMG_PROC_CSR_BASE) & ALTERA_MSGDMA_CSR_RESPONSE_BUFFER_FULL_MASK) != 0) {}


/****************generate descriptor end****************/

//printf("the descriptor read address is 0x%08x\n", (unsigned int)(a_descriptor[i].read_address));
//printf("the descriptor write address is 0x%08x\n", (unsigned int)(a_descriptor[i].write_address));
//printf("the descriptor transfer length is 0x%08x\n", (unsigned int)(a_descriptor[i].transfer_length));
//printf("the descriptor control register is 0x%08x\n", (unsigned int)(a_descriptor[i].control));

//write descriptor to msgdma
if (alt_msgdma_standard_descriptor_async_transfer (msgdma_dev_ptr, a_descriptor + i ) != 0)
{
printf("Failed to write descriptor %d to the descriptor SGDMA port.\n", i);
return 1;
}

//switch proc channel
while (msgdma_interrupt_fired == 0) {} // wait for msgdma int
msgdma_interrupt_fired = 0;
temp_data = IORD_32DIRECT(IMG_PROC_SUBMOD_0_BASE, IMG_PRE_PROC_CH_EN_OFS) & (0xfffffffe<<i);
//printf("The CH_EN register is 0x%08x.\n",temp_data);
IOWR_32DIRECT(IMG_PROC_SUBMOD_0_BASE, IMG_PRE_PROC_CH_EN_OFS, temp_data);
}

}
//after last proc loop, write PCIE-CRA to generate interrupt
IOWR_32DIRECT(PCIE_CV_HIP_AVMM_0_BASE+A2P_MAILBOX0_OFS, 0, 0x1);
} while (1);

return 0;
}

That is if only the printf() (coloured in blue) runs before the alt_msgdma_standard_descriptor_async_transfer (), then the MSGDMA can run correctly, otherwise, it will hang on. When I use sigtap to cpature the descriptor write bus, the regions of descriptor is all 0. I have tried to do following experiments:

Add delay instead of printf(), but not work.

Print some others not related with descriptor, such as "print("Hello!\n")", also does not work.

Also I have tried to add volatile , static keywords before the a_desciptor[] array, no use.

Only enable one of the four blue "printf()", it works.

Set a breakpoint at the "if" sentence after printf, and run by manually click "RESUME" button for each loop,   it also works.

I am so confused about this , Appreciate to any suggestion.

 

 

0 Kudos
2 Replies
Eliath_G_Intel
Employee
159 Views

Hi Chenguan,

Thanks for reaching us,


Regarding your issue, have you tried to do it with some extra but simple steps? what I mean with this is that if you have tried to

save the content you want to print, in a variable and then print this variable.



Please let me know if this solved it, so we can keep looking into the issue to see what could have been the root issue and solved it in a better way.


Thanks,

-Eliath Guzman



chgm
Beginner
152 Views

Hi, Eliath

Thanks for your response!

I have tried your suggestion, and that works.

Reply