西格玛向量™

分类存档: C/C++

mini2440 Helloworld驱动

Author:西玛哒   IN:C/C++, IT悟语, Linux, 硬件与嵌入式   标签: , ,    评论: 1

 

  Mini2440 是基于S3C2440(2410工业版) 的Arm9平台,实验平台已经移植了Linux,目前正打算添加RF24L01接口驱动程序。

  首先建立Helloworld驱动程序,作为驱动开发的模版,记录如下:

   一、建立编译环境:

   mini2440开发环境

    编译器 : arm-linux-gcc    3.4.1

    linux内核版本 : 2.6.32.2

    解压并记录内核源码树 位置例:/opt/FriendlyARM/mini2440/linux-2.6.32.2

   二、编写驱动程序文件:

#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
    printk(KERN_ALERT "Hello modulen");
    return 0;
}
 继续阅读 » 
03-01
2011

神奇的字符进度条

Author:西玛哒   IN:C/C++   标签: , ,    评论: 1

好久不写文章了,刚刚去FPGA的世界打了一圈酱油,回头发现自己的嵌入式C快要挂掉了,攒点人品学点儿习吧。

为了一个清凉的环境,觉得需要Emerge -auvDN world一下(不良嗜好),看着刷屏休息一下,忽然一样东西吸引了我:

真相:
4708398212 78803d6dcc 神奇的字符进度条

a quickr pickr post

一根旋转的小棍让人有了盼头,起码知道自己的机器没有挂掉哇,早先在Fedora下也见过这个东东。忽然想到,这东西既然是程序写的,就可以用程序重现嘛,为什么不自己写一个玩玩呢?
分析一下这个旋转小棍,其实原理很简单,就是一个字符位在不同字符上来回变化{- / | – …..} 问题在于,如何实现同一位上的变化呢?在字符系统中,有如下一些转移字符可以来用(引用:百度百科):

a 响铃(BEL) 007
b 退格(BS) 008
f 换页(FF) 012
n 换行(LF) 010
r 回车(CR) 013
t 水平制表(HT) 009
v 垂直制表(VT) 011
\ 反斜杠 092
? 问号字符 063
' 单引号字符 039
" 双引号字符 034
 空字符(NULL) 000
ddd 任意字符 三位八进制
xhh 任意字符 二位十六进制

其中退格和回车都可以用以实现要求,退格嘛就是删除前面的字符,那么回车呢?正常我们说的“回车”其实是回车+换行,单独的“回车”作用是将光标移动到本行的行首,而其后的输出会将原有的内容删除。
那么如此便简单了,只要一个计数器和case选择就可以实现我们的要求,首先给出Shell脚本~

#rotate_line.sh
#!/bin/sh
function rotate_line #实现旋转线的函数
{
TCOUNT=0         #声明一个计数器
TSLEEP=1         #间隔时间
while true
do
TCOUNT=`expr $TCOUNT + 1`      #计数器+1 注意格式 有空格 反单引号
echo -e "Waitingc "
case $TCOUNT in                #用CASE 语句选择状态
"1") echo -e '-'"rc "    #-e 表示转义,
sleep $TSLEEP;;
"2") echo -e '\'"rc "   #r表示回到行首
sleep $TSLEEP;;
"3") echo -e '|'"rc "    #c表示不换行
sleep $TSLEEP;;
"4") echo -e '/'"rc "
sleep $TSLEEP
TCOUNT=0;;            #回到初始状态
"*") ;;
esac
done
}
rotate_line    #使用测试函数

4707929181 232a0267a4 神奇的字符进度条

a quickr pickr post

脚本很小,但是基本功能有了,归功于echo的c转义结合经典的r b 使用,上面个的代码中r 与b产生的效果应该是一样的,但是实现方式不同,如果延时较长看的就比较明显了。
<待续>

06-17
2010

C语言状态机算法下模拟电梯的实现

Author:西玛哒   IN:C/C++, IT悟语   标签:    评论: 0

//作业中的程序,采用了状态机算法和双线程模拟一个简易3层电梯,.

// 欢迎高手指教.

//运行平台: Gcc version 4.4.3 (Gentoo 4.4.3-r2 p1.2)  编译通过

//2010.5.5  初稿

//修改:增加了代码显示插件

/**********************************/

/*    电梯程序-状态机-@sigmax6    */

/**********************************/

#include<stdio.h>

#include<pthread.h>

#define MAX_FLOOR 3

/**********************************************************/ //数据结构定义.

typedef enum Status{              // STATUS 类型: 记录电梯状态

open,

close,

run,

stop

}STATUS;

typedef enum OutReq{              // QUTREQ 类型: 记录外部请求

up_req,

down_req,

both,

no

}OUTREQ;

typedef enum Dir{                 //DIRECTION 类型: 记录运行方向

up,

down,

still

}DIRECTION;

