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.

HTU can not update N2HET RAM after free-RTOS is running.

Other Parts Discussed in Thread: TMS570LC4357, HALCOGEN

Hi TI,

I am using TMS570Lc4357 with Free-RTOS (HalCoGen generated Code). And I am using N2HET and HTU Module in my project.

In my HET Instruction, data field of Second Instruction will be get updated by HTU DCP0 and the HTU request is generated by the 6th instruction.

Before running RTOS StartScheduler() function, I configure HTU and N2HET modules and then Starts the N2HET, and it give request to the HTU module.

Upon receiving the HTU request from the N2HET module, HTU starts transmission from the Main RAM to HET RAM. This I can confirm by monitoring the CDCP0 of HTU1.

So everything is fine. N2HET works well and HTU1 works well. But the problem is N2HET RAM is not getting updated with new value transmitted by the HTU module. HTU Write access is discarded by somehow. I dont know why it is happening. After running StartScheduler() also same happens.

I have given my code below as a zip file.

8831.HETHTURTOS.zip

Please anybody go through this and please guide me to update N2HET RAM data field using HTU module.

Please explain me why I cannot Update N2HET RAM with HTU module even though HTU is performing the transfer.

Expecting a guidance.

Thanks in advance,

Regards,

karthikeyan.K



  • I was told that FreeRTOS changes MPU settings. It could change the access to NHET RAM. You will need to check FreeRTOS documents to see where it is done and how to change it.

    Thanks and regards,

    Zhaohong

  • I would like to take back my earlier post. HTU access to NHET RAM is not related to the Cortex-R5 MPU settings. You need to check the following.

    (1) Is HTU actually get triggered? If you set HTU for moving a block data, you should see the HTU tranfer completion flag getting set.
    (2) Is the HTU set up (direction, address, etc) correctly?

    Thanks and regards,

    Zhaohong
  • Hi Zhaohong,

    I check these things thoroughly.

    1. HTU is really getting triggered. No doubt.

    2. And HTU is do transmitting to the location exactly I expect in the N2HET RAM.

    I confirm these two things by analysing CITCOUNT register. It keeps on incrementing when N2HET is running.

    further, CADDRA and CADDRB points the source location correctly.

    There is no issues in HTU Side.

    Problem is N2HET RAM miss the data from the HTU.

    May be it is because some HTU has no write access on N2HET RAM by somehow.

    I dont know how to predict it. That's why I submit my code too for expert advise.

    Please go through that code sir. You may really see my problem.

    And one more thing. Please do comment following lines in the HL_het.c file so that HTU can get the trigger properly. (I forget to comment them before posting.)

    hetREG1->REQENC |= (uint32)(~SetCh); //remaining request line is enabled.
    hetREG2->REQENC |= (uint32)(~SetCh); //remaining request line is enabled.
    
    (Please comment the abouve two line in the HL_het.c file from upload zip file.)

    Hope I can get good guidance soon.

    Thanks in advance,

    Regards,

    Karthikeyan.K

  • To verify if HTU actually writes to NHET RAM, I would suggest you use HTU to write to an NHET RAM location which is not overwritten by NHET. You can then use CPU to read the contnet in the NHET RAM. You can also modify NHET code so that the same instruction also generate an interrupt. CPU can read the NHET RAM in the ISR. In this way, you can check every HTU write.

    Thanks and regards,

    Zhaohong
  • I did checking HTU in that manner sir.

    Actually Before the scheduler starts, I configure HTU and N2HET then Enable both of them means, at that time HTU gets request from N2HET and perform transmission and N2HET receive the data, everything is fine.

    Problem arises after the scheduler only.

    After Scheduler starts, and inside 10ms Task, if I configure HTU and N2HET then enable them, at that time, HTU get request from N2HET and perform Transmission but N2HET cannot receive the data.

    I ensure this as the way you said. i.e: The data field which should be updated by HTU is not updated by N2HET. In that try also same thing happens.

    I dont know why after RTOS code N2HET RAM is not getting updated eventhough HTU is trying to update it.

    What should be the cause?
    I cannot predict.

    Thanks and regards,
    karthikeyan.K
  • "inside 10ms Task, if I configure HTU and N2HET then enable them". I think that this could be the cause of the issue. Why do you want to restart a timer every 10 ms? I would suggest you to toggle a NHET pin at the instruction issuing the HTU request to see if NHET runs as expected.

    Thanks and regards,

    Zhaohong
  • Inside 10ms task I scans Serial Port for command from PC.
    If first command comes from the PC, I will prepare HTU and N2HET with Configuration #1, and Enable them,
    If Second command comes from PC, I will disable HTU and N2HET and prepare them again with Configuration#2

    So If no Second command comes from PC, the HTU and N2HET module will keeps on running using configuration#1.

    So now you can understand my logic I think. My task is to re-configure HTU and N2HET upon command from Host PC. That's all.
    For that only I scans serial port for every 10 ms, and if no command received then I will simply leave HTU and N2HET to run on previus configuration. This I clearly explain in my code Sir.

    Until new command is received, HET and HTU will not be re-initiated. They keeps on running.

    And the same N2HET Instructions are correctly working before calling StartScheduler() function. If you examine that project you will come to know this. So After Scheduler started also, same code working in the same way isn't it?

    Really it's a big challenge to find out the root cause sir. Please help me.

    Thanks and regards,
    karthikeyan.
  • I think that you first need to enable some NHET pins to prove NHET operates correctly after you restart it in the 10 ms task. I am not aware of anything which could prevent HTU from writing to the NHET RAM.

    Thanks and regards,

    Zhaohong
  • Hi Zhaohong,
    I think I found out the problem. But still I can not predict the solution.

    Ok. Problem is MPU only (I guess. If wrong please correct me!)

    I declared N2HET RAM as Device shareable and PRIV_RW_USER_RW_EXE and not the Main RAM Space.

    So what happens is HTU can not read the data from the main RAM space since it is not shareable. So that the read access of HTU from the main RAM space returns 0x0000000 as a result. But it can write the data to N2HET RAM and It writes that number to the N2HET RAM space.

    So When I examine the N2HET RAM data field it is filed with Zero again and again.

    This is what happens.

    Now We can come to the solution I think.

    I tried setting the Main RAM Space too as Device Shareable. But before RTOS code only it is running. After RTOS Code begins, I thought some modifications were done with mpu. So I have to configure MPU to declare Main RAM space as Device shareable after RTOS Code executes.

    Is that possible sir? If so how to write it?

    Thanks,

    Regards,
    Karthikeyan.K
  • Hi Zhaohong,
    I am sure sir. MPU is the only problem.
    Before RTOS code starts to work, HalcoGen generated _mpuInit() sunction is getting called in the HL_sys_startup.c file.
    So that Main RAM and N2HET RAM are configured as Device Shareable and PRIV_RW_USER_RW_EXE since I make this settings in the HalCoGen window. Because of this only, before RTOS code begins to work, everything is fine.(i.e: HTU is working, N2HET is working correctly etc.,)

    But after RTOS code begins to work, MPU Unit is reconfigured somehow by RTOS code. i.e: RTOS Code makes Main RAM and N2HET RAM as non shared memory. So that only HTU cannot read from main memory.
    This I confirmed by placeing Breakpoint before and after RTOS and examining MPU region's type and Permission.

    Unfortunately RTOS code has API to configure any memory regions as either Readable or Writeable or Readable/Writeable in either PRIV mode or USER mode or both modes.

    So I tried like calling _mpuInit() or _mpuEnable() or _mpuSetRegion and other functions defined in HL_sys_mpu.asm file (by HalCoGen). But those HalCoGen APIs doesn't work if I call after RTOS. (Yaa! Before RTOS means, they work well as per description.)

    Free-RTOS doesn't have any provision to make the memory regions as Device shareable or simply shareable as per my knowledge.
    No functions or macros from freeRTOS about region type. It has definitions for region access type only.

    So If a way to make the some memory region type as device shareable then the solution for this problem can be arrived.

    So Please help me to find any way to enable and configure MPU for device shareable or shareable property after RTOS code gets executed sir.?

    Sir. I am really new to asm writting for Cortex R5F. I did some asm coding before for PIC, ATMEL ICs. But This is the first time for Cortex core. So please help me sir.

    And really Thanks a lot for your patience with me until now.

    Thanks,

    Regards,
    Karthikeyan.K
  • Hello Karthik,

      What is the MPU setting for the L2 SRAM starting from 0x08000000? I guess you have this memory region setup as write back cache scheme. Please confirm. If this is true, please change to write through cache. Let us know if that makes a difference. My rationale is that if it is a write back cache scheme, then what the CPU writes to the L2SRAM (the data that you want HTU to read and write to the N2HET) is actually only present in the cache, not in the L2SRAM. When HTU reads from L2SRAM, the data is still zeros. HTU simply reads zeros and writes zeros to the N2HET RAM. If it is a write through cache then both the cache and the L2RAM will be coherent to each other.

     

  • Hi Zhaohong,

    I actually configure my RAM Memory starting from Base Address 0x08000000 and size of 8MB as Device Shareable and I followed the same configuration for N2HET RAM space starting from Base Address 0xFF440000 and size of 1MB.

    And I did the configuration as you said Write-thorough and shared.

    It didn't work sir.

    But Sir one happy news with another question! :)

    After I follow the following strategy, HTU can really can read the Data from Main RAM and it can update to N2HET RAM.

    I used the _cacheEnable_() and _cacheDisable_() function from HL_sys_core.h file. and I did the following experiments with WriteThrough, shared for Both Main RAM (Base Add: 0x08000000, 8MB) and N2HET (Base Add: 0xFF440000, 1MB).

    //Approach One:
    
    void main()
    {
    ConfigureHTU();
    ConfigureN2HET();
    UpdateDefaultData(); //Data Buffer is updated after many calculations by CPU without RTOS.
                         // So Default data is present in the Acutal Main RAM. 
    StartN2HET();   //Now HTU can read data from Main RAM and can write to N2HET RAM. Default Waveform is coming in the Oscilloscope.
    
    Configure_FreeRTOS();
    
    StartScheduler();
    }
    
    void _10msTask()
    {
     if(CommandFromPC)
     {
     stopN2HET();
     reConfigureHTU();
     reConfigureN2HET();
     UpdateNewData(); //Data Buffer is updated after many calculations by CPU with RTOS.
                      //I doubted that This update is happen at only to the Cache Level. Not to the Actual Main RAM.
     StartN2HET();  //Here HTU is working, N2HET is working. HTU gets request. But HTU Reads from Main RAM not from Cache.
                    //Even after I update the Data Buffer with new values, HTU is transmitting old Default data from the actual Main RAM.
                    // So I doubted that My update when RTOS is there is only happening in the Cache level.
                    //So I tried the Second Approach.
     }
     }

    //Approach Two:
    
    void main()
    {
    ConfigureHTU();
    ConfigureN2HET();
    UpdateDefaultData(); //Data Buffer is updated after many calculations by CPU without RTOS.
                         // So Default data is present in the Acutal Main RAM. 
    StartN2HET();   //Now HTU can read data from Main RAM and can write to N2HET RAM. Default Waveform is coming in the Oscilloscope.
    
    Configure_FreeRTOS();
    
    _cacheDisable_(); //Here Before starting RTOS, I disabled the cache to let see what happens. 
    StartScheduler();
    }
    
    void _10msTask()
    {
     if(CommandFromPC)
     {
     stopN2HET();
     reConfigureHTU();
     reConfigureN2HET();
     UpdateNewData(); //Data Buffer is updated after many calculations by CPU with RTOS.
                      //Surprisingly This time My Update with RTOS is happening in the Exact actual Main RAM. Not in the Cache.
     StartN2HET();  //So Here HTU is working, N2HET is working. HTU gets request. And Yes! HTU Reads from Main RAM and it Updates N2HET RAM.
                    //So now, I can See the waveform (what I expect)in the Oscilloscope.
                    //
                    //But to confirm the problem is with Cache,I tried my Third and Fourth Approach.
     }
     }

    Please sir. Keep on reading. (even though this long post, you really can come to a solution and can help me.)

    //Approach Three:
    
    void main()
    {
    _cacheEnable_(); //Here I enable the Cache.
    ConfigureHTU();
    ConfigureN2HET();
    UpdateDefaultData(); //Data Buffer is updated after many calculations by CPU without RTOS.
                         // So Default data is present in the Acutal Main RAM. 
                         //(I doubted that here Cache and Main RAM is Transparent. So I can not conclude that I writing in Main RAM or Cache.)
    StartN2HET();   //Now HTU can read data from Main RAM and can write to N2HET RAM. Default Waveform is coming in the Oscilloscope.
    
    Configure_FreeRTOS();
    
                    //Here Before starting RTOS, I didn't disabled the cache to let see what happens. 
    StartScheduler();
    }
    
    void _10msTask()
    {
     if(CommandFromPC)
     {
     stopN2HET();
     reConfigureHTU();
     reConfigureN2HET();
     UpdateNewData(); //Data Buffer is updated after many calculations by CPU with RTOS.
                      //Here RTOS is updating Cache or Main RAM. I cant predict this. But In watch window I can see that values are updated in Data Buffer Location.
                      //But RTOS is writing in Cache means, what will happen? Expecting an output!.
     StartN2HET();  //But here HTU is working, N2HET is working. HTU gets request. 
                    //But No! HTU Reads from Main RAM and it Updates same Previous Default Data values to N2HET RAM.
                    //So now, I can See only the default waveform in the Oscilloscope, even after in watch window Data Buffer field is updated with new values.
                    //
                    //So I tried Fourth Approach.
     }
     }

    //Approach Four:
    
    void main()
    {
    _cacheEnable_(); //Here I enable the Cache.
    ConfigureHTU();
    ConfigureN2HET();
    UpdateDefaultData(); //Data Buffer is updated after many calculations by CPU without RTOS.
                         // So Default data is present in the Acutal Main RAM. 
                         //(I doubted that here Cache and Main RAM is Transparent. So I can not conclude that I writing in Main RAM or Cache.)
    StartN2HET();   //Now HTU can read data from Main RAM and can write to N2HET RAM. Default Waveform is coming in the Oscilloscope.
    
    Configure_FreeRTOS();
    
    _cacheDisable_();//Here Before starting RTOS, I did disabling the cache to let see what happens. 
    StartScheduler();
    }
    
    void _10msTask()
    {
     if(CommandFromPC)
     {
     stopN2HET();
     reConfigureHTU();
     reConfigureN2HET();
     UpdateNewData(); //Data Buffer is updated with new data values after many calculations by CPU with RTOS.
                      //Here cache is disabled, So I can assume that RTOS is updating Main RAM.In watch window I can see that values are updated in Data Buffer Location.
                      //
     StartN2HET();  //And again here HTU is working, N2HET is working. HTU gets request. 
                    //And Yes! HTU Reads from Main RAM (Because Cache is disabled)and it Updates New Data values to N2HET RAM.
                    //So now, I can See waveform (what I expect)in the Oscilloscope.
                    //
                    //So what is happening sir? And Still one more Approach sir.
     }
     }

    //Approach Five:
    void main()
    {
    _cacheDisable_(); //Here I Disable the Cache.
    ConfigureHTU();
    ConfigureN2HET();
    UpdateDefaultData(); //Data Buffer is updated after many calculations by CPU without RTOS.
                         // So Default data is present in the Acutal Main RAM. (So directly to Main RAM)
                         //(Because Cache is disabled)
    StartN2HET();   //Now HTU can read data from Main RAM and can write to N2HET RAM. Default Waveform is coming in the Oscilloscope.
    
    Configure_FreeRTOS();
    
                    //Here Before starting RTOS, I didn't enabled /disabled the cache to let see what happens. 
    StartScheduler();
    }
    
    void _10msTask()
    {
     if(CommandFromPC)
     {
     stopN2HET();
     reConfigureHTU();
     reConfigureN2HET();
     UpdateNewData(); //Data Buffer is updated after many calculations by CPU with RTOS.
                      //Here RTOS is updating Main RAM. I can predict this. Because Cache is disabled. (Watch window also updates happen)
                      //
     StartN2HET();  //So here HTU is working, N2HET is working. HTU gets request. 
                    //And HTU Reads from Main RAM and it Updates New Data values to N2HET RAM.
                    //So now surprisingly, I can See the new waveform (What I expected)in the Oscilloscope.
                    //
                    //That's all sir.
     }
     }

    From the above observations I have some doubts sir.

    1. So Before RTOS code and with cache disabled, Update is happening in from Main RAM to N2HET via HTU. And After RTOS also same happening. (Everything is fine.) At the same time Before RTOS, with cache enabled, HTU working correctly and after RTOS, with disabled HTU working correctly.

    So Before RTOS, if Cache is enabled, at that time Main RAM and Cache is transparent to each other.

    But after RTOS, if Cache is enabled, at that time Main RAM and cache is not transparent to each other.

    So RTOS does something to disable the hardware mechanism that maintains the transparency / coherency between Main RAM and Cache.

    So What is that mechanism I have to do before the RTOS scheduler begins, so that Main RAM and Cache memory will be same to each other always?

    I dont know whether my prediction is correct or not. There may be some other logical reason for these happenings.

    But anyhow sir, these are the things happening. So please consider these results and help me sir. Thanks.

    This is my question now sir. I think we nearly come to the problem.

    Thanks a lot for your support sir. (I really learned a lot in these exercises.)


    Expecting your guidance.

    Thanks,

    Regards,

    Karthikeyan.K

  • I believe that the issue is still with MPU settings. The location for the HTU to read should cacheable and write through. I believe that Free RTOS change it to writeback. You can find the MPU setting in the following steps.

    (1) Set break point in the function you set up HTU and run to the breakpoint.
    (2) Write down the address HTU is supposedly to read.
    (3) In CCS register view window select CP15.
    (4) Write the MPU region number into CP15_MPU_REGION_NUMBER register and you will see the start address, region size, and settings. If you do not know the region number, you can start with region 0 and move up till you find the correct one.

    Thanks and regards,

    Zhaohong
  • Hi Zhaohong,

    Yes Sir. Free-RTOS do modification in MPU Settings.

    It is in the line no:194 of os_portasm.asm file.

    In that line, vPortStartFirstTask is asm function which calls the portRESTORE_CONTEXT macro. It is where the MPU settings is being modified by RTOS.

    In the below Image, MPU settings is given before and after free-RTOS.

    I thought that the portRESTORE_CONTEXT macro code in the os_portasm.asm file is related to context switching and free-RTOS calls this macro function again and again before entering to any task from other task. So I am not sure whether Modifying this code will after the behavior of RTOS or not. So I didn't do any modification in this code. ( and I dont know how since it is in assembly. I know the MCR and MSR instructions and how to use them. But I dont know the logic, free-RTOS used here.).

    Because of these values written in the MPU Register, Yes sir, Main RAM is changed to write-Back from write through.

    So I did modifying the MPU Registers in the Watch Window itself to change the Main RAM Space as write through, but as soon as I click on the run button, Program comes to the prefetchentry.

    So I am not aware of what is going on in this portRESTORE_CONTEXT. Please explain me how can I make my Main RAM to be updated by the free-RTOS so that HTU can read the actual data I expect to update the N2HET RAM.

    Thanks in advance,

    Regards,

    Karthikeyan.K

  • Hi Zhaohong,

    Guess what!

    I did configuring Main RAM as Write thorough shared in the free-RTOS code itself. And My HTU can read the new data (which is updated by free-RTOS) from main RAM, so that my output waveform is exactly like what I expect.

    In the file os_port.c, vPortStoreTaskMPUSettings() is the function which prepared the MPU Configuration data in a *xMPUSettings array pointer, when each task I create.

    And later, this updated *xMPUSettings pointer which holds the required MPU Settings is used in the  portRESTORE_CONTEXT macro.

    And in free-RTOS code this function configures Main RAM memory as Write-Back Non-Shared for every Tasks I created.

    So What I did is, just to change

    xMPUSettings->xRegion[0].ulRegionAttribute   = portMPU_PRIV_RW_USER_RW_EXEC | portMPU_NORMAL_OIWBWA_NONSHARED;
    
    xMPUSettings->xRegion[1].ulRegionAttribute   = portMPU_PRIV_RW_USER_NA_NOEXEC | portMPU_NORMAL_OIWBWA_NONSHARED;
    
    xMPUSettings->xRegion[0].ulRegionAttribute   = portMPU_REGION_READ_WRITE | portMPU_NORMAL_OIWBWA_NONSHARED;
    
    //I have modified the above lines with the following lines in void vPortStoreTaskMPUSettings() function in the os_port.c file
    
    xMPUSettings->xRegion[0].ulRegionAttribute   = portMPU_PRIV_RW_USER_RW_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED/*portMPU_NORMAL_OIWBWA_NONSHARED*/;
    
    xMPUSettings->xRegion[1].ulRegionAttribute   = portMPU_PRIV_RW_USER_RW_EXEC/*portMPU_PRIV_RW_USER_NA_NOEXEC*/ | portMPU_NORMAL_OIWTNOWA_SHARED/*portMPU_NORMAL_OIWBWA_NONSHARED*/;
    
    xMPUSettings->xRegion[0].ulRegionAttribute   = portMPU_REGION_READ_WRITE | portMPU_NORMAL_OIWTNOWA_SHARED/*portMPU_NORMAL_OIWBWA_NONSHARED*/;

    After I make these changes, Free-RTOS now can configure main RAM as Write-through shared memory, so that Cache and Main RAM are getting updated simultaneously.

    Thanks for your support until now sir. I have learned lot of things from this post and exercise. Surely this entire post will help newbies. Thank you so much sir.

    You have really spent good time with me. Thanks for that.

    Regards,

    Karthikeyan.K