Project 2: Dynamically changing frequency on the Ipaq

 
 

Due Date: 31st Mar 2003

 
 
Problem Statement To write a kernel module that exports API to query, increase and decrease the CPU frequency of the Ipaq, for Linux  
   
Details  
  API to be exported

Get_Current_Frequency() Will return the current frequency of the core
Set_Frequency() Will set up the operating frequency to desired value(read Developers Manual section 8.2 for valid values)
 

 
         

 

 
    Guidelines The following sequence of steps can be followed to successfully accomplish the above objective:
  1. Look at the Linux kernel code, to find out how frequency scaling is implemented in the linux kernel.
  2. Read the SA-1110 developers manual (references 1,2,3) etc to find out what registers etc need to be written to in order to change the operating frequency. A simple search on google will tell you that Linux has a nice framework for CPU Scaling, and lots of discussions/text is available, which should give you enough pointers on what all needs to be done.
  3. Write your code in the form of a loadable kernel module, so that after you write your module, we can insert it into kernel space. A simple example of a kernel module is given here. The files in this example are:
           load A script that calls insmod to load the module into kernel space
           unload A script that calls rmmod, to unload the module
          module.c Note the folloqing functions - init_module() This basically registers the module in such a way that when we open our char device, the open, close and any ioctl system calls to this device are redirected to the functions that we have written in this code. This is essentially registering a callback. do_ioctl() esentially, by passing different parameters to this ioctl call, you should be able to achieve the effect of (i)querying current speed (ii)setting a new speed
  4. You might want to look at this guide for a brief intro to writing kernel modules.
 
      Summary To write a kernel module, which will register itself, and set up a char device on /dev. By doing an ioctl on this device, user should be able to get/request CPU speed.  
           
           
References  
     
  1. A brief guide on writing assembly modules for the ARM
  2. Intel® SA-1110 processor Product Brief
  3. Intel® SA-1110 Microprocessor Brief Datasheet
  4. Intel® SA-1110 Microprocessor Developer's Manual (Note Sections 8.2 and 10.3)
  5. The ARM Calling Sequence Specification (Also look at the navigation panel on left - a few useful links should show up)
  6. VirtualAlloc()
  7. VirtualFree()
  8. A small note that I put together from some articles on the web talking about what needs to be done to achieve dynamic frequency scaling
  9. Code from the Linux kernel
  10. The Linux Kernel Module Programming Guide