keer_zu的个人空间 https://bbs.21ic.com/?472461 [收藏] [复制] [RSS]

日志

单片机,嵌入式,软件开发-这些年被大家挂在嘴边的叫法

已有 4314 次阅读2020-4-29 10:24 |个人分类:行业展望|系统分类:单片机

@Cjy_JDxy

C语言开发,我们这个行业还专门有人将单片机的C语言开发,甚至51单片机的c语言开发单独拿出来讲。搞得我刚入行的时候,以为那是一种特殊的C语言。甚至比英伟达GPU上那种开发语言还要距离“真正”的C语言更远......[/code]
一个从单片机开始的开发者
学校学的是电子专业,但是做硬件需要耐心和细心,几次电路板设计的失误让我彻底放弃了硬件这块儿。感觉还是软件更合适,学校只学了basic,于是自己学习了C语言的开发,那个时候感觉C语言好难,做pc下的c语言开发,如果涉及到底层,是非常牛X的事情,足以让人望而却步。也没有钱专门去做这方面的培训,于是就从单片机入手。

再贴一下自己第一段跑在单片机上的代码:
       
  1. void text(void)
  2. {

  3.    bit Flag_add;                                  /*加一标志*/
  4.    bit Flag_sub;                                  /*减一标志*/   
  5.    unsigned char max_value;                       /*各时间单位的最大值*/
  6.    unsigned char min_value;                       /*各时间单位的最小值*/
  7.          /*if(FUN==1)
  8.            {   */                                   /*定义标志位*/
  9.               if(switch_work==0)                 /*移位键*/
  10.                   {               
  11.                       if(Shift_on==0)
  12.                         {
  13.                                 Shift_on=1;
  14.                                 buzzer();
  15.                             clk_number++;
  16.                             if(clk_number>6)clk_number=1;                             
  17.                              }
  18.                         }
  19.               else
  20.                    Shift_on=0;
  21.               if(switch_up==0)                   /*加一键*/
  22.                   {
  23.                             if(Add_on==0)
  24.                               {
  25.                                       Add_on=1;
  26.                                         buzzer();
  27.                             Flag_add=1;
  28.                                    }
  29.                          }
  30.               else
  31.                         Add_on=0;
  32.               if(switch_down==0)                   /*减一键*/
  33.                   {
  34.                             if(Sub_on==0)
  35.                               {
  36.                                       Sub_on=1;
  37.                                               buzzer();
  38.                                       Flag_sub=1;
  39.                                    }
  40.                    }
  41.                else
  42.                    Sub_on=0;
  43.               switch(clk_number)
  44.                    {
  45.                              case 1: max_value=99;min_value=0;break;
  46.                              case 2: max_value=12;min_value=1;break;
  47.                              case 3:     if(clk_data[1]==1||
  48.                                                   clk_data[1]==3||
  49.                                                   clk_data[1]==5||
  50.                                                   clk_data[1]==7||
  51.                                                   clk_data[1]==8||
  52.                                                   clk_data[1]==10||
  53.                                                   clk_data[1]==12)
  54.                                                   max_value=31;       /*1,3,5,7,8,10,12*/
  55.                                                else if(
  56.                                                   clk_data[1]==4||
  57.                                                   clk_data[1]==6||
  58.                                                   clk_data[1]==9||
  59.                                                   clk_data[1]==11)
  60.                                                   max_value=30;                   /*4,6,9,11*/
  61.                                                else if((clk_data[0]%4==0)||clk_data[0]==0)                          
  62.                                                   max_value=29;                   /*闰年*/
  63.                                                else
  64.                                                   max_value=28;
  65.                                                min_value=1;
  66.                                                break;
  67.                              case 4: max_value=23;min_value=0;break;
  68.                              case 5: max_value=59;min_value=0;break;
  69.                              case 6: max_value=7;min_value=1;break;
  70.                            }
  71.               if(Flag_add==1)
  72.                  {
  73.                            clk_data[clk_number-1]++;         
  74.                            Flag_add=0;
  75.                            if(clk_data[clk_number-1]>max_value)
  76.                          clk_data[clk_number-1]=min_value;                     
  77.                        }
  78.               else if(Flag_sub==1)
  79.                  {
  80.                           clk_data[clk_number-1]--;        
  81.                      Flag_sub=0;
  82.                      if(clk_data[clk_number-1]<min_value||clk_data[clk_number-1]==0xff)
  83.                         clk_data[clk_number-1]=max_value;  
  84.                   }
  85.              if(switch_function==0)
  86.             {
  87.                   if(function_on==0)
  88.                   {
  89.                             function_on=1;
  90.                             FUN=0;
  91.                             buzzer();
  92.                             function_state=1;
  93.                             fun0_flag=1;
  94.                              set_time[0]=(clk_data[4]/10)*0x10+(clk_data[4]%10);
  95.                           set_time[1]=(clk_data[3]/10)*0x10+(clk_data[3]%10);
  96.                           set_time[2]=(clk_data[2]/10)*0x10+(clk_data[2]%10);
  97.                           set_time[3]=(clk_data[1]/10)*0x10+(clk_data[1]%10);
  98.                           set_time[4]=(clk_data[5]/10)*0x10+(clk_data[5]%10);
  99.                           set_time[5]=(clk_data[0]/10)*0x10+(clk_data[0]%10);
  100.                            
  101.                                           
  102.                          }
  103.                      }
  104.                      else
  105.                      {
  106.                              function_on=0;
  107.                          }                        
  108.                   
  109. }
