S3C2440 Bare Metal Practice 1 Creating an Initial Project

Publisher:omicron25Latest update time:2019-04-26 Source: eefocusKeywords:S3C2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

I haven't played with S3C2440 for several years. From single-chip microcomputers to embedded systems, I remember that this was one of the earliest chips I used when I got started with embedded systems.


S3C2440 has MMU and can run operating systems such as WinCE/Linux. It is suitable for embedded development. It always feels a bit wasteful to do single-chip microcomputer development, but it should be fine if you just want to play around.


Recently, I want to use S3C2440 as a microcontroller in my spare time.


Let’s stop talking nonsense and get straight to the point.


The first step is of course to create the initial project.


Since it is a bare metal practice, if you want to play with some features, it seems that assembly is indispensable. Of course, MDK has better support for ARM9 assembly. IAR's assembly syntax is slightly different from ARM's official one, so forget it.


The syntax of gcc is similar to that of ARM official, but the quality of the compiled code is not as good as MDK. Here we choose MDK5.1


The hello world of the microcontroller always starts with LED. I am no exception here. I start with Led, or GPIO.


Open MDK5. If there is already a project opened when MDK is started, close the currently opened project first.


1. Create a new project and you will be asked to select the chip model. Enter S3C2440A directly in the search box and confirm.


MDK will automatically add the S3C2440.s startup file, which is written in ARM assembly language. For those who are not familiar with assembly language, it may be a little difficult to understand.


You don't need to look at it here, just use it to create a complete project, otherwise the compilation and linking will not pass.


If you need to add some interesting features later, you can return to this file to modify it, or rewrite it directly as needed.


2. Settings


1) Target page,


    IRAM1 Start 0x40000000 Size 0x1000


    Remove Use Cross-Module Optimization. It is recommended not to enable optimization in the early stages of the code.


    Remove Use mirolib


2) Output page


     Check Create HEX File


3) User page


     Check Run #1


    Fill in fromelf.exe --bin -o @p.bin @p.axf at the end


 4) The following Debug and Unitiily pages are modified according to the simulator type, and other pages do not need to be modified by default.


3. Of course, the initial project should complete the main function first, so create a main.c file and write a basic main function.


int main(void)

{

    unsigned int a = 0;

    unsigned int b = 1;

    while(1){

        a = b ;

        b = a;

    }

    return 1;

}

After writing, of course the first thing I thought of was to compile it. I didn't expect that all kinds of strange errors would appear after compiling.

After looking at the information carefully, I found that it was not a compilation error, but an error in the linking stage.


Well, I guess there is something wrong with the scatter loading settings.




4. Write a scatter loading script.


Click options for target, which is the settings button in the toolbar, go to the Linker column, and remove Use Memory Layout from Target Dialog, so that you can use


Scatter File, that is, the scattered loading script method. My personal habit is to use the scattered loading script. The one checked above is a simple setting method, which can only support relatively simple scattered loading requirements.


It cannot do complex scatter loading, and the scatter loading script can handle both simple and complex ones.




After unchecking the box, the system will default to giving the scattered loading script name with the same project name in the same directory as the previous project file. Click Edit at the back.


Overwrite it with the following code, save it, and recompile everything to pass.




ER_ROM1 0x40000000

{

    ER_ROM1 0x40000000

    {

        *.o (RESET, +First)

        *(InRoot$$Sections)

        * (+RO)

    }     

    

    RW_RAM1 0x40000800

    {

        ;S3C2440.o (MyStacks)

        .ANY (+RW,+ZI) ; * (+RO)    

    }  

 

    HEAP +0 UNINIT

    {

        S3C2440.o (Heap)

    }

 

    STACK 0x40001000 UNINIT

    {

        S3C2440.o (STACK)

    }

}


Is it OK here? I don’t know, let’s simulate it first.








2015-2-9


5. Simulation test


After a simulation, I realized that there was a big problem. In the ARM system, the system stack is full and decremental, so the top of the stack cannot exceed 0x40001000, and the bottom of the stack cannot exceed


I calculated the stack capacity, which should be 0x488. I looked at the map file and found that the top of the stack was 0x40001488, so I need to check the script.


ER_ROM1 0x40000000

{

    ER_ROM1 0x40000000

    {

        *.o (RESET, +First)

*(InRoot$$Sections)

        * (+RO)

    }     

 

    RW_RAM1 0x40000800

    {

        ;S3C2440.o (MyStacks)

        .ANY (+RW,+ZI) ; * (+RO)

    }  

 

    HEAP +0 UNINIT

    {

        S3C2440.o (Heap)

    }

 

STACK 0x40000B00 UNINIT

    {

        S3C2440.o (STACK)

    }

}


After compiling, the simulation can enter the main function, but it always restarts. In addition, it is found that the CPU is running the program that was previously burned into the first 4KB of nandflash, which means that the code seen during simulation is actually

The steppingstone code is running during simulation, and the location of the first instruction is 0x00000000, not 0x40000000. It seems that the simulation period did not let the PC point to 0x40000000, so the steppingstone code is running during simulation.


Add the following code to edit initization file in debug column. Here we just want to set PC to 0x40000000. Remove the initialization clock, RAM, etc., which will be added later.


Since it is a bare metal practice, we should try to let the code do the functions we need. It is meaningless if the script does the initialization work for us. Of course, there is no way to initialize the PC, so we can only set it through the script. After all, now


The first 4KB of code in nandflash is not our own code and cannot be controlled.


FUNC void SetupForStart (void) {

 

//

 PC = 0x40000000; //0x30000000

}

 

 

FUNC void Init (void) {

 

    // Clock Setup 

                                        // FCLK = 300 MHz, HCLK = 100 MHz, PCLK = 50 MHz

// _WDWORD(0x4C000000, 0x0FFF0FFF); // LOCKTIME

// _WDWORD(0x4C000014, 0x0000000F); // CLKDIVN

// _WDWORD(0x4C000004, 0x00043011); // MPLLCON

// _WDWORD(0x4C000008, 0x00038021); // UPLLCON

// _WDWORD(0x4C00000C, 0x001FFFF0); // CLKCON

 

}

 

 

// Reset chip with watchdog, because nRST line is routed on hardware in a way 

// that it can not be pulled low with ULINK

 

//_WDWORD(0x40000000, 0xEAFFFFFE); // Load RAM addr 0 with branch to itself

CPSR = 0x000000D3; // Disable interrupts

PC = 0x40000000; //0x30000000 // Position PC to start of RAM

//_WDWORD(0x53000000, 0x00000021); // Enable Watchdog

//g, 0 // Wait for Watchdog to reset chip

 

//Init(); // Initialize memory

LOAD project.axf INCREMENTAL // Download program

SetupForStart(); // Setup for Running


Simulate again, no problem.

Well, at this point, the first project of the S3C2440 bare metal is almost completed.


After writing the peripheral header file according to CMSIS, operate the LED.




This is done with the help of the assembly startup code provided by MKD. Those who understand assembly can write an assembly startup by themselves. If you don’t understand it, it’s okay. You can write it according to the ARM7 assembly startup code, such as the LPC213x/214x series assembly startup code.


Recommend a link to interpret the S3C2440 assembly startup code provided by MDK:


http://www.oschina.net/question/565065_115207

Keywords:S3C2440 Reference address:S3C2440 Bare Metal Practice 1 Creating an Initial Project

Previous article:S3C2440 Development Board Bare Metal Program Series 07—NAND FLASH Memory
Next article:s3c2440 bare metal system clock and timer settings

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号