linux(或者windows)软件工程师和软件工程师

linux(或者windows)软件工程师和软件工程师

一个从单片机开始的开发者

学校学的是电子专业,但是做硬件需要耐心和细心,几次电路板设计的失误让我彻底放弃了硬件这块儿。感觉还是软件更合适,学校只学了basic,于是自己学习了C语言的开发,那个时候感觉C语言好难,做pc下的c语言开发,如果涉及到底层,是非常牛X的事情,足以让人望而却步。也没有钱专门去做这方面的培训,于是就从单片机入手,写下了自己运行在硬件上的第一段代码(部分):

void text(void)
{

   bit Flag_add;                                  /*加一标志*/
   bit Flag_sub;                                  /*减一标志*/   
   unsigned char max_value;                       /*各时间单位的最大值*/
   unsigned char min_value;                       /*各时间单位的最小值*/
         /*if(FUN==1)
           {   */                                   /*定义标志位*/
              if(switch_work==0)                 /*移位键*/
                  {               
                      if(Shift_on==0)
                        {
                                Shift_on=1;
                                buzzer();
                            clk_number++;
                            if(clk_number>6)clk_number=1;                             
                             }
                        }
              else
                   Shift_on=0;
              if(switch_up==0)                   /*加一键*/
                  {
                            if(Add_on==0)
                              {
                                      Add_on=1;
                                        buzzer();
                            Flag_add=1;
                                   }
                         }
              else
                        Add_on=0;
              if(switch_down==0)                   /*减一键*/
                  {
                            if(Sub_on==0)
                              {
                                      Sub_on=1;
                                              buzzer();
                                      Flag_sub=1;
                                   }
                   }
               else
                   Sub_on=0;
              switch(clk_number)
                   {
                             case 1: max_value=99;min_value=0;break;
                             case 2: max_value=12;min_value=1;break;
                             case 3:     if(clk_data[1]==1||
                                                  clk_data[1]==3||
                                                  clk_data[1]==5||
                                                  clk_data[1]==7||
                                                  clk_data[1]==8||
                                                  clk_data[1]==10||
                                                  clk_data[1]==12)
                                                  max_value=31;       /*1,3,5,7,8,10,12*/
                                               else if(
                                                  clk_data[1]==4||
                                                  clk_data[1]==6||
                                                  clk_data[1]==9||
                                                  clk_data[1]==11)
                                                  max_value=30;                   /*4,6,9,11*/
                                               else if((clk_data[0]%4==0)||clk_data[0]==0)                          
                                                  max_value=29;                   /*闰年*/
                                               else
                                                  max_value=28;
                                               min_value=1;
                                               break;
                             case 4: max_value=23;min_value=0;break;
                             case 5: max_value=59;min_value=0;break;
                             case 6: max_value=7;min_value=1;break;
                           }
              if(Flag_add==1)
                 {
                           clk_data[clk_number-1]++;         
                           Flag_add=0;
                           if(clk_data[clk_number-1]>max_value)
                         clk_data[clk_number-1]=min_value;                     
                       }
              else if(Flag_sub==1)
                 {
                          clk_data[clk_number-1]--;        
                     Flag_sub=0;
                     if(clk_data[clk_number-1]<min_value||clk_data[clk_number-1]==0xff)
                        clk_data[clk_number-1]=max_value;  
                  }
             if(switch_function==0)
            {
                  if(function_on==0)
                  {
                            function_on=1;
                            FUN=0;
                            buzzer();
                            function_state=1;
                            fun0_flag=1;
                             set_time[0]=(clk_data[4]/10)*0x10+(clk_data[4]%10);
                          set_time[1]=(clk_data[3]/10)*0x10+(clk_data[3]%10);
                          set_time[2]=(clk_data[2]/10)*0x10+(clk_data[2]%10);
                          set_time[3]=(clk_data[1]/10)*0x10+(clk_data[1]%10);
                          set_time[4]=(clk_data[5]/10)*0x10+(clk_data[5]%10);
                          set_time[5]=(clk_data[0]/10)*0x10+(clk_data[0]%10);
                           
                                          
                         }
                     }
                     else
                     {
                             function_on=0;
                         }                        
                  
}

这段代码是运行在51单片机上的处女作,那是14年前的事情了。

当初从单片机开始接触编程,总觉得在linux(或者windows)上做开发好高大上。后来从学习安装linux和基本指令开始,直到在郑州一家做电力系统信息化的小公司接手一个之前时工做的linux项目维护开始(这里非常感谢时工的指点和帮助),后来工作中慢慢熟悉了linux应用开发。到上海后,抽空看看内核和驱动,在后边的工作中陆续用上了,感觉也就那样子吧。这个过程大概持续了四五年,大约14年之后就很少再关注linux的细节了,开始关注软件工程,敏捷开发,面向对象什么的,直到现在还是感觉自己在这方面所知甚少,没有达到设计一款软件时候有非常明确方向,并且有非常有效的手段的感觉,还是一些经验的积累,距离目标甚远。
最近的工作需要解决一些linux内核的问题,也会涉及到bootloader,没有什么特别的地方,方向也很明确,只是花点时间去理解一下linux某种特定机制而已:比如3.0之后内核增加的设备树概念,比如从android带来的低功耗管理等等。
linux的问题是一个理解别人做了什么,怎么做的问题。是一个相对很有边界的问题。
但是软件设计本身是一个在不断演进的问题,是一个没有边界的问题,而且很抽象,所以我一直更多花心思在这上面。