复制代码

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


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

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

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

最近也抽空写一个可以在单片机和linux下都可以使用的简易通信框架:
zxcom




这里是其中一个文件pacet.c:

       
  1. #include "packet.h"
  2. #include "command.h"
  3. #include "ucomlib.h"

  4. unsigned int g_cur_msgid = 0;

  5. static inline unsigned int get_new_msgid()
  6. {
  7.         ENTER_CRITICAL();
  8.         if(g_cur_msgid >= 0x00ffffff){
  9.                 g_cur_msgid = 0;
  10.         } else {
  11.                 g_cur_msgid += 1;
  12.         }
  13.         EXIT_CRITICAL();

  14.         return g_cur_msgid;
  15. }

  16. int ZxcomOnPacket(const char *pack,const int len)
  17. {
  18.         int ret;
  19.         unsigned int datalen;

  20.         char req[100];
  21.         handler_param_t param;
  22.         
  23.         packet_t *packet = (packet_t *)pack;

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

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

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

  35.                 }
  36.         } else if(dir == DIR_RESPONSE) {
  37.                 if(msg_type == MSG_TYPE_ASYNC) {
  38.                         ret = CommGetMsg(msg_id,req,&datalen);
  39.                         if(ret != 0) {
  40.                                 return ret;
  41.                         }

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

  46.                         command_handler_t handler = g_command_manager.get_response(content->cmd_id);
  47.                         if(handler == NULL){
  48.                                 return ERR_CMD_NOT_EXIST;
  49.                         }
  50.                         
  51.                         ret = handler(¶m);
  52.                         if(ret != 0) {
  53.                         }
  54.                 }
  55.         }

  56.         return 0;
  57. }

  58. int ZxcomOnSendMsg(COMMAND_ID_TYPE cmdId,const char *param,const unsigned int paramLen,char *packet)
  59. {
  60.         int i,ret;
  61.         
  62.         packet_t *pk = (packet_t *)packet;
  63.         unsigned int msgid = get_new_msgid();
  64.         
  65.         pk->ctrlInfo = SET_CTRL_INFO(DIR_REQUEST, MSG_TYPE_ASYNC,msgid);

  66.         cmd_content_t *cmd = (cmd_content_t *)pk->data;
  67.         cmd->cmd_id = cmdId;
  68.         
  69.         for(i = 0;i < paramLen;i ++) {
  70.                 cmd->param[i] = param[i];
  71.         }

  72.         ret = CommSaveMsg(msgid,packet,paramLen + sizeof(COMMAND_ID_TYPE));
  73.         if(ret != 0) {
  74.                 return ret;
  75.         }

  76.         return 0;
  77. }

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

  81.         const char *__mptr = (char *)recv;
  82.         packet_t *recv_pk = (packet_t *)(__mptr - offsetof(packet_t,data));
  83.         cmd_content_t *recv_content = (cmd_content_t *)recv_pk->data;
  84.         
  85.         packet_t *pk = (packet_t *)packet;
  86.         
  87.         pk->ctrlInfo = SET_CTRL_INFO(DIR_RESPONSE, MSG_TYPE_ASYNC,GET_MSG_ID(recv_pk->ctrlInfo));

  88.         cmd_content_t *content = (cmd_content_t *)pk->data;
  89.         content->cmd_id = recv_content->cmd_id;
  90.         
  91.         for(i = 0;i < paramLen;i ++) {
  92.                 content->param[i] = param[i];
  93.         }

  94.         return 0;
  95. }
复制代码

希望有人可以把这些C代码跑在单片机上。







路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)