分类存档: C/C++
Author:西玛哒 IN:C/C++, IT悟语, Linux, 硬件与嵌入式 标签: Driver, Linux, mini2440 评论: 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;
}
继续阅读 »
Author:西玛哒 IN:C/C++ 标签: C/C++, Linux, Shell 评论: 1好久不写文章了,刚刚去FPGA的世界打了一圈酱油,回头发现自己的嵌入式C快要挂掉了,攒点人品学点儿习吧。
为了一个清凉的环境,觉得需要Emerge -auvDN world一下(不良嗜好),看着刷屏休息一下,忽然一样东西吸引了我:
真相:

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 #使用测试函数

a quickr pickr post
脚本很小,但是基本功能有了,归功于echo的c转义结合经典的r b 使用,上面个的代码中r 与b产生的效果应该是一样的,但是实现方式不同,如果延时较长看的就比较明显了。
<待续>
Author:西玛哒 IN:C/C++, IT悟语 标签: C/C++ 评论: 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;
}
/*************************************************************************************************/