typedef struct Requests{         //REQURST  类型:  记录请求,Req表示请求类型,-1无情求,0为内部请求,1为外部请求

int    Req;

OUTREQ outReq;

}REQUEST;

typedef struct ElevatorInfo{     //ELEINFO_T 类型:  存放当前电梯状态

DIRECTION Direction;

int       Floor;

STATUS    Statu;

REQUEST   Request[MAX_FLOOR];

}ELEINFO_T;

typedef struct Key{               //KEY_T    类型:  存放当前按键信息

char       typeFlag;

int        floor;

char       updownFlag;

}KEY_T;

//--------------------------------

ELEINFO_T ELEINFO;                //ELEINFO  存储电梯状态

KEY_T KEY;                        //KEY      存储按键信息

/**********************************************************/ //电梯初始化函数

void initEle(void)

{

int temp;                      //计数器

ELEINFO.Direction=still;       //电梯初始状态,在1层,无方向,状态为停止.

ELEINFO.Floor=0;

ELEINFO.Statu=stop;

for(temp=0;temp<MAX_FLOOR;temp++)

{

ELEINFO.Request[temp].Req=-1;

ELEINFO.Request[temp].outReq=no;

}

}

/**********************************************************/  //打印当前状态函数

void printEle(void)

{

printf("%d : ",ELEINFO.Floor+1);  //楼层:

switch(ELEINFO.Statu)

{

case stop:

printf("Stopping!n");

break;

case run:

printf("Running!n");

break;

case open:

printf("Door Opened!n");

break;

case close:

printf("Door Closed!n");

break;

}

}

/**********************************************************/  //线程1:获取输入(KEY)并处理为请求(REQUEST)

void * getKey(void)

{

while(1)

{

scanf("%d",&KEY.floor);      //这里方便测试,没有设计复杂的按键处理

/*

* 可扩展按键处理

*/

switch(KEY.floor)

{

case 1:

case 2:

case 3:                         //1,2,3按键对应1-3层内部请求.

ELEINFO.Request[KEY.floor-1].Req=0;;

break;

case 4:

case 5:

case 6:                         //4,5,6对应1-3层外部向上请求

(ELEINFO.Request[KEY.floor-4].outReq==down_req)?(ELEINFO.Request[KEY.floor-4].outReq=both):(ELEINFO.Request[KEY.floor-4].outReq=up_req);

ELEINFO.Request[KEY.floor-4].Req=1;

break;

case 7:

case 8:

case 9:                         //7,8,9对应1-3层外部向下请求

(ELEINFO.Request[KEY.floor-7].outReq==up_req)?(ELEINFO.Request[KEY.floor-7].outReq=both):(ELEINFO.Request[KEY.floor-7].outReq=down_req);

ELEINFO.Request[KEY.floor-7].Req=1;

break;

default:

printf("ERROR!n");

break;

}

}

}

/**********************************************************/  //线程2 :电梯状态转换处理函数

void * procEle(void)

