当前位置: 首页 > news >正文

广州网站建设的费用网站开发与维护是学什么

广州网站建设的费用,网站开发与维护是学什么,中国最新军事新闻视频,删除wordpress首页链接1.为什么自己写一个时间片调度呢 a. 网上其实有很多成熟的时间片调度例程, 包括我最开始参加工作也是抄的网上的例程(还记得当时领导问我看明白了它的调度原理吗, 作为一个自学刚参加工作的我来说, 看懂别人的意思真的很难, 当时只能含糊其词的说看得差不多) b. 在我看来网上的…

1.为什么自己写一个时间片调度呢

        a. 网上其实有很多成熟的时间片调度例程, 包括我最开始参加工作也是抄的网上的例程(还记得当时领导问我看明白了它的调度原理吗, 作为一个自学刚参加工作的我来说, 看懂别人的意思真的很难, 当时只能含糊其词的说看得差不多)

        b. 在我看来网上的例程是有一些问题的, 计算时间的那个函数放到定时器中递减, 随着任务的增加, 定时器定时越不准确, 违背了中断的快进快出, 不过话说回来时间片本来就是一个不准确的定时.

        c. 违背了软件的开闭原则, 每次添加任务都需要进去修改那个定义任务调度的数组.

        d. 时间为0的任务不能添加到调度中.

        e. 不能删除任务: 比如某个任务我运行了一段时间, 我根本就不会运行了, 这个时候它还是在调度, 只是我们会在内部放置一个标志位, 让它快速切出去.同时也不能在运行过程中添加任务.

2.程序设计思路

        1. 先说下如何定时, 通过一个int类型(32bit)来记录1ms时间过去了, 当定时中断产生中断依次将bit0-31置1, 然后在while(1)中检测有没有置1的bit, 如果有就将任务时间递减. 由于只用一个int类型计时, 这也是为什么程序最大只能支持你程序中, 不能死等超过32ms. 

        2. 任务的删除, 添加, 转移其实都是链表的知识, 掌握好链表就能明白了.

3.程序移植

2.1 移植超级简单, 只需要添加三个文件: os.c, os.h, list.h.

#include "os.h"
#include "string.h"#define MAX_SLICE_SUPPORT    0x1F   /* 程序运行过程最大允许被阻塞时间, 如果大于32ms, 将会导致计时不准 */
volatile static unsigned int millisecond; typedef struct
{unsigned int time_que;unsigned char bit_head;unsigned char bit_tail;
}bit_time_t;bit_time_t task_time = {0};/* 任务等待队列和任务就绪队列 */
struct list_head list_wait = LIST_HEAD_INIT(list_wait);
struct list_head list_ready = LIST_HEAD_INIT(list_ready);void add_task(task_t *task)
{if(task->time_slice == 0)   /* 如果时间片设置为0, 则直接挂到就绪队列 */{list_add(&task->next, &list_ready);} else    /* 否则将任务挂到等待队列 */{list_add(&task->next, &list_wait);}
}void delet_task_onself(task_t *task)
{list_del(&task->next);
}static void move_task(task_t *task, struct list_head* soure_list, struct list_head* dest_list)
{if(soure_list == &list_wait)    /* if the task in list_wait, then move to list_ready */{list_del(&task->next);list_add(&task->next, dest_list);}else{/* task->time_slice is not zero can move to list_wait */if(task->time_slice){list_del(&task->next);list_add(&task->next, dest_list);}}
}inline void time_cb()
{ task_time.bit_tail = millisecond & MAX_SLICE_SUPPORT;task_time.time_que |=  1 << task_time.bit_tail;millisecond++;
}void run_task()
{task_t  *node, temp_node;/* 时间队列里面是否有时间 */if(task_time.time_que & (1 << task_time.bit_head)){/* 将延时等待队列的时间减一 */list_for_each_entry(node, &list_wait, next, task_t){node->slice_count--;if(node->slice_count == 0)  /* 如果时间减完了, 则将当前任务挂到就绪队列 */{memcpy(&temp_node, node, sizeof(task_t));node->slice_count = node->time_slice;move_task(node, &list_wait, &list_ready);node = &temp_node;}    }/* 将当前bit的时间清零, 并让bit_head指向下一个位置 */task_time.time_que &= ~(1 << task_time.bit_head);task_time.bit_head++;if(task_time.bit_head == MAX_SLICE_SUPPORT){task_time.bit_head = 0;}}/* 执行就绪队列中的任务, 并将任务重新挂到等待队列 */list_for_each_entry(node, &list_ready, next, task_t){memcpy(&temp_node, node, sizeof(task_t));move_task(node, &list_ready, &list_wait);node->task();node = &temp_node;}
}unsigned int current_time()
{return millisecond;
}
#ifndef LIST_H
#define LIST_Hstruct list_head {struct list_head *next, *prev;
};//双链表的头初始化,next, prev指向自己
#define LIST_HEAD_INIT(name) { &(name), &(name) }//通过函数初始化头
static inline void INIT_LIST_HEAD(struct list_head *list)
{list->next = list;list->prev = list;
}//添加一个新的结点
static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
{next->prev = new;new->next = next;new->prev = prev;prev->next = new;
}//头插法
static inline void list_add(struct list_head *new, struct list_head *head)
{__list_add(new, head, head->next);
}//尾插法
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{__list_add(new, head->prev, head);
}//删除某个结点
static inline void __list_del(struct list_head *prev, struct list_head *next)//将要删除的结点从链表中释放出来
{next->prev = prev;prev->next = next;
}
static inline void list_del(struct list_head *entry) //这个函数才是最后的删除函数
{__list_del(entry->prev, entry->next);entry->next = (void *)0;entry->prev = (void *)0;
}//判断结点是否为空
static inline int list_empty(const struct list_head *head)
{return head->next == head;
}//已知结构体中的某个成员的地址ptr,得到结构体的地址
#define list_entry(ptr, type, member) \((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))//遍历链表, pos为链表结点, head为链表头, member为链表中的成员, type为结点类型
#define list_for_each_entry(pos, head, member, type)        \for (pos = list_entry((head)->next, type, member);      \&pos->member != (head);                         \pos = list_entry(pos->member.next, type, member))
#endif
#ifndef OS_H
#define OS_H
#include "list.h"
typedef struct
{void (*task)();unsigned short time_slice;unsigned short slice_count;struct list_head next;
}task_t;  void add_task(task_t *task);
void delet_task_onself(task_t *task);
void run_task(void);void time_cb(void);
unsigned int current_time(void);#endif

