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.

Hardware drivers on beaglebone using sysbios

Other Parts Discussed in Thread: SYSBIOS

Hi,

Why does the following line (from StarterwarePackage) generate an exception when run in a the static_BeagleBone_CortexA project fro SYSbios crash the system when executed after main(), i.e

void main()
{
    GPIO1Pin23PinMuxSetup();   /*This causes exception*/
    Swi_post(swi0);
    Swi_post(swi1);
    Clock_start(clk1);
    //GPIO1ModuleClkConfig();
    BIOS_start(); 
}.,

however when moved into the startup code i.e. the code that runs before main, it executes correclty. Does Sysbios maybe prevent a user from accessing hardware registers directly? If so, what is the correct way to access hardware directly from Sysbios assuming that I would want to write my own hardware drivers?

I wanted to get a simple LED flasher running, but ran into this problem when enabling GPIO1 clocks as seen above

Thanks

Graeme

  • Hi Graeme,

    SYS/BIOS will automatically enable MMU on A8 platform only for the memories defined in platform package. 
    So If A8 wants to access the peripheral registers, then the exception would be expected.
    You can allow A8 to access peripheral registers via MMU configurations.
    The following is the snap shot from Cdoc (ti.sysbios.family.arm.a8.Mmu):

    ===================
    The following example demonstrates how to add a peripheral's address to the MMU table so that it can be accessed by code at runtime:
        var Cache = xdc.useModule('ti.sysbios.family.arm.a8.Cache'); 
        var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu'); 
     
        // Enable the cache 
        Cache.enableCache = true; 
     
        // Enable the MMU (Required for L1/L2 data caching) 
        Mmu.enableMMU = true; 
     
        // Force peripheral section to be NON cacheable 
        var peripheralAttrs = { 
            type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor 
            bufferable : false,                // bufferable 
            cacheable  : false,                // cacheable 
            shareable  : false,                // shareable 
            noexecute  : true,                 // not executable 
        }; 
        
        // Define the base address of the 1 Meg page  
        // the peripheral resides in. 
        var peripheralBaseAddr = 0xa0400000; 
     
        // Configure the corresponding MMU page descriptor accordingly 
        Mmu.setFirstLevelDescMeta(peripheralBaseAddr,  
                                  peripheralBaseAddr,  
                                  peripheralAttrs); 
    

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

    You would be able to access registers with Mmu.setFirstLevelDescMeta configurations.

    Best Regards,
    Kawada 

  • Hi Kawada,

    Thanks you for your response. I will give that I try this evening (although I suspect I might have some reading to do on this :))

    Kind regards

    Graeme

  • Hi,

    I have tried the following in the .cfg file:

    var Cache = xdc.useModule('ti.sysbios.family.arm.a8.Cache'); 
        var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu'); 
     
        // Enable the cache 
        Cache.enableCache = true; 
     
        // Enable the MMU (Required for L1/L2 data caching) 
        Mmu.enableMMU = true; 
     
        // Force peripheral section to be NON cacheable 
        var peripheralAttrs = { 
            type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor 
            bufferable : false,                // bufferable 
            cacheable  : false,                // cacheable 
            shareable  : false,                // shareable 
            noexecute  : true,                 // not executable 
        }; 
        
        // Define the base address of the 1 Meg page  
        // the peripheral resides in. 
        var peripheralBaseAddr = 0x4804C000;   /*Physical address of the GPIO1 module*/ 
     
        // Configure the corresponding MMU page descriptor accordingly 
        Mmu.setFirstLevelDescMeta(peripheralBaseAddr,  
                                  peripheralBaseAddr,  
                                  peripheralAttrs); 

    and then tried
    Void main()
    {
        Task_create(task1Fxn, NULL, NULL);

        GPIO1ModuleClkConfig();

        System_printf("Memory example started.\n");

        BIOS_start();
    }
    which still causes crash when getting to the GPIO1ModuleClkConfig() function call. GPIO1ModuleClkConfig()
    makes direct calls to the GPIO1 physical registers.

    Disabling MMU in the .cfg file causes the above code to work and I can read the GPIO1 registers in the
    debugger register view.

    Clealy I am still missing something, maybe the way I write to the registers? Am I supposed to use
     the physical address of the register,(although it seems from th eabove that the physical and virtual
     addresses are the same). Maybe an API I should use to talk to the registers?

    Any help would be appreciated
    Kind regards
    Graeme





  • Hi Graeme,

    > var peripheralBaseAddr = 0x4804C000;  

    MMU would require 1Mbytes alignment because MMU regards upper 12bits phy address to make section descriptor and upper 12bits virt address to make a index for address translation table holding the descriptor.
    Could you please try 1Mbytes aligned address ?

    Once MMU configuration is completed, A8 should be able to access memories and registers via phy(==virt) address.
    No special API will be required to access them.

    Best Regards,
    Kawada 

  • Hi  Kawada,

    I have tried the 1M alignment as you suggested but still the behavior is the same.

    var peripheralBaseAddr = 0x48000000 (0x4804C000 lies within the 1M address)

    Below is my .cfg file that I am using.

    Also, GPIO1 is listed as a L4 peripheral. With the cacheing they mention it is for L1,L2. Not sure if this is maybe a clue

    Thanks again for your help with this

    Kind regards

    Graeme

    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory')
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Idle = xdc.useModule('ti.sysbios.knl.Idle');
    var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu');
    var Cache = xdc.useModule('ti.sysbios.family.arm.a8.Cache');
    // Enable the cache
    Cache.enableCache = true;

    // Enable the MMU (Required for L1/L2 data caching)
    Mmu.enableMMU = true;

    // Force peripheral section to be NON cacheable
    var peripheralAttrs = {
        type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor
        bufferable : false, // bufferable
        cacheable : false, // cacheable
        shareable : false, // shareable
        noexecute : true, // not executable
    };

    // Define the base address of the 1 Meg page
    // the peripheral resides in.
    var peripheralBaseAddr = 0x48000000;

    // Configure the corresponding MMU page descriptor accordingly
    Mmu.setFirstLevelDescMeta(peripheralBaseAddr, peripheralBaseAddr, peripheralAttrs);

    /*
     * Program.argSize sets the size of the .args section.
     * The examples don't use command line args so argSize is set to 0.
     */
    Program.argSize = 0x0;

    /*
     * Uncomment this line to globally disable Asserts.
     * All modules inherit the default from the 'Defaults' module.  You
     * can override these defaults on a per-module basis using Module.common$.
     * Disabling Asserts will save code space and improve runtime performance.
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
     */

    /*
     * Uncomment this line to keep module names from being loaded on the target.
     * The module name strings are placed in the .const section. Setting this
     * parameter to false will save space in the .const section.  Error and
     * Assert messages will contain an "unknown module" prefix instead
     * of the actual module name.
    Defaults.common$.namedModule = false;
     */

    /*
     * Minimize exit handler array in System.  The System module includes
     * an array of functions that are registered with System_atexit() to be
     * called by System_exit().
     */
    System.maxAtexitHandlers = 4;       

    /*
     * Uncomment this line to disable the Error print function.  
     * We lose error information when this is disabled since the errors are
     * not printed.  Disabling the raiseHook will save some code space if
     * your app is not using System_printf() since the Error_print() function
     * calls System_printf().
    Error.raiseHook = null;
     */

    /*
     * Uncomment this line to keep Error, Assert, and Log strings from being
     * loaded on the target.  These strings are placed in the .const section.
     * Setting this parameter to false will save space in the .const section.
     * Error, Assert and Log message will print raw ids and args instead of
     * a formatted message.
    Text.isLoaded = false;
     */

    /*
     * Uncomment this line to disable the output of characters by SysMin
     * when the program exits.  SysMin writes characters to a circular buffer.
     * This buffer can be viewed using the SysMin Output view in ROV.
    SysMin.flushAtExit = false;
     */

    /*
     * The BIOS module will create the default heap for the system.
     * Specify the size of this default heap.
     */
    BIOS.heapSize = 0x2000;

    /*
     * Build a custom SYS/BIOS library from sources.
     */
    BIOS.libType = BIOS.LibType_Custom;

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x1000;

    /* Circular buffer size for System_printf() */
    SysMin.bufSize = 0x400;

    /*
     * Create and install logger for the whole system
     */
    var loggerBufParams = new LoggerBuf.Params();
    loggerBufParams.numEntries = 32;
    var logger0 = LoggerBuf.create(loggerBufParams);
    Defaults.common$.logger = logger0;
    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    System.SupportProxy = SysMin;

    /* Create two heaps to be used by two separate tasks for alloc and free. */
    var heapBufParams = new HeapBuf.Params;
    heapBufParams.blockSize = 32;
    heapBufParams.numBlocks = 2;
    heapBufParams.align = 8;
    Program.global.task0Heap = HeapBuf.create(heapBufParams);

    var heapMemParams2 = new HeapMem.Params;
    heapMemParams2.size = 512;
    heapMemParams2.align = 8;
    Program.global.task1Heap = HeapMem.create(heapMemParams2);

    /* Create the static task */
    var taskParams = new Task.Params;
    var task0 = Task.create('&task0Fxn', taskParams);

    /* Add idle function */
    Idle.addFunc('&idl0Fxn');

    Mmu.defaultAttrs.type = Mmu.FirstLevelDesc_SECTION;
    Mmu.cachePlatformMemory = false;

    
    



  • Hi Graeme,

    You mentioned reading GPIO register worked without MMU... I'm wondering if GPIO1 is really being enabled in GPIO1ModuleClkConfig(). In PRCM point of view, CM_PER_GPIO1_CLKCTRL register should be setup to enable GPIO1 clock but this register is in CM_PER module started from 0x44E0_0000. And this is not in the range you configured. Please check what HW registers are configured in GPIO1ModuleClkConfig() and allow the register accessing if any (by the same configuration scheme) .

    Best Regards,
    Kawada 

     

  • Hi Kawada,

    Thanks, you are correct.

    0x44E00000 is being acesssed in the frst line of  GPIO1ModuleClkConfig(). Didn't think to check that.

    Will enable that section this evening and will  test.

    Thanks again

    Kind regards

    Graeme

  • Good to know that. Good luck !

  • Hi Kawada,

    Tested and it works!

    thanks again for your help

    Kind regards

    Graeme

  • hi, can you post the complete example code and and cfg file, i´m trying with bbb and doesn´t work.

    thanks.