这些年,行业的热点在不停变换,所使用的技术也是不断演进,然而就相对底层的开发而言,变化就小很多。总有某些内容会沉淀下来的,他们需要花费很大的专注和领悟才能达到某种高度,要想有所成就就必须抛弃浮躁,但是这个行业本身又是那样浮躁,真不是一件容易做到的事情,而且做到了也常常看不到效果或者感觉付出没有得到应有的“回报”,取舍总是有的,生活中处处都是。

一个真正的软件工程师应该不能对平台依赖太多,而且尽量不要太依赖某一两种语言。
有很多是和平台无关的知识,也和语言无关。我们就是要在合适的平台上,用合适的语言去构建用户需要的系统。这个系统要兼顾可扩展(根据需要对某些内容方便扩展)和可维护性。有时候要根据具体情况对付出和收益作出权衡。

最近也抽空写一个可以在单片机和linux下都可以使用的简易通信框架:
实现一个简易的对等式异步通信框架

zxcom

其中一个包解析的文件,packet.c:

#include "packet.h"
#include "command.h"
#include "ucomlib.h"

unsigned int g_cur_msgid = 0;

static inline unsigned int get_new_msgid()
{
	ENTER_CRITICAL();
	if(g_cur_msgid >= 0x00ffffff){
		g_cur_msgid = 0;
	} else {
		g_cur_msgid += 1;
	}
	EXIT_CRITICAL();

	return g_cur_msgid;
}

int ZxcomOnPacket(const char *pack,const int len)
{
	int ret;
	unsigned int datalen;

	char req[100];
	handler_param_t param;
	
	packet_t *packet = (packet_t *)pack;

	unsigned int dir = GET_DIR(packet->ctrlInfo);
	unsigned int msg_type = GET_MSG_TYPE(packet->ctrlInfo);
	cmd_content_t *content = (cmd_content_t *)packet->data;
	unsigned int msg_id = (unsigned int)GET_MSG_ID(packet->ctrlInfo);

	if(dir == DIR_REQUEST) {
		command_handler_t handler = g_command_manager.get_command(content->cmd_id);
		if(handler == NULL){
			return ERR_CMD_NOT_EXIST;
		}

		ret = handler(packet->data);
		if(ret != 0) {

		}
	} else if(dir == DIR_RESPONSE) {
		if(msg_type == MSG_TYPE_ASYNC) {
			ret = CommGetMsg(msg_id,req,&datalen);
			if(ret != 0) {
				return ret;
			}

			packet_t *pk = (packet_t *)req;
			cmd_content_t *cmd = (cmd_content_t *)pk->data;
			param.req = cmd->param;
			param.res = packet->data + sizeof(COMMAND_ID_TYPE);

			command_handler_t handler = g_command_manager.get_response(content->cmd_id);
			if(handler == NULL){
				return ERR_CMD_NOT_EXIST;
			}
			
			ret = handler(&param);
			if(ret != 0) {
			}
		}
	}

	return 0;
}

int ZxcomOnSendMsg(COMMAND_ID_TYPE cmdId,const char *param,const unsigned int paramLen,char *packet)
{
	int i,ret;
	
	packet_t *pk = (packet_t *)packet;
	unsigned int msgid = get_new_msgid();
	
	pk->ctrlInfo = SET_CTRL_INFO(DIR_REQUEST, MSG_TYPE_ASYNC,msgid);

	cmd_content_t *cmd = (cmd_content_t *)pk->data;
	cmd->cmd_id = cmdId;
	
	for(i = 0;i < paramLen;i ++) {
		cmd->param[i] = param[i];
	}

	ret = CommSaveMsg(msgid,packet,paramLen + sizeof(COMMAND_ID_TYPE));
	if(ret != 0) {
		return ret;
	}

	return 0;
}

int ZxcomOnSendResponse(const void *recv,const char *param,const unsigned int paramLen,char *packet)
{
	int i,ret;

	const char *__mptr = (char *)recv;
	packet_t *recv_pk = (packet_t *)(__mptr - offsetof(packet_t,data));
	cmd_content_t *recv_content = (cmd_content_t *)recv_pk->data;
	
	packet_t *pk = (packet_t *)packet;
	
	pk->ctrlInfo = SET_CTRL_INFO(DIR_RESPONSE, MSG_TYPE_ASYNC,GET_MSG_ID(recv_pk->ctrlInfo));

	cmd_content_t *content = (cmd_content_t *)pk->data;
	content->cmd_id = recv_content->cmd_id;
	
	for(i = 0;i < paramLen;i ++) {
		content->param[i] = param[i];
	}

	return 0;
}

欢迎关注公众号
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值