2.2 添加任务和调用

我使用了编译器特性, 自动运行程序, 这样就不需要在main函数开头手动调用函数add_task()了

#include "./UART/uart.h"
#include "./BaseTime/basetime.h"
#include "os.h"static void task1(void);static task_t task_1 = {.task = task1,.time_slice = 500,.slice_count = 500,
};static void task1()
{printf("task1\n");
}/* 使用编译器特性, 自动运行该程序 */
__attribute__((constructor)) static void task1_add()
{add_task(&task_1);
}void task2();
task_t task_2 = {.task = task2,.time_slice = 387,.slice_count = 387,
};
void task2()
{static int count = 0;printf("task2ddasdfasfsafafasdsfsfsfsfsfsew\r\n");if(++count > 5){delet_task_onself(&task_2);}
}__attribute__((constructor)) void task2_add()
{add_task(&task_2);
}void task3()
{printf("task3\r\n");
}task_t task_3 = {.task = task3,.time_slice = 632,.slice_count = 632,
};__attribute__((constructor)) void task3_add()
{add_task(&task_3);
}int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);uart_init(115200);bsTime_Init(1004, 80);//1ms中断while(1){run_task();}
}

3.注意点

1.为了尽可能的节约内存, 以及程序调用的及时性, 程序运行过程最大可以等待32ms去轮询时间递减. 如果内部有死等大于32ms, 就有会导致任务执行时间不准确.

2.如果想在window验证, 由于list.h在visual studio会报错, 如果想验证需要安装gcc(在windows环境下用vscode配置gcc编译代码_windows vscode gcc-CSDN博客), 

贴出keil和gcc源码, 有积分的兄弟可以支持下.也可以不下, 我已经将所有代码贴出来了.

https://download.csdn.net/download/qq_38591801/88900090

http://www.yayakq.cn/news/708356/

相关文章:

  • 网站建设的设计与实现wordpress快递主题
  • 网站开发写好了怎么发布商城网站建设制作设计
  • 漯河网站建设-千弘网络公众号怎么制作链接
  • 长网址转短网址网站wordpress 多栏主题
  • 北京网站建设公司华网opencart做视频网站
  • 网站是怎么做优化网站上线方案
  • 做一个网站一般费用东京购物商城
  • 惠州 网站建设app开发免费seo网站自动推广软件
  • 网站建设的目标的意思iis部署网站无法访问
  • 做网站的方案图片安徽建设工程信息网官网查询
  • 森马网站建设情况淄博网站客户
  • 个人网站名称请深圳市网页制作
  • 郑州网站建设公司哪家好呼和浩特企业网站
  • 佛山个人网站建设免费简单网页制作成品
  • 武隆网站建设费用网上书店网页设计实训报告
  • 湖北网站设计流程辽宁省建设工程信息网人员解除
  • 企业网站的建立意义网站开发 避免 字段变化 代码
  • 网站建设技术经费预算佛山网站推广经理
  • 做云购网站工业互联网解决方案
  • win10 中国建设银行网站进入淘宝网官网首页电脑版
  • wordpress 网站上传到服务器网站开发建设的步骤
  • 资讯网站模版昌平网站开发
  • 建设一个网站主要受哪些因素的影响因素给被k的网站做友链
  • 个人网站怎么做内容比较好中国林业建设工程网站
  • 福田网站建设有限公司精美个人主页
  • 鹤壁建设网站推广渠道关于外贸的网站
  • 淘宝客网站开发教程公司网络规划设计方案
  • 企业网站推广的目的国内免费ip地址
  • 有哪些做统计销量的网站那些使用vue做的网站
  • 合肥市建设厅官方网站安福网站建设