Category Archives: Laboratory



#include <stdio.h>

int main() {

	char string_buff[12];
	unsigned int i_not_zero = 0xFF;

	sprintf(string_buff, "Hello,world!");

	printf("i = %x\r\n", i_not_zero);

	return 0;


i = 0

上述代码使用sprintf修改了string_buff指针所指向的char型数组。但是由于在申明数组长度的时候,没有考虑到字符串结束符’\0’,所以实际写入时不慎篡改了下一位内存地址的内容(此例中为i_not_zero, 使用MinGW gcc)。在实际程序中,此类bug一般很难被发现,尤其是还有其他程序在正常修改该值时,一般先会去排查和该变量有关的程序。




char *covert_to_upper_case(char *string) {
    char p[100];
    int i = 0;
    for(; i < strlen(string); i++ ) {
            p[i] = string[i] - ('a' - 'A'); 
    p[i] = '\0';
    return p;


  1. 主程序调用convert_to_upper_case()函数后,堆栈为p分配了内存空间;
  2. 函数体正确修改了p对应字符数组的内容,并将p的首地址作为指针返回;
  3. 函数返回后,所有临时变量从堆栈中弹出,包括p[100];
  4. 主程序得到返回的指针,对其进行解析。然而指针指向的字符数组此时已经从堆栈中弹出,解析后的数据无法被定义。




最近给本科的学生带Embedded System课程设计,遇到了一个非常奇怪的bug。有一段代码需要实现I2C通信,核心代码已经由软件库提供了,学生只需要设置结构体后调用API即可。一个学生的代码是这样的:

struct I2C_CONFIG {
  // ...
  char *i2c_buff;
  int length;
  // ...

struct I2C_CONFIG cfg;
char *i2c_buff;

void I2C_init() 
  // ...
  cfg.buff = i2c_buff;
  cfg.length = sizeof(buff);
  // ...

void I2C_send(new_buff)
  // ...
  i2c_buff = new_buff;
  I2C_MasterTransferData(LPC_I2C1, cfg);
  // ...


因为代码一直无法实现期望的功能,我又仔细看了一下其中的蹊跷。我注意到,这段代码中使用了一个中间变量:char *i2c_buff。在I2C_init()中虽然将cfg.buff指向了i2c_buff,但是因为cfg.buff本身也是指针变量,而非”指向指针的指针”,所以这里只实现了简单的按值传递,即将i2c_buff的值 (初始值为0) 赋给了cfg.buff。之后虽然在I2C_send()中修改了临时变量i2c_buff指向的位置,但却没有影响到cfg.buff中的内容,cfg.buff依然指向之前i2c_buff初始化时指向的内存地址,所以需要发送的缓冲指针new_buff其实并没有传递给之后的I2C_MasterTransferData()函数!为了解决这个问题,必须将更改后的i2c_buff的值再次赋给cfg.buff,即:

void I2C_send(new_buff)
  // ...
  i2c_buff = new_buff;
  cfg.buff = i2c_buff;
  I2C_MasterTransferData(LPC_I2C1, cfg);
  // ...

另外这段代码还有一个不容易注意的bug,就是在I2C_init()中使用了sizeof()来判断buffer的大小。因为sizeof()函数得到的只是数据类型的大小,所以对于指针char *i2c_buff来说,sizeof(i2c_buff) = 4,而不会返回buffer的实际大小。指针的大小并不等于指针指向缓冲的大小!

The Limitations of Classical PID Controller and Its Advanced Derivations

Since founded by N. Weiner in 1947, the control theory has been evolved for more than 60 years and is still full of challenges and opportunities. The most important principle of the control theory, in my opinion, is the feedback mechanism. Without feedback and closed-loop, almost no algorithm and control technique can be implied. The idea of feedback is that by comparing the reference input and the actual output, an error signal can be obtained and then can be used by the controller to trace and eliminate the difference between the input and the output. Apart from Watt’s steam engine, one could say that the first formally implication of (negative) feedback is the amplifier invented by H.S. Black. It is a genius idea when first came out in 1927 and was proved to be an extremely useful way to solve electronic and control problems. The idea of output feedback has also been extended to state feedback and error feedback to achieve state control and estimation in more advanced control techniques.

Classical control is the foundation of control theory and it is more concentrated on analysing the stability and performance of a controlled plant. However, only linear and SISO systems have been discussed in classical control theory. Although traditional control techniques such as PID controller are still widely used in industry, they cannot handle more complex engineering scenarios such as aerospace, chemistry and biology. Another problem of classical control is that all parameters are designed and tuned based on the current system model, in which case the system will be more vulnerable to further disturbance and parameters varying.

In order to solve these problems of classical PID controller which mentioned before, more advanced approaches have been derived nowadays. If using classical approach to control a MIMO system, one should divide the system into different modes and control each mode separately. However if the system inputs and outputs are coupled with each other, it cannot be decoupled and this method will not be practicable anymore. Here comes the state-space method, which solved the limitation of classical control by using state variables. The advantage of state-space is that it can be represented by matrices and such is very computer-friendly. State-space representation is actually defined in time domain instead of frequency domain and every state can have some extend of physical meaning which gives some clues about what is happening inside a controlled plant. One milestone which makes the state-space method more practicable is the invention of Kalman filter. Kalman filter uses a series of history measurements in the presence of noise to estimate the current state of the system. Kalman filter can work as a state estimator or simply a special filter which uses the physical system model to remove the process and the measurement noise.

Optimal control method such as MPC and LQR is another derivation of classical control. In most circumstances, there are more than one possible control inputs which can drive the system to work properly, but we need is to find the optimal one. Optimal control actually transforms the control problem into an optimal problem which tries to minimise an objective function to get the best outcome. Another advantage of optimal control is that it can take constraints into consideration. One defect of PID controller is that it cannot handle system constraints like actuator saturation or output limitation. In the optimal case control, design a controller with constraints could be feasible.

It is also known that no system is constant and some parameters are likely to vary with time or to the working condition. In classical control, the controller is designed just for the current system model and thus may loss performance or even be unstable due to the system change and uncertainties. In such aspect, adaptive control or robust control may be more applicable. Both adaptive control and robust control are designed to cope with uncertainties. The difference is that adaptive control identifies the system model and changes its parameters in real-time, but robust control fixed its parameters after deployed to the plant. For the truth that adaptive control has to calculate the system model every few periods, it needs much more computational time. What’s more, since the control parameters in the adaptive controller are changing every time, it may be difficult to prove its stability.  On the other hand, the gain of robust controller has already been designed before applied to the system, so it doesn’t need to do additional calculation during the operation. Since robust controller is globally optimised and especially designed to handle uncertainties, it may not have a performance as good as other controllers. But since the real control problems are always not ideal, it is meaningful to take uncertainties and disturbance into the system model.

Some more advanced control techniques such as neural network and expert control are being discussed today. In my opinion, these new approaches have the potential to be the next generation of control theory. With the developing of computer science, it is now possible to model extremely complex networks. This kind of controller can actually take all the possible system states and its corresponding solutions into a database and each time just search for the best solution according to the current system data.  New techniques such as machine learning can also be absorbed into the controller and make the controller more flexible which can handle different control problems using a same configuration.

However, no matter how powerful the control method is, there are rarely situations where we do not need to make trade-offs. As human-beings, we always need to make decisions and balance the income and the expense. Being too greedy is like giving an infinite gain to a helicopter, which may work at the beginning but will suddenly crash whenever there is any disturbance. So push yourself while keep in mind that you have limitation. Take it easy, be adaptive to the environment and always try to get the optimal solution of your life.


[1] R.C. Dorf & R.H. Bishop, Modern Control Systems (Twelfth Edition), Pearson, USA.

[2] Wikipedia, Harold Stephen Black. Available at: Last accessed 26th Mar 2014

[3] E.F. Camacho and C. Bordons, Modern Predictive Control, Springer, London, 2003


1. 引子


  • 直接和GPIO插口对接的屏幕,使用SPI与CPU进行通信。需要特殊的驱动程序将framebuffer的内容发送到LCD控制器上,一般带有触屏功能,大小以3.5寸为主流。受限于SPI通信速度,刷新速率不高;
  • 专用USB接口的屏幕,如RoboPeak Mini USB Display。这类屏幕通过USB连接,需要本地运行驱动程序;
  • 通用LCD屏幕,通过HDMI和树莓派连接。因其通用性不需要特殊的驱动程序,但是很多都不支持触屏功能,而且都需要额外的转接板,体积较大;

▲ 图.  树莓派官方7寸屏实拍


  • 官方屏的LCD模组最有保证,淘宝上的HDMI LCD一般成像质量不高;
  • 官方屏的触摸功能在所有方案中是支持的最好的,有十点电容触摸(目前Raspbian还只支持单点,以后会升级),且不需要额外驱动。而HDMI接口的LCD如果有触摸功能,都需要额外接一根USB用于提供触摸控制;
  • 官方触屏和树莓派3可以直接通过铜柱物理连接,无需额外的驱动电路板。连线也非常少,只需要一根DSI软排线和供电接口即可。

▲ 图. 树莓派官方LCD屏实拍 – 正面

Read more »