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.

ti-sdk-am37x-evm-05.02.00.00 on CCSv5

Hi Experts,

I am using Code Composer V5 (CCSv5) and Linux tool chain ti-sdk-am37x-evm-05.02 and I am new to this. I was trying to setup interrupt using interrupt.h in Linux kernel. But I found /linux/interrupt.h is missing from the /user/include/linux directory in Code Composer. By further debugging, I found that under ti-sdkxxx05.02xxxx/psp/linux-2.6.37xxxxsdk/linux, there is interrupt.h. But under ti-sdkxxx05.02xxxx/linux-devkit/arm-arago-linux-xxxx/usr/include, there is no interrupt.h although most other files are the same. We know interrupt.h is part of linux kernel.

 If I manually include psp linux directory then there is compiling errors due to many  .h files are the same.

Could anyone tell me why the tool chain not including the whole /linux directory for .h include under /usr/include in code composer? How could I include the whole Linux Kernel to compile my applications in CCSv5?

Here is what I did in Code Composer:

1. File->new->project-> C project -> Next

2. Project type: executable, Toolchain: Linux GCC

After I entered the name and created the project. I check in the usr/include/linux directory, most of the .h files under /linux/*.h are there but missing some such as interrupt.h. How could I use interrupt.h? Thanks.

Frank

  • If you're building the Linux kernel then the "include path" specified with "-I" should not have "/usr/include" nor any "arm-arago-linux-xxxx/usr/include" directories.  All Linux kernel "include files" come from the Linux source tree itself (mostly from the <linux-source>/include directory).  "/usr/include" contains user-level files, as does "arm-arago-linux-xxx/usr/include", and those user-level files should never be referenced for a kernel build.

    However, I wouldn't use a CCS project to build the Linux kernel.  The Linux kernel contains its own build system based on gmake, and is very easy to invoke, taking care of its own "include" directory specifications.  You do need a Linux shell, though.

    Regards,

    - Rob

     

  • Hi Rob,

    Thank you for the quick response. I will try to figure out the include path issue based on your comments. If I build Linux Kernel by gmake and through Linux shell. How do I load to my target AM37x EVM board through CCSv5? Do I just need to load the bin file using gdbserver? Also if I build through Linux shell, then is CCSv5 still useful for me? How could I use its nice GUI debugger if I build through Linux Shell? Thanks again.

    Frank.

  • The Linux kernel needs to be loaded by u-boot, which is *the* standard booting tool.  Typically, a ROM-based bootloader will load a 1st-stage bootloader named "UBL".  UBL will then load and run u-boot, and u-boot will load and run the Linux kernel.  I realize this sounds like perhaps too many stages (I can hear you ask "why not have the RBL (ROM Boot Loader) just load/run u-boot?", I dunno), but it's the standard way today.  u-boot will take care of setting up HW as it needs to be setup for the Linux kernel.

    The Linux kernel can be loaded by u-boot in many different ways.  It can reside in NAND or on an MMC card, it can be TFTP-loaded over ethernet, plus a few other methods.  A good deal of the Linux configuration is handled by u-boot, effectively allowing dynamic configuration of Linux by way of the u-boot 'bootargs' variable.

    As for CCS v5, it's quite possible to attach to an already-running binary and inform CCS of the location of the binary image and the source code used to build that image.  A CCS project would normally provide this sort of information to CCS, but lacking a CCS project it should be possible to manually tell CCS all the things that the project otherwise would.  I'm speaking in generalities here because I'm not the right person to give you the details, especially since I've had difficulty getting CCS v4 to be able to debug a Linux kernel.  I believe CCS v5 is much better suited than CCS v4 for this task, but unfortunately you will need to get that information from someone/somewhere other than me.  There is a CCS Forum, plus wiki sites and docs that describe "Linux-aware debugging with CCS".

    Regards,

    - Rob

     

  • Hi Rob,

    I quickly checked what you said about the /usr/include part. The issue is my AM37x EVM board came with a tool chain ti-sdk-arm-arago-linux-05.02xxx. The user guide let me point the library to the library in the tool chain directory.  When I start an executable project and select tool chain Linux gcc, the CCSv5 is automatically putting arm-arago-linux-xxx/usr/include into my usr/include and I could not change it. But this include directory only holds partially the linux kernel. I got your second email. I will try not to use the tool chain but directly make appication from the PSP linux kernel package. Thanks.

    Frank

  • CCS projects are geared towards providing support for "user" applications, and a user application would indeed need to be pointed to the arm-arago-linux-xxx/usr/include directory for your cross-compile.  FYI, the /usr/include directory would not be used in your cross-compile, as that directory is only for a "native" compile for a user application that runs on your host system (not on your EVM board).

    Bigtree said:
    But this include directory only holds partially the linux kernel.

    While it  may appear that a usr/include directory (either /usr/include or arago/usr/include) contains files suitable for building the Linux kernel, with the same filenames and perhaps even the same file content, those files are not for building the Linux kernel.  As I said previously, the Linux kernel source tree contains *all* the #include files needed by the kernel source.

    Bigtree said:
    The issue is my AM37x EVM board came with a tool chain ti-sdk-arm-arago-linux-05.02xxx.

    It's a bit confusing.  That tool chain is indeed used for building the Linux kernel, but it is also used to build user applications.  The arago/usr/include and any libraries in the arago toolchain are for *only* user applications.  The Linux kernel does not need any libraries from the toolchain, nor any #include files.

    Regards,

    - Rob

     

  • Hi Rob,

    Now I feel more clear now by your answer. What I need is to setup an interrupt and I am trying to call request_irq() in /linux/interrupt.h. I think this should be in my application code, right? So I am trying to build application not kernel. I guess I confused you on this part.

    When I put in  #include </linux/interrupt.h> in my application code, CCS could not find interrupt.h. I found out usr/include does not have interrupt.h there. So that is why I am asking why it is not there. But I found this file under another directory under the toolchain: pspxxxxx/include/linux. So my question is why the toolchain does not have the required .h files under /usr/include? How to fix this?

    Thanks

    Frank

  •  

    Robert Tivy said:
    [CCS projects are geared towards providing support for "user" applications, and a user application would indeed need to be pointed to the arm-arago-linux-xxx/usr/include directory for your cross-compile.  FYI, the /usr/include directory would not be used in your cross-compile, as that directory is only for a "native" compile for a user application that runs on your host system (not on your EVM board).

    But this include directory only holds partially the linux kernel.

    [/quote]

    And perhaps the final missing bit is that <linux/interrupt.h> is inappropriate for user space applications.  I don't know off-hand if CCS has a mode to help with writing kernel modules.

  • Bigtree said:
    What I need is to setup an interrupt and I am trying to call request_irq() in /linux/interrupt.h. I think this should be in my application code, right? So I am trying to build application not kernel. I guess I confused you on this part.

    Ahhh, there's the stumbling block.  request_irq() is *not* for application code, it is purely for kernel code.  In fact, application code cannot affect interrupts at all.

    Any API declared in a header file from the Linux kernel source is for kernel use only.  It's possible that a kernel API matches an application-level API, but they are completely separate.

    So, there's nothing to fix here, interrupt.h will *not* be present in application-level "include" directories.

    It sounds to me like you need a kernel device driver to satisfy your interrupt needs.  You might want to look into UIO support present in Linux.  A description is here: http://lwn.net/Articles/232575/.  If that doesn't suit your needs, you can write a small device driver that services interrupt-related requests from user-space (sounds like a bit much for a newbie, though).

    Regards,

    - Rob

     

  • Rob,

    Oh, I see. I am really a newbie to linux. What I am trying to do is to tie a interrupt handler routine to an irq number which is from an interrupt line in hardware. I need to invoke this interrupt handler routine once the specific interrupt happens. Should I do this in the application domain or in the kernel domain? What should I do or what document to check? I will read your suggested document in your last post. Thanks a lot. You are very helpful.

    Best regards,

    Frank

     

  • You're gonna need a bigger boat!  :)  ("Jaws" reference)

    In other words, it's not easy to do what you describe.  I would suggest at this point that you're going to need help beyond what is typically provided in support forums.

    Interrupts are *always* first handled by kernel code  If application code needs "energy" based on an interrupt, the kernel will have to supply it with that "energy".  "Device drivers" are the kernel code entities that handle interrupts related to the device.  There are many ways in which a device driver can deliver the synchronization needed by the application.  Typically an interrupt signals that a device has just finished with some data, and an application would make a fread()/fwrite() call to the device driver that would return to the application when the data is ready  (or rendered).  The ioctl() device driver API can handle "out-of-band" control/synchronization that isn't easily covered by a read or write operation.

    Anyways, take a look at the UIO article I pointed you to.  I believe that it is the simplest path to achieving what you need here.

    Have you looked into any possible existing Linux device driver that is responsible for handling the interrupt in question here?  It's possible that one exists, and has a nice, easy interface for a user application to be notified when its interrupt occurs.

    Regards,

    - Rob

     

  • Hi Tom,

    Thank you for the answer.  What I am trying to do is to tie a interrupt handler routine to an irq number which is from an interrupt line in hardware. I need to invoke this interrupt handler routine once the specific interrupt happens. Should I do this in the application domain or in the kernel domain? What should I do or what document to check? Thanks.

    Best regards,

    Chenshu

  • Hi Rob,

    I will read the document you told me and get back to you with more questions. Just curious why this is so difficult with Linux. Basically, request_irq() is doing exactly what I want connecting an interrupt handler routine with a irq number. I will read the document first to save you some time. :). Thanks a lot and have a good evening or afternoon.

    Best regards,

    Frank

  • Bigtree said:
    Just curious why this is so difficult with Linux.

    It's difficult in Linux because Linux is a solid, open, multi-user environment that needs to protect itself from potentially buggy or malicious applications.  I'm not implying that your code will be buggy or malicious, just that your application runs in the same space and therefore is under the same constraints.  A good Linux system cannot be crashed or compromised by applications, no matter how buggy or how hard it tries.

    Device driver code (or other kernel code that you might add to the kernel, after all it's your kernel) certainly can be bad and crash the whole system, but the system integrator is in control and completely responsible for kernel code, and once a system is "locked down" only root priviledges can do things that are "bad".  If Linux allowed user applications to control interrupts then that application could potentially take the whole system down.

    Bigtree said:
    Basically, request_irq() is doing exactly what I want connecting an interrupt handler routine with a irq number.

    The code in request_irq() would not work from the application level.  The kernel runs with special privileges that allow it to do the operations in request_irq().  Also, the code that you register with request_irq() runs in kernel context, and allowing application code to run in kernel context is a BAD IDEA for the overall operation of the Linux system.

    Regards,

    - Rob

  • Hi Rob,

    Thanks for the detail explanation. I know now I should do the work at user space not at the kernel. I went through the document you suggested. But  <linux/uio_driver.h> is still at kernel space, isn't it? I could not find it in /usr/include and it is under kernel /linux/include just as interrupt.h. So I still could not use these functions in  <linux/uio_driver.h> in application code, right? Then what do I do in application code and how to start? Thanks.

    Frank

  • Bigtree said:
    So I still could not use these functions in  <linux/uio_driver.h> in application code, right? Then what do I do in application code and how to start?

    That's right, applications can't call any function declared in a header file from the kernel source tree.

    I'm afraid that my ability to assist you here is declining, since I'm really not familiar with UIO.  My initial involvement in this thread was to steer you away from the wrong approach and to point you in the right direction.  I will monitor this thread and help when I can, but as I said, I don't know UIO.

    Regards,

    - Rob

     

  • Hi Rob,

    Hope you had a good weekend. I understand the direction now and I will try to proceed. I don't know if you are familiar with ARM AM3707 and its supporting software package. I posted some questions in those tags and no one answers me. Basically, I do not see any driver libraries in the Linux tool chain provided to me. For example, I want to setup DMA. There are 30+ hardware registers to set in the hardware spec but I do not see any driver functions to set them and no #defines for these registers. If you could not help, could you point to me the right place to post my questions? Thanks.

    Frank.

  • The Linux tool chain would probably not have library support for DMA.  Any device support would be contained in the Linux kernel, in the form of a device driver, but again there would not be any help there for generic DMA support.  DMAs are used internally in device drivers, for purposes related to IO with the device supported by the driver.

    So, what is it that you want to DMA to/from?

    TI does offer some DMA-related support in the form of TI's Framework Components (FC) package.  It has an interface for accessing the EDMA module in another TI package named Linux Utils.  The EDMA module has a user interface for communicating with the EDMAK Linux device driver.  This interface is mostly for allocating a DMA channel and returning its address in user address space.  There are no EDMA module APIs for actually operating the EDMA channel, but FC has a higher-level interface for operating the DMA channel. FC offers abstract interfaces designed for use by XDAIS algorithms, so it's not a simple interface.

    Take a look here for one-stop-shopping for info: http://www.ti.com/tool/tmdmfp.  There are also TI wiki pages with tips/help for these components.

    Linux is not friendly to allowing user access to HW devices, as you're learning.

    Regards,

    - Rob