The basic rules of low-level driver writing

1 Write independent drivers for each hardware object

Each object corresponds to a header file and source file. If the object is an external object, a macro should be used in the header file to define which pin the object is connected to. The header file only declares the function function for external call, that is, other people only Look at the header file function declaration to know how to use this object without having to look at the source file to read the code. The general function naming rules are: object functions, such as initializing the Charger, the function name can be ChargerInit.
If a function is only called internally by the function of the object, the function is declared and implemented in the source file, not in the header file, and declared as a static function, because the function declared as static can only be used for the source file that defines the function Use, other source files can't see this function. If a global variable is only used by a certain module, you can define this global variable as static, so that this variable can only be used in the source file where it is defined, and other source files cannot see this variable, so there will be no naming conflict.

2 The package must be complete and cannot be crossed between packages

The module function realizes the function to be realized by this module. The module cannot call each other. If you want to call, it will be handled by the high-end. For example, the serial port cannot be called in the Flash subroutine. Of course, it is an exception when testing the Flash subroutine. When finished, you must delete the calling serial subroutine code. At this time, the Flash subroutine can tell the high-end through the return value, and the high-end decides whether to call the serial subroutine according to the return value.

3 Return value problem

If you only return a basic type of return value, you can use the return value to return this value. If you return a complex type of return value, such as a struct structure, you need to copy if the return value is returned, which is very expensive. When returning by address, if there are many returned values, these values ​​can be defined in a struct and returned in the form of pointers.

4 Function writing

First, the function must be named reasonably. You can know the function and the object of the function by looking at the function name. It’s best not to have more than 5 levels of function. One is that the efficiency is reduced, and the other is that the readability becomes worse. Each function is clearly commented, and all function codes are written in a unified style. Pay attention to alignment. The stack variable in the function must be assigned an initial value before use, and an embedded RAM is generally less, so be careful not to overflow the stack. Try to use efficient coding methods, such as multiplication and division can be achieved by shifting. If you write a program to run on a 16-bit controller, use 16 bits for function integer parameters and local integer variables, because if you use 8-bit integer variables, the system needs to do extra work to prevent 8-bit overflows and the like Not only does it not save space, but it also reduces efficiency. This phenomenon can be seen through disassembly and comparison.

5. Call the driver

Generally, the driver will be called in two places, one is the function called by patrol and the other is the interrupt handling function. There may be multiple source files containing the same header file. When designing the header file, avoid the problem of repeated definitions. The method is: take the definition of the CHARGER module as an example. The header file is written as follows:

#ifndef _CHARGER_H
#define _CHARGER_H
/*函数声明*/
#endif

Guess you like

Origin blog.csdn.net/weixin_43704402/article/details/114664347