{

int floorPtr;

while(1)

{

switch(ELEINFO.Statu)                                 //依据当前状态判断处理方式

{

case stop:                                         //停止状态处理------------------------

if(ELEINFO.Request[ELEINFO.Floor].Req!=-1)

{

ELEINFO.Request[ELEINFO.Floor].Req=-1;

ELEINFO.Request[ELEINFO.Floor].outReq=no;

ELEINFO.Statu=open;

}

else

{

floorPtr=ELEINFO.Floor;

while(floorPtr<MAX_FLOOR)

{

if(ELEINFO.Request[floorPtr].Req!=-1)

break;

floorPtr++;

}

if(floorPtr<MAX_FLOOR)

{

ELEINFO.Direction=up;

ELEINFO.Statu=run;

}

else

{

floorPtr=0;

while(floorPtr<ELEINFO.Floor)

{

if(ELEINFO.Request[floorPtr].Req!=-1)

break;

floorPtr++;

}

if(floorPtr<ELEINFO.Floor)

{

ELEINFO.Direction=down;

ELEINFO.Statu=run;

}

}

}

break;

case run:                                             //运行状态处理---------------------

if(ELEINFO.Direction==up)

{

if(ELEINFO.Request[ELEINFO.Floor].Req!=-1&&ELEINFO.Request[ELEINFO.Floor].outReq!=down_req)

{

ELEINFO.Statu=open;

}

else

{

floorPtr=ELEINFO.Floor;

while(floorPtr<MAX_FLOOR)

{

if(ELEINFO.Request[floorPtr].Req!=-1)

break;

floorPtr++;

}

if(floorPtr<MAX_FLOOR)

{

ELEINFO.Floor++;

}

else if(ELEINFO.Request[ELEINFO.Floor].Req!=-1&&ELEINFO.Request[ELEINFO.Floor].outReq==down_req)

{

ELEINFO.Statu=open;

}

else

{

floorPtr=0;

while(floorPtr<ELEINFO.Floor)

{

if(ELEINFO.Request[floorPtr].Req!=-1)

break;

floorPtr++;

}

if(floorPtr<ELEINFO.Floor)

{

ELEINFO.Direction=down;

}

}

}

}

else

{

if(ELEINFO.Request[ELEINFO.Floor].Req!=-1&&ELEINFO.Request[ELEINFO.Floor].outReq!=up_req)

{

ELEINFO.Statu=open;

}

else

{

floorPtr=0;

while(floorPtr<ELEINFO.Floor)

{

if(ELEINFO.Request[floorPtr].Req!=-1)

break;

floorPtr++;

}

if(floorPtr<ELEINFO.Floor)

{

ELEINFO.Floor--;

}

else if(ELEINFO.Request[ELEINFO.Floor].Req!=-1&&ELEINFO.Request[ELEINFO.Floor].outReq==up_req)

{

ELEINFO.Statu=open;

}

else

{

floorPtr=ELEINFO.Floor;

while(floorPtr<MAX_FLOOR)

{

if(ELEINFO.Request[floorPtr].Req!=-1)

break;

floorPtr++;

}

if(floorPtr<ELEINFO.Floor)

{

ELEINFO.Direction=up;

}

}

}

}

break;

case open:                                             //开门状态处理----------------------

ELEINFO.Statu=close;

if(ELEINFO.Direction==up)

{

if(ELEINFO.Request[ELEINFO.Floor].Req==1&&ELEINFO.Request[ELEINFO.Floor].outReq==both)

{

ELEINFO.Request[ELEINFO.Floor].outReq=down_req;

}

else if(ELEINFO.Request[ELEINFO.Floor].Req!=-1)

{

ELEINFO.Request[ELEINFO.Floor].outReq=no;

ELEINFO.Request[ELEINFO.Floor].Req=-1;

}

}

else if(ELEINFO.Direction==down)

{

if(ELEINFO.Request[ELEINFO.Floor].Req==1&&ELEINFO.Request[ELEINFO.Floor].outReq==both)

{

ELEINFO.Request[ELEINFO.Floor].outReq=up_req;

}

else if(ELEINFO.Request[ELEINFO.Floor].Req!=-1)

{

ELEINFO.Request[ELEINFO.Floor].outReq=no;

ELEINFO.Request[ELEINFO.Floor].Req=-1;

}

}

else

{

ELEINFO.Request[ELEINFO.Floor].outReq=no;

ELEINFO.Request[ELEINFO.Floor].Req=-1;

}

break;

case close:                                              //关门状态处理----------------------

if(ELEINFO.Direction==up)

{

floorPtr=ELEINFO.Floor;

while(floorPtr<MAX_FLOOR)

{

if(ELEINFO.Request[floorPtr].Req!=-1&&ELEINFO.Request[floorPtr].outReq!=down_req)

break;

floorPtr++;

}

if(floorPtr<MAX_FLOOR)

{

ELEINFO.Statu=run;

}

else

{

floorPtr=0;

while(floorPtr<ELEINFO.Floor)

{

if(ELEINFO.Request[floorPtr].Req!=-1&&ELEINFO.Request[floorPtr].outReq!=up_req)

break;

floorPtr++;

}

if(floorPtr<ELEINFO.Floor)

{

ELEINFO.Statu=run;

ELEINFO.Direction=down;

}

else

{

ELEINFO.Statu=stop;

ELEINFO.Direction=still;

}

}

}

else

{

floorPtr=0;

while(floorPtr<ELEINFO.Floor)

{

if(ELEINFO.Request[floorPtr].Req!=-1&&ELEINFO.Request[floorPtr].outReq!=up_req)

break;

floorPtr++;

}

if(floorPtr<ELEINFO.Floor)

{

ELEINFO.Statu=run;

}

else

{

floorPtr=ELEINFO.Floor;

while(floorPtr<MAX_FLOOR)

{

if(ELEINFO.Request[floorPtr].Req!=-1&&ELEINFO.Request[floorPtr].outReq!=down_req)

break;

floorPtr++;

}

if(floorPtr<MAX_FLOOR)

{

ELEINFO.Statu=run;

ELEINFO.Direction=up;

}

else

{

ELEINFO.Statu=stop;

ELEINFO.Direction=still;

}

}

}

break;

}

//------------------------------------------

printEle();                              //打印当前状态

sleep(1);

//------------------------------------------

}

}

/**********************************************************/  //主函数 调用初始化,创建调度线程

int main (int argc, char const* argv[])

{

pthread_t getkey_t,proc_t;           //线程ID

initEle();                           //初始化

pthread_create(&getkey_t,NULL,(void *)&getKey,NULL);  //创建键盘获取线程

pthread_create(&proc_t,NULL,(void *)&procEle,NULL);   //创建电梯处理线程

pthread_exit(NULL);                  //等待线程结束

return 0;

}

/*************************************************************************************************/
05-05
2010
loading...